diff --git a/ICE_LICENSE b/ICE_LICENSE new file mode 100644 index 0000000..be01cbd --- /dev/null +++ b/ICE_LICENSE @@ -0,0 +1,48 @@ +Copyright (c) ZeroC, Inc. All rights reserved. + +This copy of Ice is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +Ice is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License version +2 along with this program; if not, see http://www.gnu.org/licenses. + +Linking Ice statically or dynamically with other software (such as a +library, module or application) is making a combined work based on Ice. +Thus, the terms and conditions of the GNU General Public License version +2 cover this combined work. + +If such software can only be used together with Ice, then not only the +combined work but the software itself is a work derived from Ice and as +such shall be licensed under the terms of the GNU General Public License +version 2. This includes the situation where Ice is only being used +through an abstraction layer. + +As a special exception to the above, ZeroC grants to the copyright +holders and contributors of the Mumble project (http://www.mumble.info) +the permission to license the Ice-based software they contribute to +Mumble under the terms of the BSD license. This exception does not extend +to the parts of Ice used by Mumble, or to any other derived work: as a +whole, any work based on Ice shall be licensed under the terms and +conditions of the GNU General Public License version 2. + +You may also combine Ice with any software not derived from Ice, provided +the license of such software is compatible with the GNU General Public +License version 2. In addition, as a special exception, ZeroC grants you +permission to combine Ice with: + + - the OpenSSL library, or with a modified version of the OpenSSL library + that uses the same license as OpenSSL + + - any library not derived from Ice and licensed under the terms of + the Apache License, version 2.0 + (http://www.apache.org/licenses/LICENSE-2.0.html) + +If you modify this copy of Ice, you may extend any of the exceptions +provided above to your version of Ice, but you are not obligated to +do so. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..147e2c9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..3b51225 --- /dev/null +++ b/Package.swift @@ -0,0 +1,43 @@ +// swift-tools-version:5.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let cxxSettings: [CXXSetting] = [ + .define("ICE_BUILDING_SRC"), + .define("ICE_STATIC_LIBS"), + .define("ICE_SWIFT"), + .define("ICE_CPP11_MAPPING")] + +let package = Package( + name: "Ice", + platforms: [ + .macOS(.v10_14), + .iOS(.v12), + ], + products: [ + .library(name: "Ice", targets: ["Ice"]), + .library(name: "Glacier2", targets: ["Glacier2"]), + .library(name: "IceStorm", targets: ["IceStorm"]), + .library(name: "IceGrid", targets: ["IceGrid"]) + ], + dependencies: [ + .package(url: "https://github.com/mxcl/PromiseKit.git", from: "6.8.10") + ], + targets: [ + .target(name: "IceCpp", cxxSettings: cxxSettings, + linkerSettings: [.linkedLibrary("iconv"), .linkedLibrary("bz2")]), + .target(name: "IceSSLCpp", dependencies: ["IceCpp"], cxxSettings: cxxSettings), + .target(name: "IceDiscoveryCpp", dependencies: ["IceCpp"], cxxSettings: cxxSettings), + .target(name: "IceLocatorDiscoveryCpp", dependencies: ["IceCpp"], cxxSettings: cxxSettings), + .target(name: "IceImpl", + dependencies: ["IceCpp", "IceSSLCpp", "IceDiscoveryCpp", "IceLocatorDiscoveryCpp"], + cxxSettings: cxxSettings, + linkerSettings: [.linkedFramework("ExternalAccessory")]), + .target(name: "Ice", dependencies: ["IceImpl", "PromiseKit"]), + .target(name: "Glacier2", dependencies: ["Ice"]), + .target(name: "IceStorm", dependencies: ["Ice"]), + .target(name: "IceGrid", dependencies: ["Ice", "Glacier2"]) + ], + cxxLanguageStandard: .cxx14 +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff286d2 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Ice for Swift + +This tag provides the Ice for Swift source code for the Swift Package Manager (SPM). +It includes Swift and C++ code generated by slice2swift and slice2cpp. diff --git a/Sources/Glacier2/Metrics.swift b/Sources/Glacier2/Metrics.swift new file mode 100644 index 0000000..060e1fa --- /dev/null +++ b/Sources/Glacier2/Metrics.swift @@ -0,0 +1,109 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Metrics.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// Traits for Slice class `MXSessionMetrics`. +public struct MXSessionMetricsTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::Metrics", "::IceMX::SessionMetrics"] + public static let staticId = "::IceMX::SessionMetrics" +} + +/// :nodoc: +public class MXSessionMetrics_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return MXSessionMetrics.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceMX_SessionMetrics() -> Ice.ValueTypeResolver { + return MXSessionMetrics_TypeResolver() + } +} + +/// Provides information on Glacier2 sessions. +open class MXSessionMetrics: Ice.MXMetrics { + /// Number of client requests forwared. + public var forwardedClient: Swift.Int32 = 0 + /// Number of server requests forwared. + public var forwardedServer: Swift.Int32 = 0 + /// The size of the routing table. + public var routingTableSize: Swift.Int32 = 0 + /// Number of client requests queued. + public var queuedClient: Swift.Int32 = 0 + /// Number of server requests queued. + public var queuedServer: Swift.Int32 = 0 + /// Number of client requests overridden. + public var overriddenClient: Swift.Int32 = 0 + /// Number of server requests overridden. + public var overriddenServer: Swift.Int32 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, forwardedClient: Swift.Int32, forwardedServer: Swift.Int32, routingTableSize: Swift.Int32, queuedClient: Swift.Int32, queuedServer: Swift.Int32, overriddenClient: Swift.Int32, overriddenServer: Swift.Int32) { + self.forwardedClient = forwardedClient + self.forwardedServer = forwardedServer + self.routingTableSize = routingTableSize + self.queuedClient = queuedClient + self.queuedServer = queuedServer + self.overriddenClient = overriddenClient + self.overriddenServer = overriddenServer + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXSessionMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXSessionMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.forwardedClient = try istr.read() + self.forwardedServer = try istr.read() + self.routingTableSize = try istr.read() + self.queuedClient = try istr.read() + self.queuedServer = try istr.read() + self.overriddenClient = try istr.read() + self.overriddenServer = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: MXSessionMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.forwardedClient) + ostr.write(self.forwardedServer) + ostr.write(self.routingTableSize) + ostr.write(self.queuedClient) + ostr.write(self.queuedServer) + ostr.write(self.overriddenClient) + ostr.write(self.overriddenServer) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} diff --git a/Sources/Glacier2/PermissionsVerifier.swift b/Sources/Glacier2/PermissionsVerifier.swift new file mode 100644 index 0000000..7c73d87 --- /dev/null +++ b/Sources/Glacier2/PermissionsVerifier.swift @@ -0,0 +1,599 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PermissionsVerifier.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// :nodoc: +public class PermissionDeniedException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return PermissionDeniedException.self + } +} + +public extension Ice.ClassResolver { + @objc static func Glacier2_PermissionDeniedException() -> Ice.UserExceptionTypeResolver { + return PermissionDeniedException_TypeResolver() + } +} + +/// This exception is raised if a client is denied the ability to create +/// a session with the router. +open class PermissionDeniedException: Ice.UserException { + /// The reason why permission was denied. + public var reason: Swift.String = "" + var _slicedData: Ice.SlicedData? + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Glacier2::PermissionDeniedException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: PermissionDeniedException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } + + /// Returns the sliced data if the exception has a preserved-slice base class and has been + /// sliced during un-marshaling, nil is returned otherwise. + /// + /// - returns: `Ice.SlicedData` - The sliced data. + open override func ice_getSlicedData() -> Ice.SlicedData? { + return _slicedData + } + + open override func _iceRead(from istr: Ice.InputStream) throws { + istr.startException() + try _iceReadImpl(from: istr) + _slicedData = try istr.endException(preserve: true) + } + + open override func _iceWrite(to ostr: Ice.OutputStream) { + ostr.startException(data: _slicedData) + _iceWriteImpl(to: ostr) + ostr.endException() + } +} + +/// Traits for Slice interface `PermissionsVerifier`. +public struct PermissionsVerifierTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::PermissionsVerifier", "::Ice::Object"] + public static let staticId = "::Glacier2::PermissionsVerifier" +} + +/// Traits for Slice interface `SSLPermissionsVerifier`. +public struct SSLPermissionsVerifierTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::SSLPermissionsVerifier", "::Ice::Object"] + public static let staticId = "::Glacier2::SSLPermissionsVerifier" +} + +/// The Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// PermissionsVerifierPrx Methods: +/// +/// - checkPermissions: Check whether a user has permission to access the router. +/// +/// - checkPermissionsAsync: Check whether a user has permission to access the router. +public protocol PermissionsVerifierPrx: Ice.ObjectPrx {} + +private final class PermissionsVerifierPrxI: Ice.ObjectPrxI, PermissionsVerifierPrx { + public override class func ice_staticId() -> Swift.String { + return PermissionsVerifierTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `PermissionsVerifierPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `PermissionsVerifierPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: PermissionsVerifierPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> PermissionsVerifierPrx? { + return try PermissionsVerifierPrxI.checkedCast(prx: prx, facet: facet, context: context) as PermissionsVerifierPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `PermissionsVerifierPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `PermissionsVerifierPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: PermissionsVerifierPrx.Protocol, facet: Swift.String? = nil) -> PermissionsVerifierPrx { + return PermissionsVerifierPrxI.uncheckedCast(prx: prx, facet: facet) as PermissionsVerifierPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `PermissionsVerifierPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: PermissionsVerifierPrx.Protocol) -> Swift.String { + return PermissionsVerifierTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `PermissionsVerifierPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `PermissionsVerifierPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `PermissionsVerifierPrx?` - The extracted proxy + func read(_ type: PermissionsVerifierPrx.Protocol) throws -> PermissionsVerifierPrx? { + return try read() as PermissionsVerifierPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `PermissionsVerifierPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `PermissionsVerifierPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: PermissionsVerifierPrx.Protocol) throws -> PermissionsVerifierPrx? { + return try read(tag: tag) as PermissionsVerifierPrxI? + } +} + +/// The Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// PermissionsVerifierPrx Methods: +/// +/// - checkPermissions: Check whether a user has permission to access the router. +/// +/// - checkPermissionsAsync: Check whether a user has permission to access the router. +public extension PermissionsVerifierPrx { + /// Check whether a user has permission to access the router. + /// + /// - parameter userId: `Swift.String` The user id for which to check permission. + /// + /// - parameter password: `Swift.String` The user's password. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: Swift.Bool, reason: Swift.String)`: + /// + /// - returnValue: `Swift.Bool` - True if access is granted, or false otherwise. + /// + /// - reason: `Swift.String` - The reason why access was denied. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the user access is + /// denied. This can be raised in place of returning false with a + /// reason set in the reason out parameter. + func checkPermissions(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil) throws -> (returnValue: Swift.Bool, reason: Swift.String) { + return try _impl._invoke(operation: "checkPermissions", + mode: .Nonmutating, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_reason: Swift.String = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_reason) + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Check whether a user has permission to access the router. + /// + /// - parameter userId: `Swift.String` The user id for which to check permission. + /// + /// - parameter password: `Swift.String` The user's password. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: Swift.Bool, reason: Swift.String)>` - The result of the operation + func checkPermissionsAsync(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: Swift.Bool, reason: Swift.String)> { + return _impl._invokeAsync(operation: "checkPermissions", + mode: .Nonmutating, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_reason: Swift.String = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_reason) + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The SSL Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// SSLPermissionsVerifierPrx Methods: +/// +/// - authorize: Check whether a user has permission to access the router. +/// +/// - authorizeAsync: Check whether a user has permission to access the router. +public protocol SSLPermissionsVerifierPrx: Ice.ObjectPrx {} + +private final class SSLPermissionsVerifierPrxI: Ice.ObjectPrxI, SSLPermissionsVerifierPrx { + public override class func ice_staticId() -> Swift.String { + return SSLPermissionsVerifierTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SSLPermissionsVerifierPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SSLPermissionsVerifierPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SSLPermissionsVerifierPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SSLPermissionsVerifierPrx? { + return try SSLPermissionsVerifierPrxI.checkedCast(prx: prx, facet: facet, context: context) as SSLPermissionsVerifierPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SSLPermissionsVerifierPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SSLPermissionsVerifierPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SSLPermissionsVerifierPrx.Protocol, facet: Swift.String? = nil) -> SSLPermissionsVerifierPrx { + return SSLPermissionsVerifierPrxI.uncheckedCast(prx: prx, facet: facet) as SSLPermissionsVerifierPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SSLPermissionsVerifierPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SSLPermissionsVerifierPrx.Protocol) -> Swift.String { + return SSLPermissionsVerifierTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SSLPermissionsVerifierPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SSLPermissionsVerifierPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SSLPermissionsVerifierPrx?` - The extracted proxy + func read(_ type: SSLPermissionsVerifierPrx.Protocol) throws -> SSLPermissionsVerifierPrx? { + return try read() as SSLPermissionsVerifierPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SSLPermissionsVerifierPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SSLPermissionsVerifierPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SSLPermissionsVerifierPrx.Protocol) throws -> SSLPermissionsVerifierPrx? { + return try read(tag: tag) as SSLPermissionsVerifierPrxI? + } +} + +/// The SSL Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// SSLPermissionsVerifierPrx Methods: +/// +/// - authorize: Check whether a user has permission to access the router. +/// +/// - authorizeAsync: Check whether a user has permission to access the router. +public extension SSLPermissionsVerifierPrx { + /// Check whether a user has permission to access the router. + /// + /// - parameter _: `SSLInfo` The SSL information. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: Swift.Bool, reason: Swift.String)`: + /// + /// - returnValue: `Swift.Bool` - True if access is granted, or false otherwise. + /// + /// - reason: `Swift.String` - The reason why access was denied. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the user access is + /// denied. This can be raised in place of returning false with a + /// reason set in the reason out parameter. + func authorize(_ iceP_info: SSLInfo, context: Ice.Context? = nil) throws -> (returnValue: Swift.Bool, reason: Swift.String) { + return try _impl._invoke(operation: "authorize", + mode: .Nonmutating, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_info) + }, + read: { istr in + let iceP_reason: Swift.String = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_reason) + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Check whether a user has permission to access the router. + /// + /// - parameter _: `SSLInfo` The SSL information. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: Swift.Bool, reason: Swift.String)>` - The result of the operation + func authorizeAsync(_ iceP_info: SSLInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: Swift.Bool, reason: Swift.String)> { + return _impl._invokeAsync(operation: "authorize", + mode: .Nonmutating, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_info) + }, + read: { istr in + let iceP_reason: Swift.String = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_reason) + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `PermissionsVerifier` servants. +public struct PermissionsVerifierDisp: Ice.Disp { + public let servant: PermissionsVerifier + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: PermissionsVerifier) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "checkPermissions": + return try servant._iceD_checkPermissions(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? PermissionsVerifierDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? PermissionsVerifierDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? PermissionsVerifierDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? PermissionsVerifierDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +public protocol PermissionsVerifier { + /// Check whether a user has permission to access the router. + /// + /// - parameter userId: `Swift.String` The user id for which to check permission. + /// + /// - parameter password: `Swift.String` The user's password. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: Swift.Bool, reason: Swift.String)`: + /// + /// - returnValue: `Swift.Bool` - True if access is granted, or false otherwise. + /// + /// - reason: `Swift.String` - The reason why access was denied. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the user access is + /// denied. This can be raised in place of returning false with a + /// reason set in the reason out parameter. + func checkPermissions(userId: Swift.String, password: Swift.String, current: Ice.Current) throws -> (returnValue: Swift.Bool, reason: Swift.String) +} + + +/// Dispatcher for `SSLPermissionsVerifier` servants. +public struct SSLPermissionsVerifierDisp: Ice.Disp { + public let servant: SSLPermissionsVerifier + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: SSLPermissionsVerifier) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "authorize": + return try servant._iceD_authorize(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SSLPermissionsVerifierDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SSLPermissionsVerifierDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SSLPermissionsVerifierDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SSLPermissionsVerifierDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The SSL Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +public protocol SSLPermissionsVerifier { + /// Check whether a user has permission to access the router. + /// + /// - parameter info: `SSLInfo` The SSL information. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: Swift.Bool, reason: Swift.String)`: + /// + /// - returnValue: `Swift.Bool` - True if access is granted, or false otherwise. + /// + /// - reason: `Swift.String` - The reason why access was denied. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the user access is + /// denied. This can be raised in place of returning false with a + /// reason set in the reason out parameter. + func authorize(info: SSLInfo, current: Ice.Current) throws -> (returnValue: Swift.Bool, reason: Swift.String) +} + +/// The Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// PermissionsVerifier Methods: +/// +/// - checkPermissions: Check whether a user has permission to access the router. +public extension PermissionsVerifier { + func _iceD_checkPermissions(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_userId, iceP_password): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_userId: Swift.String = try istr.read() + let iceP_password: Swift.String = try istr.read() + return (iceP_userId, iceP_password) + } + inS.setFormat(.SlicedFormat) + + let (iceP_returnValue, iceP_reason) = try self.checkPermissions(userId: iceP_userId, password: iceP_password, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_reason) + ostr.write(iceP_returnValue) + } + } +} + +/// The SSL Glacier2 permissions verifier. This is called through the +/// process of establishing a session. +/// +/// SSLPermissionsVerifier Methods: +/// +/// - authorize: Check whether a user has permission to access the router. +public extension SSLPermissionsVerifier { + func _iceD_authorize(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_info: SSLInfo = try inS.read { istr in + let iceP_info: SSLInfo = try istr.read() + return iceP_info + } + inS.setFormat(.SlicedFormat) + + let (iceP_returnValue, iceP_reason) = try self.authorize(info: iceP_info, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_reason) + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Glacier2/PermissionsVerifierF.swift b/Sources/Glacier2/PermissionsVerifierF.swift new file mode 100644 index 0000000..579c103 --- /dev/null +++ b/Sources/Glacier2/PermissionsVerifierF.swift @@ -0,0 +1,17 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PermissionsVerifierF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice diff --git a/Sources/Glacier2/Router.swift b/Sources/Glacier2/Router.swift new file mode 100644 index 0000000..f162366 --- /dev/null +++ b/Sources/Glacier2/Router.swift @@ -0,0 +1,862 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Router.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// :nodoc: +public class SessionNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return SessionNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func Glacier2_SessionNotExistException() -> Ice.UserExceptionTypeResolver { + return SessionNotExistException_TypeResolver() + } +} + +/// This exception is raised if a client tries to destroy a session +/// with a router, but no session exists for the client. +open class SessionNotExistException: Ice.UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Glacier2::SessionNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: SessionNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// Traits for Slice interface `Router`. +public struct RouterTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::Router", "::Ice::Object", "::Ice::Router"] + public static let staticId = "::Glacier2::Router" +} + +/// The Glacier2 specialization of the Ice::Router interface. +/// +/// RouterPrx Methods: +/// +/// - getCategoryForClient: This category must be used in the identities of all of the client's callback objects. +/// +/// - getCategoryForClientAsync: This category must be used in the identities of all of the client's callback objects. +/// +/// - createSession: Create a per-client session with the router. +/// +/// - createSessionAsync: Create a per-client session with the router. +/// +/// - createSessionFromSecureConnection: Create a per-client session with the router. +/// +/// - createSessionFromSecureConnectionAsync: Create a per-client session with the router. +/// +/// - refreshSession: Keep the calling client's session with this router alive. +/// +/// - refreshSessionAsync: Keep the calling client's session with this router alive. +/// +/// - destroySession: Destroy the calling client's session with this router. +/// +/// - destroySessionAsync: Destroy the calling client's session with this router. +/// +/// - getSessionTimeout: Get the value of the session timeout. +/// +/// - getSessionTimeoutAsync: Get the value of the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +/// +/// - getACMTimeoutAsync: Get the value of the ACM timeout. +public protocol RouterPrx: Ice.RouterPrx {} + +private final class RouterPrxI: Ice.ObjectPrxI, RouterPrx { + public override class func ice_staticId() -> Swift.String { + return RouterTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RouterPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RouterPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: RouterPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> RouterPrx? { + return try RouterPrxI.checkedCast(prx: prx, facet: facet, context: context) as RouterPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RouterPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RouterPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: RouterPrx.Protocol, facet: Swift.String? = nil) -> RouterPrx { + return RouterPrxI.uncheckedCast(prx: prx, facet: facet) as RouterPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RouterPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RouterPrx.Protocol) -> Swift.String { + return RouterTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RouterPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RouterPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterPrx?` - The extracted proxy + func read(_ type: RouterPrx.Protocol) throws -> RouterPrx? { + return try read() as RouterPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RouterPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RouterPrx.Protocol) throws -> RouterPrx? { + return try read(tag: tag) as RouterPrxI? + } +} + +/// The Glacier2 specialization of the Ice::Router interface. +/// +/// RouterPrx Methods: +/// +/// - getCategoryForClient: This category must be used in the identities of all of the client's callback objects. +/// +/// - getCategoryForClientAsync: This category must be used in the identities of all of the client's callback objects. +/// +/// - createSession: Create a per-client session with the router. +/// +/// - createSessionAsync: Create a per-client session with the router. +/// +/// - createSessionFromSecureConnection: Create a per-client session with the router. +/// +/// - createSessionFromSecureConnectionAsync: Create a per-client session with the router. +/// +/// - refreshSession: Keep the calling client's session with this router alive. +/// +/// - refreshSessionAsync: Keep the calling client's session with this router alive. +/// +/// - destroySession: Destroy the calling client's session with this router. +/// +/// - destroySessionAsync: Destroy the calling client's session with this router. +/// +/// - getSessionTimeout: Get the value of the session timeout. +/// +/// - getSessionTimeoutAsync: Get the value of the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +/// +/// - getACMTimeoutAsync: Get the value of the ACM timeout. +public extension RouterPrx { + /// This category must be used in the identities of all of the client's + /// callback objects. This is necessary in order for the router to + /// forward callback requests to the intended client. If the Glacier2 + /// server endpoints are not set, the returned category is an empty + /// string. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The category. + func getCategoryForClient(context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getCategoryForClient", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// This category must be used in the identities of all of the client's + /// callback objects. This is necessary in order for the router to + /// forward callback requests to the intended client. If the Glacier2 + /// server endpoints are not set, the returned category is an empty + /// string. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getCategoryForClientAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getCategoryForClient", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create a per-client session with the router. If a + /// SessionManager has been installed, a proxy to a Session + /// object is returned to the client. Otherwise, null is returned + /// and only an internal session (i.e., not visible to the client) + /// is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter userId: `Swift.String` The user id for which to check the password. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session, or null if no + /// SessionManager has been installed. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createSession(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "createSession", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a per-client session with the router. If a + /// SessionManager has been installed, a proxy to a Session + /// object is returned to the client. Otherwise, null is returned + /// and only an internal session (i.e., not visible to the client) + /// is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter userId: `Swift.String` The user id for which to check the password. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionAsync(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createSession", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create a per-client session with the router. The user is + /// authenticated through the SSL certificates that have been + /// associated with the connection. If a SessionManager has been + /// installed, a proxy to a Session object is returned to the + /// client. Otherwise, null is returned and only an internal + /// session (i.e., not visible to the client) is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session, or null if no + /// SessionManager has been installed. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + /// + /// - PermissionDeniedException - Raised if the user cannot be + /// authenticated or if the user is not allowed access. + func createSessionFromSecureConnection(context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "createSessionFromSecureConnection", + mode: .Normal, + format: .SlicedFormat, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a per-client session with the router. The user is + /// authenticated through the SSL certificates that have been + /// associated with the connection. If a SessionManager has been + /// installed, a proxy to a Session object is returned to the + /// client. Otherwise, null is returned and only an internal + /// session (i.e., not visible to the client) is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionFromSecureConnectionAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createSessionFromSecureConnection", + mode: .Normal, + format: .SlicedFormat, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Keep the calling client's session with this router alive. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - SessionNotExistException - Raised if no session exists + /// for the calling client. + func refreshSession(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "refreshSession", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as SessionNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Keep the calling client's session with this router alive. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func refreshSessionAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "refreshSession", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as SessionNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Destroy the calling client's session with this router. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - SessionNotExistException - Raised if no session exists + /// for the calling client. + func destroySession(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "destroySession", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as SessionNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Destroy the calling client's session with this router. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func destroySessionAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "destroySession", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as SessionNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the value of the session timeout. Sessions are destroyed + /// if they see no activity for this period of time. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int64` - The timeout (in seconds). + func getSessionTimeout(context: Ice.Context? = nil) throws -> Swift.Int64 { + return try _impl._invoke(operation: "getSessionTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int64 = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the value of the session timeout. Sessions are destroyed + /// if they see no activity for this period of time. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSessionTimeoutAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSessionTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int64 = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the value of the ACM timeout. Clients supporting connection + /// heartbeats can enable them instead of explicitly sending keep + /// alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getACMTimeout(context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getACMTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the value of the ACM timeout. Clients supporting connection + /// heartbeats can enable them instead of explicitly sending keep + /// alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getACMTimeoutAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getACMTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Router` servants. +public struct RouterDisp: Ice.Disp { + public let servant: Router + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Router) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "addProxies": + return try servant._iceD_addProxies(incoming: request, current: current) + case "createSession": + return try servant._iceD_createSession(incoming: request, current: current) + case "createSessionFromSecureConnection": + return try servant._iceD_createSessionFromSecureConnection(incoming: request, current: current) + case "destroySession": + return try servant._iceD_destroySession(incoming: request, current: current) + case "getACMTimeout": + return try servant._iceD_getACMTimeout(incoming: request, current: current) + case "getCategoryForClient": + return try servant._iceD_getCategoryForClient(incoming: request, current: current) + case "getClientProxy": + return try servant._iceD_getClientProxy(incoming: request, current: current) + case "getServerProxy": + return try servant._iceD_getServerProxy(incoming: request, current: current) + case "getSessionTimeout": + return try servant._iceD_getSessionTimeout(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "refreshSession": + return try servant._iceD_refreshSession(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Glacier2 specialization of the Ice::Router interface. +public protocol Router: Ice.Router { + /// This category must be used in the identities of all of the client's + /// callback objects. This is necessary in order for the router to + /// forward callback requests to the intended client. If the Glacier2 + /// server endpoints are not set, the returned category is an empty + /// string. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The category. + func getCategoryForClient(current: Ice.Current) throws -> Swift.String + + /// Create a per-client session with the router. If a + /// SessionManager has been installed, a proxy to a Session + /// object is returned to the client. Otherwise, null is returned + /// and only an internal session (i.e., not visible to the client) + /// is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter userId: `Swift.String` The user id for which to check the password. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionAsync(userId: Swift.String, password: Swift.String, current: Ice.Current) -> PromiseKit.Promise + + /// Create a per-client session with the router. The user is + /// authenticated through the SSL certificates that have been + /// associated with the connection. If a SessionManager has been + /// installed, a proxy to a Session object is returned to the + /// client. Otherwise, null is returned and only an internal + /// session (i.e., not visible to the client) is created. + /// + /// If a session proxy is returned, it must be configured to route + /// through the router that created it. This will happen automatically + /// if the router is configured as the client's default router at the + /// time the session proxy is created in the client process, otherwise + /// the client must configure the session proxy explicitly. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionFromSecureConnectionAsync(current: Ice.Current) -> PromiseKit.Promise + + /// Keep the calling client's session with this router alive. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func refreshSessionAsync(current: Ice.Current) -> PromiseKit.Promise + + /// Destroy the calling client's session with this router. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - SessionNotExistException - Raised if no session exists + /// for the calling client. + func destroySession(current: Ice.Current) throws + + /// Get the value of the session timeout. Sessions are destroyed + /// if they see no activity for this period of time. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int64` - The timeout (in seconds). + func getSessionTimeout(current: Ice.Current) throws -> Swift.Int64 + + /// Get the value of the ACM timeout. Clients supporting connection + /// heartbeats can enable them instead of explicitly sending keep + /// alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getACMTimeout(current: Ice.Current) throws -> Swift.Int32 +} + +/// The Glacier2 specialization of the Ice::Router interface. +/// +/// Router Methods: +/// +/// - getCategoryForClient: This category must be used in the identities of all of the client's callback objects. +/// +/// - createSession: Create a per-client session with the router. +/// +/// - createSessionFromSecureConnection: Create a per-client session with the router. +/// +/// - refreshSession: Keep the calling client's session with this router alive. +/// +/// - destroySession: Destroy the calling client's session with this router. +/// +/// - getSessionTimeout: Get the value of the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +public extension Router { + func _iceD_getCategoryForClient(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getCategoryForClient(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_createSession(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_userId, iceP_password): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_userId: Swift.String = try istr.read() + let iceP_password: Swift.String = try istr.read() + return (iceP_userId, iceP_password) + } + inS.setFormat(.SlicedFormat) + + return inS.setResultPromise(createSessionAsync(userId: iceP_userId, password: iceP_password, current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_createSessionFromSecureConnection(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + inS.setFormat(.SlicedFormat) + + return inS.setResultPromise(createSessionFromSecureConnectionAsync(current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_refreshSession(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + return inS.setResultPromise(refreshSessionAsync(current: current)) + } + + func _iceD_destroySession(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.destroySession(current: current) + + return inS.setResult() + } + + func _iceD_getSessionTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSessionTimeout(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getACMTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getACMTimeout(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Glacier2/RouterF.swift b/Sources/Glacier2/RouterF.swift new file mode 100644 index 0000000..4067e57 --- /dev/null +++ b/Sources/Glacier2/RouterF.swift @@ -0,0 +1,17 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RouterF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice diff --git a/Sources/Glacier2/SSLInfo.swift b/Sources/Glacier2/SSLInfo.swift new file mode 100644 index 0000000..277a053 --- /dev/null +++ b/Sources/Glacier2/SSLInfo.swift @@ -0,0 +1,105 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `SSLInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// Information taken from an SSL connection used for permissions +/// verification. +public struct SSLInfo: Swift.Hashable { + /// The remote host. + public var remoteHost: Swift.String = "" + /// The remote port. + public var remotePort: Swift.Int32 = 0 + /// The router's host. + public var localHost: Swift.String = "" + /// The router's port. + public var localPort: Swift.Int32 = 0 + /// The negotiated cipher suite. + public var cipher: Swift.String = "" + /// The certificate chain. + public var certs: Ice.StringSeq = Ice.StringSeq() + + public init() {} + + public init(remoteHost: Swift.String, remotePort: Swift.Int32, localHost: Swift.String, localPort: Swift.Int32, cipher: Swift.String, certs: Ice.StringSeq) { + self.remoteHost = remoteHost + self.remotePort = remotePort + self.localHost = localHost + self.localPort = localPort + self.cipher = cipher + self.certs = certs + } +} + +/// An `Ice.InputStream` extension to read `SSLInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `SSLInfo` structured value from the stream. + /// + /// - returns: `SSLInfo` - The structured value read from the stream. + func read() throws -> SSLInfo { + var v = SSLInfo() + v.remoteHost = try self.read() + v.remotePort = try self.read() + v.localHost = try self.read() + v.localPort = try self.read() + v.cipher = try self.read() + v.certs = try self.read() + return v + } + + /// Read an optional `SSLInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `SSLInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> SSLInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as SSLInfo + } +} + +/// An `Ice.OutputStream` extension to write `SSLInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `SSLInfo` structured value to the stream. + /// + /// - parameter _: `SSLInfo` - The value to write to the stream. + func write(_ v: SSLInfo) { + self.write(v.remoteHost) + self.write(v.remotePort) + self.write(v.localHost) + self.write(v.localPort) + self.write(v.cipher) + self.write(v.certs) + } + + /// Write an optional `SSLInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `SSLInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: SSLInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} diff --git a/Sources/Glacier2/Session.swift b/Sources/Glacier2/Session.swift new file mode 100644 index 0000000..ce6f22e --- /dev/null +++ b/Sources/Glacier2/Session.swift @@ -0,0 +1,1960 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Session.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// :nodoc: +public class CannotCreateSessionException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return CannotCreateSessionException.self + } +} + +public extension Ice.ClassResolver { + @objc static func Glacier2_CannotCreateSessionException() -> Ice.UserExceptionTypeResolver { + return CannotCreateSessionException_TypeResolver() + } +} + +/// This exception is raised if an attempt to create a new session failed. +open class CannotCreateSessionException: Ice.UserException { + /// The reason why session creation has failed. + public var reason: Swift.String = "" + var _slicedData: Ice.SlicedData? + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Glacier2::CannotCreateSessionException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: CannotCreateSessionException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } + + /// Returns the sliced data if the exception has a preserved-slice base class and has been + /// sliced during un-marshaling, nil is returned otherwise. + /// + /// - returns: `Ice.SlicedData` - The sliced data. + open override func ice_getSlicedData() -> Ice.SlicedData? { + return _slicedData + } + + open override func _iceRead(from istr: Ice.InputStream) throws { + istr.startException() + try _iceReadImpl(from: istr) + _slicedData = try istr.endException(preserve: true) + } + + open override func _iceWrite(to ostr: Ice.OutputStream) { + ostr.startException(data: _slicedData) + _iceWriteImpl(to: ostr) + ostr.endException() + } +} + +/// Traits for Slice interface `Session`. +public struct SessionTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::Session", "::Ice::Object"] + public static let staticId = "::Glacier2::Session" +} + +/// Traits for Slice interface `StringSet`. +public struct StringSetTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::StringSet", "::Ice::Object"] + public static let staticId = "::Glacier2::StringSet" +} + +/// Traits for Slice interface `IdentitySet`. +public struct IdentitySetTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::IdentitySet", "::Ice::Object"] + public static let staticId = "::Glacier2::IdentitySet" +} + +/// Traits for Slice interface `SessionControl`. +public struct SessionControlTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::SessionControl", "::Ice::Object"] + public static let staticId = "::Glacier2::SessionControl" +} + +/// Traits for Slice interface `SessionManager`. +public struct SessionManagerTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::SessionManager", "::Ice::Object"] + public static let staticId = "::Glacier2::SessionManager" +} + +/// Traits for Slice interface `SSLSessionManager`. +public struct SSLSessionManagerTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::SSLSessionManager", "::Ice::Object"] + public static let staticId = "::Glacier2::SSLSessionManager" +} + +/// A client-visible session object, which is tied to the lifecycle of a Router. +/// +/// SessionPrx Methods: +/// +/// - destroy: Destroy the session. +/// +/// - destroyAsync: Destroy the session. +public protocol SessionPrx: Ice.ObjectPrx {} + +private final class SessionPrxI: Ice.ObjectPrxI, SessionPrx { + public override class func ice_staticId() -> Swift.String { + return SessionTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SessionPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SessionPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SessionPrx? { + return try SessionPrxI.checkedCast(prx: prx, facet: facet, context: context) as SessionPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SessionPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SessionPrx.Protocol, facet: Swift.String? = nil) -> SessionPrx { + return SessionPrxI.uncheckedCast(prx: prx, facet: facet) as SessionPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SessionPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SessionPrx.Protocol) -> Swift.String { + return SessionTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SessionPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionPrx?` - The extracted proxy + func read(_ type: SessionPrx.Protocol) throws -> SessionPrx? { + return try read() as SessionPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SessionPrx.Protocol) throws -> SessionPrx? { + return try read(tag: tag) as SessionPrxI? + } +} + +/// A client-visible session object, which is tied to the lifecycle of a Router. +/// +/// SessionPrx Methods: +/// +/// - destroy: Destroy the session. +/// +/// - destroyAsync: Destroy the session. +public extension SessionPrx { + /// Destroy the session. This is called automatically when the router is destroyed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func destroy(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "destroy", + mode: .Normal, + context: context) + } + + /// Destroy the session. This is called automatically when the router is destroyed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func destroyAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "destroy", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// An object for managing the set of identity constraints for specific +/// parts of object identity on a +/// Session. +/// +/// StringSetPrx Methods: +/// +/// - add: Add a sequence of strings to this set of constraints. +/// +/// - addAsync: Add a sequence of strings to this set of constraints. +/// +/// - remove: Remove a sequence of strings from this set of constraints. +/// +/// - removeAsync: Remove a sequence of strings from this set of constraints. +/// +/// - `get`: Returns a sequence of strings describing the constraints in this set. +/// +/// - getAsync: Returns a sequence of strings describing the constraints in this set. +public protocol StringSetPrx: Ice.ObjectPrx {} + +private final class StringSetPrxI: Ice.ObjectPrxI, StringSetPrx { + public override class func ice_staticId() -> Swift.String { + return StringSetTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `StringSetPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `StringSetPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: StringSetPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> StringSetPrx? { + return try StringSetPrxI.checkedCast(prx: prx, facet: facet, context: context) as StringSetPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `StringSetPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `StringSetPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: StringSetPrx.Protocol, facet: Swift.String? = nil) -> StringSetPrx { + return StringSetPrxI.uncheckedCast(prx: prx, facet: facet) as StringSetPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `StringSetPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: StringSetPrx.Protocol) -> Swift.String { + return StringSetTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `StringSetPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `StringSetPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `StringSetPrx?` - The extracted proxy + func read(_ type: StringSetPrx.Protocol) throws -> StringSetPrx? { + return try read() as StringSetPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `StringSetPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `StringSetPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: StringSetPrx.Protocol) throws -> StringSetPrx? { + return try read(tag: tag) as StringSetPrxI? + } +} + +/// An object for managing the set of identity constraints for specific +/// parts of object identity on a +/// Session. +/// +/// StringSetPrx Methods: +/// +/// - add: Add a sequence of strings to this set of constraints. +/// +/// - addAsync: Add a sequence of strings to this set of constraints. +/// +/// - remove: Remove a sequence of strings from this set of constraints. +/// +/// - removeAsync: Remove a sequence of strings from this set of constraints. +/// +/// - `get`: Returns a sequence of strings describing the constraints in this set. +/// +/// - getAsync: Returns a sequence of strings describing the constraints in this set. +public extension StringSetPrx { + /// Add a sequence of strings to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter _: `Ice.StringSeq` The sequence of strings to be added. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func add(_ iceP_additions: Ice.StringSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "add", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_additions) + }, + context: context) + } + + /// Add a sequence of strings to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter _: `Ice.StringSeq` The sequence of strings to be added. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func addAsync(_ iceP_additions: Ice.StringSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "add", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_additions) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Remove a sequence of strings from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter _: `Ice.StringSeq` The sequence of strings to be removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func remove(_ iceP_deletions: Ice.StringSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "remove", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_deletions) + }, + context: context) + } + + /// Remove a sequence of strings from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter _: `Ice.StringSeq` The sequence of strings to be removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func removeAsync(_ iceP_deletions: Ice.StringSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "remove", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_deletions) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns a sequence of strings describing the constraints in this + /// set. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The sequence of strings for this set. + func `get`(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "get", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Returns a sequence of strings describing the constraints in this + /// set. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "get", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// An object for managing the set of object identity constraints on a +/// Session. +/// +/// IdentitySetPrx Methods: +/// +/// - add: Add a sequence of Ice identities to this set of constraints. +/// +/// - addAsync: Add a sequence of Ice identities to this set of constraints. +/// +/// - remove: Remove a sequence of identities from this set of constraints. +/// +/// - removeAsync: Remove a sequence of identities from this set of constraints. +/// +/// - `get`: Returns a sequence of identities describing the constraints in this set. +/// +/// - getAsync: Returns a sequence of identities describing the constraints in this set. +public protocol IdentitySetPrx: Ice.ObjectPrx {} + +private final class IdentitySetPrxI: Ice.ObjectPrxI, IdentitySetPrx { + public override class func ice_staticId() -> Swift.String { + return IdentitySetTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `IdentitySetPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `IdentitySetPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: IdentitySetPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> IdentitySetPrx? { + return try IdentitySetPrxI.checkedCast(prx: prx, facet: facet, context: context) as IdentitySetPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `IdentitySetPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `IdentitySetPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: IdentitySetPrx.Protocol, facet: Swift.String? = nil) -> IdentitySetPrx { + return IdentitySetPrxI.uncheckedCast(prx: prx, facet: facet) as IdentitySetPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `IdentitySetPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: IdentitySetPrx.Protocol) -> Swift.String { + return IdentitySetTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `IdentitySetPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `IdentitySetPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `IdentitySetPrx?` - The extracted proxy + func read(_ type: IdentitySetPrx.Protocol) throws -> IdentitySetPrx? { + return try read() as IdentitySetPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `IdentitySetPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `IdentitySetPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: IdentitySetPrx.Protocol) throws -> IdentitySetPrx? { + return try read(tag: tag) as IdentitySetPrxI? + } +} + +/// An object for managing the set of object identity constraints on a +/// Session. +/// +/// IdentitySetPrx Methods: +/// +/// - add: Add a sequence of Ice identities to this set of constraints. +/// +/// - addAsync: Add a sequence of Ice identities to this set of constraints. +/// +/// - remove: Remove a sequence of identities from this set of constraints. +/// +/// - removeAsync: Remove a sequence of identities from this set of constraints. +/// +/// - `get`: Returns a sequence of identities describing the constraints in this set. +/// +/// - getAsync: Returns a sequence of identities describing the constraints in this set. +public extension IdentitySetPrx { + /// Add a sequence of Ice identities to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter _: `Ice.IdentitySeq` The sequence of Ice identities to be added. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func add(_ iceP_additions: Ice.IdentitySeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "add", + mode: .Idempotent, + write: { ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_additions) + }, + context: context) + } + + /// Add a sequence of Ice identities to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter _: `Ice.IdentitySeq` The sequence of Ice identities to be added. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func addAsync(_ iceP_additions: Ice.IdentitySeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "add", + mode: .Idempotent, + write: { ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_additions) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Remove a sequence of identities from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter _: `Ice.IdentitySeq` The sequence of Ice identities to be removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func remove(_ iceP_deletions: Ice.IdentitySeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "remove", + mode: .Idempotent, + write: { ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_deletions) + }, + context: context) + } + + /// Remove a sequence of identities from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter _: `Ice.IdentitySeq` The sequence of Ice identities to be removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func removeAsync(_ iceP_deletions: Ice.IdentitySeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "remove", + mode: .Idempotent, + write: { ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_deletions) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns a sequence of identities describing the constraints in this + /// set. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.IdentitySeq` - The sequence of Ice identities for this set. + func `get`(context: Ice.Context? = nil) throws -> Ice.IdentitySeq { + return try _impl._invoke(operation: "get", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Returns a sequence of identities describing the constraints in this + /// set. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "get", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// An administrative session control object, which is tied to the +/// lifecycle of a Session. +/// +/// SessionControlPrx Methods: +/// +/// - categories: Access the object that manages the allowable categories for object identities for this session. +/// +/// - categoriesAsync: Access the object that manages the allowable categories for object identities for this session. +/// +/// - adapterIds: Access the object that manages the allowable adapter identities for objects for this session. +/// +/// - adapterIdsAsync: Access the object that manages the allowable adapter identities for objects for this session. +/// +/// - identities: Access the object that manages the allowable object identities for this session. +/// +/// - identitiesAsync: Access the object that manages the allowable object identities for this session. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - getSessionTimeoutAsync: Get the session timeout. +/// +/// - destroy: Destroy the associated session. +/// +/// - destroyAsync: Destroy the associated session. +public protocol SessionControlPrx: Ice.ObjectPrx {} + +private final class SessionControlPrxI: Ice.ObjectPrxI, SessionControlPrx { + public override class func ice_staticId() -> Swift.String { + return SessionControlTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SessionControlPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SessionControlPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SessionControlPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SessionControlPrx? { + return try SessionControlPrxI.checkedCast(prx: prx, facet: facet, context: context) as SessionControlPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SessionControlPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SessionControlPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SessionControlPrx.Protocol, facet: Swift.String? = nil) -> SessionControlPrx { + return SessionControlPrxI.uncheckedCast(prx: prx, facet: facet) as SessionControlPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SessionControlPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SessionControlPrx.Protocol) -> Swift.String { + return SessionControlTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SessionControlPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SessionControlPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionControlPrx?` - The extracted proxy + func read(_ type: SessionControlPrx.Protocol) throws -> SessionControlPrx? { + return try read() as SessionControlPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SessionControlPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionControlPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SessionControlPrx.Protocol) throws -> SessionControlPrx? { + return try read(tag: tag) as SessionControlPrxI? + } +} + +/// An administrative session control object, which is tied to the +/// lifecycle of a Session. +/// +/// SessionControlPrx Methods: +/// +/// - categories: Access the object that manages the allowable categories for object identities for this session. +/// +/// - categoriesAsync: Access the object that manages the allowable categories for object identities for this session. +/// +/// - adapterIds: Access the object that manages the allowable adapter identities for objects for this session. +/// +/// - adapterIdsAsync: Access the object that manages the allowable adapter identities for objects for this session. +/// +/// - identities: Access the object that manages the allowable object identities for this session. +/// +/// - identitiesAsync: Access the object that manages the allowable object identities for this session. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - getSessionTimeoutAsync: Get the session timeout. +/// +/// - destroy: Destroy the associated session. +/// +/// - destroyAsync: Destroy the associated session. +public extension SessionControlPrx { + /// Access the object that manages the allowable categories + /// for object identities for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `StringSetPrx?` - A StringSet object. + func categories(context: Ice.Context? = nil) throws -> StringSetPrx? { + return try _impl._invoke(operation: "categories", + mode: .Normal, + read: { istr in + let iceP_returnValue: StringSetPrx? = try istr.read(StringSetPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Access the object that manages the allowable categories + /// for object identities for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func categoriesAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "categories", + mode: .Normal, + read: { istr in + let iceP_returnValue: StringSetPrx? = try istr.read(StringSetPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Access the object that manages the allowable adapter identities + /// for objects for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `StringSetPrx?` - A StringSet object. + func adapterIds(context: Ice.Context? = nil) throws -> StringSetPrx? { + return try _impl._invoke(operation: "adapterIds", + mode: .Normal, + read: { istr in + let iceP_returnValue: StringSetPrx? = try istr.read(StringSetPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Access the object that manages the allowable adapter identities + /// for objects for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func adapterIdsAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "adapterIds", + mode: .Normal, + read: { istr in + let iceP_returnValue: StringSetPrx? = try istr.read(StringSetPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Access the object that manages the allowable object identities + /// for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `IdentitySetPrx?` - An IdentitySet object. + func identities(context: Ice.Context? = nil) throws -> IdentitySetPrx? { + return try _impl._invoke(operation: "identities", + mode: .Normal, + read: { istr in + let iceP_returnValue: IdentitySetPrx? = try istr.read(IdentitySetPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Access the object that manages the allowable object identities + /// for this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func identitiesAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "identities", + mode: .Normal, + read: { istr in + let iceP_returnValue: IdentitySetPrx? = try istr.read(IdentitySetPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the session timeout. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The timeout. + func getSessionTimeout(context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getSessionTimeout", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the session timeout. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSessionTimeoutAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSessionTimeout", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Destroy the associated session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func destroy(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "destroy", + mode: .Normal, + context: context) + } + + /// Destroy the associated session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func destroyAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "destroy", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The session manager for username/password authenticated users that +/// is responsible for managing Session objects. New session objects +/// are created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the application, +/// no client-visible sessions are passed to the client. +/// +/// SessionManagerPrx Methods: +/// +/// - create: Create a new session. +/// +/// - createAsync: Create a new session. +public protocol SessionManagerPrx: Ice.ObjectPrx {} + +private final class SessionManagerPrxI: Ice.ObjectPrxI, SessionManagerPrx { + public override class func ice_staticId() -> Swift.String { + return SessionManagerTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SessionManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SessionManagerPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SessionManagerPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SessionManagerPrx? { + return try SessionManagerPrxI.checkedCast(prx: prx, facet: facet, context: context) as SessionManagerPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SessionManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SessionManagerPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SessionManagerPrx.Protocol, facet: Swift.String? = nil) -> SessionManagerPrx { + return SessionManagerPrxI.uncheckedCast(prx: prx, facet: facet) as SessionManagerPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SessionManagerPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SessionManagerPrx.Protocol) -> Swift.String { + return SessionManagerTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SessionManagerPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SessionManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionManagerPrx?` - The extracted proxy + func read(_ type: SessionManagerPrx.Protocol) throws -> SessionManagerPrx? { + return try read() as SessionManagerPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SessionManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionManagerPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SessionManagerPrx.Protocol) throws -> SessionManagerPrx? { + return try read(tag: tag) as SessionManagerPrxI? + } +} + +/// The session manager for username/password authenticated users that +/// is responsible for managing Session objects. New session objects +/// are created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the application, +/// no client-visible sessions are passed to the client. +/// +/// SessionManagerPrx Methods: +/// +/// - create: Create a new session. +/// +/// - createAsync: Create a new session. +public extension SessionManagerPrx { + /// Create a new session. + /// + /// - parameter userId: `Swift.String` The user id for the session. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy to the newly created session. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + func create(userId iceP_userId: Swift.String, control iceP_control: SessionControlPrx?, context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "create", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_control) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a new session. + /// + /// - parameter userId: `Swift.String` The user id for the session. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createAsync(userId iceP_userId: Swift.String, control iceP_control: SessionControlPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "create", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_control) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The session manager for SSL authenticated users that is +/// responsible for managing Session objects. New session objects are +/// created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the +/// application, no client-visible sessions are passed to the client. +/// +/// SSLSessionManagerPrx Methods: +/// +/// - create: Create a new session. +/// +/// - createAsync: Create a new session. +public protocol SSLSessionManagerPrx: Ice.ObjectPrx {} + +private final class SSLSessionManagerPrxI: Ice.ObjectPrxI, SSLSessionManagerPrx { + public override class func ice_staticId() -> Swift.String { + return SSLSessionManagerTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SSLSessionManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SSLSessionManagerPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SSLSessionManagerPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SSLSessionManagerPrx? { + return try SSLSessionManagerPrxI.checkedCast(prx: prx, facet: facet, context: context) as SSLSessionManagerPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SSLSessionManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SSLSessionManagerPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SSLSessionManagerPrx.Protocol, facet: Swift.String? = nil) -> SSLSessionManagerPrx { + return SSLSessionManagerPrxI.uncheckedCast(prx: prx, facet: facet) as SSLSessionManagerPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SSLSessionManagerPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SSLSessionManagerPrx.Protocol) -> Swift.String { + return SSLSessionManagerTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SSLSessionManagerPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SSLSessionManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SSLSessionManagerPrx?` - The extracted proxy + func read(_ type: SSLSessionManagerPrx.Protocol) throws -> SSLSessionManagerPrx? { + return try read() as SSLSessionManagerPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SSLSessionManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SSLSessionManagerPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SSLSessionManagerPrx.Protocol) throws -> SSLSessionManagerPrx? { + return try read(tag: tag) as SSLSessionManagerPrxI? + } +} + +/// The session manager for SSL authenticated users that is +/// responsible for managing Session objects. New session objects are +/// created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the +/// application, no client-visible sessions are passed to the client. +/// +/// SSLSessionManagerPrx Methods: +/// +/// - create: Create a new session. +/// +/// - createAsync: Create a new session. +public extension SSLSessionManagerPrx { + /// Create a new session. + /// + /// - parameter info: `SSLInfo` The SSL info. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy to the newly created session. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + func create(info iceP_info: SSLInfo, control iceP_control: SessionControlPrx?, context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "create", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_info) + ostr.write(iceP_control) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a new session. + /// + /// - parameter info: `SSLInfo` The SSL info. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createAsync(info iceP_info: SSLInfo, control iceP_control: SessionControlPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "create", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_info) + ostr.write(iceP_control) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as CannotCreateSessionException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Session` servants. +public struct SessionDisp: Ice.Disp { + public let servant: Session + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Session) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// A client-visible session object, which is tied to the lifecycle of a Router. +public protocol Session { + /// Destroy the session. This is called automatically when the router is destroyed. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func destroy(current: Ice.Current) throws +} + + +/// Dispatcher for `StringSet` servants. +public struct StringSetDisp: Ice.Disp { + public let servant: StringSet + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: StringSet) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "add": + return try servant._iceD_add(incoming: request, current: current) + case "get": + return try servant._iceD_get(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? StringSetDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? StringSetDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? StringSetDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? StringSetDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "remove": + return try servant._iceD_remove(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// An object for managing the set of identity constraints for specific +/// parts of object identity on a +/// Session. +public protocol StringSet { + /// Add a sequence of strings to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter additions: `Ice.StringSeq` The sequence of strings to be added. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func add(additions: Ice.StringSeq, current: Ice.Current) throws + + /// Remove a sequence of strings from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter deletions: `Ice.StringSeq` The sequence of strings to be removed. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func remove(deletions: Ice.StringSeq, current: Ice.Current) throws + + /// Returns a sequence of strings describing the constraints in this + /// set. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The sequence of strings for this set. + func `get`(current: Ice.Current) throws -> Ice.StringSeq +} + + +/// Dispatcher for `IdentitySet` servants. +public struct IdentitySetDisp: Ice.Disp { + public let servant: IdentitySet + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: IdentitySet) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "add": + return try servant._iceD_add(incoming: request, current: current) + case "get": + return try servant._iceD_get(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? IdentitySetDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? IdentitySetDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? IdentitySetDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? IdentitySetDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "remove": + return try servant._iceD_remove(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// An object for managing the set of object identity constraints on a +/// Session. +public protocol IdentitySet { + /// Add a sequence of Ice identities to this set of constraints. Order is + /// not preserved and duplicates are implicitly removed. + /// + /// - parameter additions: `Ice.IdentitySeq` The sequence of Ice identities to be added. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func add(additions: Ice.IdentitySeq, current: Ice.Current) throws + + /// Remove a sequence of identities from this set of constraints. No + /// errors are returned if an entry is not found. + /// + /// - parameter deletions: `Ice.IdentitySeq` The sequence of Ice identities to be removed. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func remove(deletions: Ice.IdentitySeq, current: Ice.Current) throws + + /// Returns a sequence of identities describing the constraints in this + /// set. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.IdentitySeq` - The sequence of Ice identities for this set. + func `get`(current: Ice.Current) throws -> Ice.IdentitySeq +} + + +/// Dispatcher for `SessionControl` servants. +public struct SessionControlDisp: Ice.Disp { + public let servant: SessionControl + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: SessionControl) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "adapterIds": + return try servant._iceD_adapterIds(incoming: request, current: current) + case "categories": + return try servant._iceD_categories(incoming: request, current: current) + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "getSessionTimeout": + return try servant._iceD_getSessionTimeout(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SessionControlDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SessionControlDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SessionControlDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SessionControlDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "identities": + return try servant._iceD_identities(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// An administrative session control object, which is tied to the +/// lifecycle of a Session. +public protocol SessionControl { + /// Access the object that manages the allowable categories + /// for object identities for this session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `StringSetPrx?` - A StringSet object. + func categories(current: Ice.Current) throws -> StringSetPrx? + + /// Access the object that manages the allowable adapter identities + /// for objects for this session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `StringSetPrx?` - A StringSet object. + func adapterIds(current: Ice.Current) throws -> StringSetPrx? + + /// Access the object that manages the allowable object identities + /// for this session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `IdentitySetPrx?` - An IdentitySet object. + func identities(current: Ice.Current) throws -> IdentitySetPrx? + + /// Get the session timeout. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The timeout. + func getSessionTimeout(current: Ice.Current) throws -> Swift.Int32 + + /// Destroy the associated session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func destroy(current: Ice.Current) throws +} + + +/// Dispatcher for `SessionManager` servants. +public struct SessionManagerDisp: Ice.Disp { + public let servant: SessionManager + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: SessionManager) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "create": + return try servant._iceD_create(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SessionManagerDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SessionManagerDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SessionManagerDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SessionManagerDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The session manager for username/password authenticated users that +/// is responsible for managing Session objects. New session objects +/// are created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the application, +/// no client-visible sessions are passed to the client. +public protocol SessionManager { + /// Create a new session. + /// + /// - parameter userId: `Swift.String` The user id for the session. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `SessionPrx?` - A proxy to the newly created session. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + func create(userId: Swift.String, control: SessionControlPrx?, current: Ice.Current) throws -> SessionPrx? +} + + +/// Dispatcher for `SSLSessionManager` servants. +public struct SSLSessionManagerDisp: Ice.Disp { + public let servant: SSLSessionManager + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: SSLSessionManager) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "create": + return try servant._iceD_create(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SSLSessionManagerDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SSLSessionManagerDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SSLSessionManagerDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SSLSessionManagerDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The session manager for SSL authenticated users that is +/// responsible for managing Session objects. New session objects are +/// created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the +/// application, no client-visible sessions are passed to the client. +public protocol SSLSessionManager { + /// Create a new session. + /// + /// - parameter info: `SSLInfo` The SSL info. + /// + /// - parameter control: `SessionControlPrx?` A proxy to the session control object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `SessionPrx?` - A proxy to the newly created session. + /// + /// - throws: + /// + /// - CannotCreateSessionException - Raised if the session + /// cannot be created. + func create(info: SSLInfo, control: SessionControlPrx?, current: Ice.Current) throws -> SessionPrx? +} + +/// A client-visible session object, which is tied to the lifecycle of a Router. +/// +/// Session Methods: +/// +/// - destroy: Destroy the session. +public extension Session { + func _iceD_destroy(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.destroy(current: current) + + return inS.setResult() + } +} + +/// An object for managing the set of identity constraints for specific +/// parts of object identity on a +/// Session. +/// +/// StringSet Methods: +/// +/// - add: Add a sequence of strings to this set of constraints. +/// +/// - remove: Remove a sequence of strings from this set of constraints. +/// +/// - `get`: Returns a sequence of strings describing the constraints in this set. +public extension StringSet { + func _iceD_add(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_additions: Ice.StringSeq = try inS.read { istr in + let iceP_additions: Ice.StringSeq = try istr.read() + return iceP_additions + } + + try self.add(additions: iceP_additions, current: current) + + return inS.setResult() + } + + func _iceD_remove(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_deletions: Ice.StringSeq = try inS.read { istr in + let iceP_deletions: Ice.StringSeq = try istr.read() + return iceP_deletions + } + + try self.remove(deletions: iceP_deletions, current: current) + + return inS.setResult() + } + + func _iceD_get(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.`get`(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} + +/// An object for managing the set of object identity constraints on a +/// Session. +/// +/// IdentitySet Methods: +/// +/// - add: Add a sequence of Ice identities to this set of constraints. +/// +/// - remove: Remove a sequence of identities from this set of constraints. +/// +/// - `get`: Returns a sequence of identities describing the constraints in this set. +public extension IdentitySet { + func _iceD_add(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_additions: Ice.IdentitySeq = try inS.read { istr in + let iceP_additions: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_additions + } + + try self.add(additions: iceP_additions, current: current) + + return inS.setResult() + } + + func _iceD_remove(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_deletions: Ice.IdentitySeq = try inS.read { istr in + let iceP_deletions: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_deletions + } + + try self.remove(deletions: iceP_deletions, current: current) + + return inS.setResult() + } + + func _iceD_get(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.`get`(current: current) + + return inS.setResult{ ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_returnValue) + } + } +} + +/// An administrative session control object, which is tied to the +/// lifecycle of a Session. +/// +/// SessionControl Methods: +/// +/// - categories: Access the object that manages the allowable categories for object identities for this session. +/// +/// - adapterIds: Access the object that manages the allowable adapter identities for objects for this session. +/// +/// - identities: Access the object that manages the allowable object identities for this session. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - destroy: Destroy the associated session. +public extension SessionControl { + func _iceD_categories(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.categories(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_adapterIds(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.adapterIds(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_identities(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.identities(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getSessionTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSessionTimeout(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_destroy(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.destroy(current: current) + + return inS.setResult() + } +} + +/// The session manager for username/password authenticated users that +/// is responsible for managing Session objects. New session objects +/// are created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the application, +/// no client-visible sessions are passed to the client. +/// +/// SessionManager Methods: +/// +/// - create: Create a new session. +public extension SessionManager { + func _iceD_create(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_userId, iceP_control): (Swift.String, SessionControlPrx?) = try inS.read { istr in + let iceP_userId: Swift.String = try istr.read() + let iceP_control: SessionControlPrx? = try istr.read(SessionControlPrx.self) + return (iceP_userId, iceP_control) + } + inS.setFormat(.SlicedFormat) + + let iceP_returnValue = try self.create(userId: iceP_userId, control: iceP_control, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} + +/// The session manager for SSL authenticated users that is +/// responsible for managing Session objects. New session objects are +/// created by the Router object calling on an application-provided +/// session manager. If no session manager is provided by the +/// application, no client-visible sessions are passed to the client. +/// +/// SSLSessionManager Methods: +/// +/// - create: Create a new session. +public extension SSLSessionManager { + func _iceD_create(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_info, iceP_control): (SSLInfo, SessionControlPrx?) = try inS.read { istr in + let iceP_info: SSLInfo = try istr.read() + let iceP_control: SessionControlPrx? = try istr.read(SessionControlPrx.self) + return (iceP_info, iceP_control) + } + inS.setFormat(.SlicedFormat) + + let iceP_returnValue = try self.create(info: iceP_info, control: iceP_control, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Ice/AdminFacetFactory.swift b/Sources/Ice/AdminFacetFactory.swift new file mode 100644 index 0000000..982f88b --- /dev/null +++ b/Sources/Ice/AdminFacetFactory.swift @@ -0,0 +1,130 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class AdminFacetFacade: ICEBlobjectFacade { + private let communicator: Communicator + var disp: Disp + + init(communicator: Communicator, disp: Disp) { + self.communicator = communicator + self.disp = disp + } + + func facadeInvoke(_ adapter: ICEObjectAdapter, + inEncapsBytes: UnsafeMutableRawPointer, + inEncapsCount: Int, + con: ICEConnection?, + name: String, + category: String, + facet: String, + operation: String, + mode: UInt8, + context: [String: String], + requestId: Int32, + encodingMajor: UInt8, + encodingMinor: UInt8, + response: @escaping ICEBlobjectResponse, + exception: @escaping ICEBlobjectException) { + let objectAdapter = adapter.getSwiftObject(ObjectAdapterI.self) { + let oa = ObjectAdapterI(handle: adapter, communicator: communicator) + + // Register the admin OA's id with the servant manager. This is used to distinguish between + // ObjectNotExistException and FacetNotExistException when a servant is not found on + // a Swift Admin OA. + oa.servantManager.setAdminId(Identity(name: name, category: category)) + return oa + } + + let connection = con?.getSwiftObject(ConnectionI.self) { ConnectionI(handle: con!) } ?? nil + + let current = Current(adapter: objectAdapter, + con: connection, + id: Identity(name: name, category: category), + facet: facet, + operation: operation, + mode: OperationMode(rawValue: mode)!, + ctx: context, + requestId: requestId, + encoding: EncodingVersion(major: encodingMajor, minor: encodingMinor)) + + let incoming = Incoming(istr: InputStream(communicator: communicator, + encoding: EncodingVersion(major: encodingMajor, + minor: encodingMinor), + bytes: Data(bytesNoCopy: inEncapsBytes, count: inEncapsCount, + deallocator: .none)), + response: response, + exception: exception, + current: current) + + dispatch(incoming: incoming, current: current) + } + + func dispatch(incoming: Incoming, current: Current) { + // Dispatch directly to the servant. Do not call invoke on Incoming + do { + // Request was dispatched asynchronously if promise is non-nil + if let promise = try disp.dispatch(request: incoming, current: current) { + // Use the thread which fulfilled the promise (on: nil) + promise.done(on: nil) { ostr in + incoming.setResult(ostr) + incoming.response() + }.catch(on: nil) { error in + incoming.exception(error) + } + } else { + incoming.response() + } + } catch { + incoming.exception(error) + } + } + + func facadeRemoved() {} +} + +final class UnsupportedAdminFacet: LocalObject, Object { + func ice_id(current _: Current) -> String { + return ObjectTraits.staticId + } + + func ice_ids(current _: Current) -> [String] { + return ObjectTraits.staticIds + } + + func ice_isA(id: String, current _: Current) -> Bool { + return id == ObjectTraits.staticId + } + + func ice_ping(current _: Current) {} +} + +class AdminFacetFactory: ICEAdminFacetFactory { + static func createProcess(_ communicator: ICECommunicator, handle: ICEProcess) -> ICEBlobjectFacade { + let c = communicator.getCachedSwiftObject(CommunicatorI.self) + return AdminFacetFacade(communicator: c, + disp: ProcessDisp(handle.getSwiftObject(ProcessI.self) { + ProcessI(handle: handle) + })) + } + + static func createProperties(_ communicator: ICECommunicator, handle: ICEPropertiesAdmin) -> ICEBlobjectFacade { + let c = communicator.getCachedSwiftObject(CommunicatorI.self) + + return AdminFacetFacade(communicator: c, + disp: PropertiesAdminDisp(handle.getSwiftObject(PropertiesAdminI.self) { + PropertiesAdminI(communicator: c, handle: handle) + })) + } + + static func createUnsupported(_ communicator: ICECommunicator, + handle: ICEUnsupportedAdminFacet) -> ICEBlobjectFacade { + let c = communicator.getCachedSwiftObject(CommunicatorI.self) + return AdminFacetFacade(communicator: c, + disp: ObjectDisp(handle.getSwiftObject(UnsupportedAdminFacet.self) { + UnsupportedAdminFacet(handle: handle) + })) + } +} diff --git a/Sources/Ice/Blobject.swift b/Sources/Ice/Blobject.swift new file mode 100644 index 0000000..83b9e64 --- /dev/null +++ b/Sources/Ice/Blobject.swift @@ -0,0 +1,41 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import PromiseKit + +/// Base protocol for dynamic dispatch servants. +public protocol Blobject { + /// Dispatch an incoming request. + /// + /// - parameter inEncaps: `Data` - The encoded in-parameters for the operation. + /// + /// - parameter current: `Ice.Current` - The Current object to pass to the operation. + /// + /// - returns: `(ok: Bool, outParams: Data)` - A tuple with the following fields: + /// + /// - ok: `Bool` - True if the operation completed successfully, false if + /// the operation raised a user exception (in this case, outParams + /// contains the encoded user exception). If the operation raises an + /// Ice run-time exception, it must throw it directly. + /// + /// - outParams: `Data` - The encoded out-paramaters and return value + /// for the operation. The return value follows any out-parameters. + func ice_invoke(inEncaps: Data, current: Current) throws -> (ok: Bool, outParams: Data) +} + +/// Request dispatcher for Blobject servants. +public struct BlobjectDisp: Disp { + public let servant: Blobject + + public init(_ servant: Blobject) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> Promise? { + let inEncaps = try request.readParamEncaps() + let invokeResult = try servant.ice_invoke(inEncaps: inEncaps, current: current) + return request.setResult(request.writeParamEncaps(ok: invokeResult.ok, outParams: invokeResult.outParams)) + } +} diff --git a/Sources/Ice/BlobjectAsync.swift b/Sources/Ice/BlobjectAsync.swift new file mode 100644 index 0000000..dea2a6b --- /dev/null +++ b/Sources/Ice/BlobjectAsync.swift @@ -0,0 +1,41 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import PromiseKit + +/// Base protocol for dynamic asynchronous dispatch servants. +public protocol BlobjectAsync { + /// Dispatch an incoming request. + /// + /// - parameter inEncaps: `Data` - The encoded in-parameters for the operation. + /// + /// - parameter current: `Ice.Current` - The Current object to pass to the operation. + /// + /// - returns: `PromiseKit.Promise<(ok: Bool, outParams: Data)>` - The result of the operation. + /// + /// - ok: `Bool` - True if the operation completed successfully, false if + /// the operation raised a user exception (in this case, outParams + /// contains the encoded user exception). If the operation raises an + /// Ice run-time exception, it must throw it directly. + /// + /// - outParams: `Data` - The encoded out-paramaters and return value + /// for the operation. The return value follows any out-parameters. + func ice_invokeAsync(inEncaps: Data, current: Current) -> Promise<(ok: Bool, outParams: Data)> +} + +/// Request dispatcher for BlobjectAsync servants. +public struct BlobjectAsyncDisp: Disp { + public let servant: BlobjectAsync + + public init(_ servant: BlobjectAsync) { + self.servant = servant + } + public func dispatch(request: Request, current: Current) throws -> Promise? { + let inEncaps = try request.readParamEncaps() + return servant.ice_invokeAsync(inEncaps: inEncaps, current: current).map(on: nil) { invokeResult in + request.writeParamEncaps(ok: invokeResult.ok, outParams: invokeResult.outParams) + } + } +} diff --git a/Sources/Ice/ClassResolver.swift b/Sources/Ice/ClassResolver.swift new file mode 100644 index 0000000..0f6903f --- /dev/null +++ b/Sources/Ice/ClassResolver.swift @@ -0,0 +1,68 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation + +open class ValueTypeResolver: NSObject { + open func type() -> Value.Type { + fatalError("Abstract method") + } +} + +open class UserExceptionTypeResolver: NSObject { + open func type() -> UserException.Type { + fatalError("Abstract method") + } +} + +// +// The generated code for Slice classes and exceptions provides an extension for +// Ice.ClassResolver with a static function that returns a ValueTypeResolver or +// UserExceptionTypeResolver. +// +public class ClassResolver: NSObject { + private static func resolveImpl(typeId: String, prefix: String?) -> AnyObject? { + return autoreleasepool { + let start = typeId.index(typeId.startIndex, offsetBy: 2) + let selector = Selector((prefix ?? "") + typeId[start...].replacingOccurrences(of: "::", with: "_")) + guard ClassResolver.responds(to: selector) else { + return nil + } + return ClassResolver.perform(selector).takeUnretainedValue() + } + } + + static func resolve(typeId: String, prefix: String? = nil) -> Value.Type? { + guard let t = resolveImpl(typeId: typeId, prefix: prefix) as? ValueTypeResolver else { + return nil + } + return t.type() + } + + static func resolve(typeId: String, prefix: String? = nil) -> UserException.Type? { + guard let t = resolveImpl(typeId: typeId, prefix: prefix) as? UserExceptionTypeResolver else { + return nil + } + return t.type() + } +} + +public class TypeIdResolver: NSObject { + static func resolve(compactId: Int32) -> String? { + return autoreleasepool { + let selector = Selector("TypeId_\(compactId)") + + guard TypeIdResolver.responds(to: selector) else { + return nil + } + + let val = TypeIdResolver.perform(selector).takeUnretainedValue() + + guard let typeId = val as? String else { + preconditionFailure("unexpected value type") + } + return typeId + } + } +} diff --git a/Sources/Ice/CommunicatorI.swift b/Sources/Ice/CommunicatorI.swift new file mode 100644 index 0000000..0f930e3 --- /dev/null +++ b/Sources/Ice/CommunicatorI.swift @@ -0,0 +1,321 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl +import PromiseKit + +class CommunicatorI: LocalObject, Communicator { + private let valueFactoryManager: ValueFactoryManager = ValueFactoryManagerI() + let defaultsAndOverrides: DefaultsAndOverrides + let initData: InitializationData + let classGraphDepthMax: Int32 + let traceSlicing: Bool + let acceptClassCycles: Bool + + init(handle: ICECommunicator, initData: InitializationData) { + defaultsAndOverrides = DefaultsAndOverrides(handle: handle) + self.initData = initData + let num = initData.properties!.getPropertyAsIntWithDefault(key: "Ice.ClassGraphDepthMax", value: 50) + if num < 1 || num > 0x7FFF_FFFF { + classGraphDepthMax = 0x7FFF_FFFF + } else { + classGraphDepthMax = num + } + traceSlicing = initData.properties!.getPropertyAsIntWithDefault(key: "Ice.Trace.Slicing", value: 0) > 0 + acceptClassCycles = initData.properties!.getPropertyAsIntWithDefault(key: "Ice.AcceptClassCycles", value: 0) > 0 + + super.init(handle: handle) + } + + func destroy() { + handle.destroy() + } + + func shutdown() { + handle.shutdown() + } + + func waitForShutdown() { + handle.waitForShutdown() + } + + func isShutdown() -> Bool { + return handle.isShutdown() + } + + func stringToProxy(_ str: String) throws -> ObjectPrx? { + return try autoreleasepool { + guard let prxHandle = try handle.stringToProxy(str: str) as? ICEObjectPrx else { + return nil + } + return ObjectPrxI(handle: prxHandle, communicator: self) + } + } + + func proxyToString(_ obj: ObjectPrx?) -> String { + return obj?.ice_toString() ?? "" + } + + func propertyToProxy(_ property: String) throws -> ObjectPrx? { + return try autoreleasepool { + guard let handle = try handle.propertyToProxy(property: property) as? ICEObjectPrx else { + return nil + } + return ObjectPrxI(handle: handle, communicator: self) + } + } + + func proxyToProperty(proxy: ObjectPrx, property: String) -> PropertyDict { + precondition(!proxy.ice_isFixed(), "Cannot create property for fixed proxy") + do { + return try autoreleasepool { + try handle.proxyToProperty(prx: proxy._impl.handle, property: property) + } + } catch is CommunicatorDestroyedException { + return PropertyDict() + } catch { + fatalError("\(error)") + } + } + + func identityToString(_ id: Identity) -> String { + return Ice.identityToString(id: id) + } + + func createObjectAdapter(_ name: String) throws -> ObjectAdapter { + return try autoreleasepool { + let handle = try self.handle.createObjectAdapter(name) + + return ObjectAdapterI(handle: handle, communicator: self) + } + } + + func createObjectAdapterWithEndpoints(name: String, endpoints: String) throws -> ObjectAdapter { + return try autoreleasepool { + let handle = try self.handle.createObjectAdapterWithEndpoints(name: name, endpoints: endpoints) + return ObjectAdapterI(handle: handle, communicator: self) + } + } + + func createObjectAdapterWithRouter(name: String, rtr: RouterPrx) throws -> ObjectAdapter { + return try autoreleasepool { + let handle = try self.handle.createObjectAdapterWithRouter(name: name, router: rtr._impl.handle) + return ObjectAdapterI(handle: handle, communicator: self) + } + } + + func getImplicitContext() -> ImplicitContext { + let handle = self.handle.getImplicitContext() + return handle.getSwiftObject(ImplicitContextI.self) { + ImplicitContextI(handle: handle) + } + } + + func getProperties() -> Properties { + return initData.properties! + } + + func getLogger() -> Logger { + return initData.logger! + } + + func getDefaultRouter() -> RouterPrx? { + guard let handle = handle.getDefaultRouter() else { + return nil + } + return RouterPrxI.fromICEObjectPrx(handle: handle, communicator: self) + } + + func setDefaultRouter(_ rtr: RouterPrx?) { + do { + try autoreleasepool { + try handle.setDefaultRouter((rtr as? ObjectPrxI)?.handle) + } + } catch is CommunicatorDestroyedException { + // Ignored + } catch { + fatalError("\(error)") + } + } + + func getDefaultLocator() -> LocatorPrx? { + guard let handle = handle.getDefaultLocator() else { + return nil + } + return LocatorPrxI.fromICEObjectPrx(handle: handle, communicator: self) + } + + func setDefaultLocator(_ loc: LocatorPrx?) { + do { + try autoreleasepool { + try handle.setDefaultLocator((loc as? ObjectPrxI)?.handle) + } + } catch is CommunicatorDestroyedException { + // Ignored + } catch { + fatalError("\(error)") + } + } + + func getValueFactoryManager() -> ValueFactoryManager { + return valueFactoryManager + } + + func flushBatchRequests(_ compress: CompressBatch) throws { + try autoreleasepool { + try handle.flushBatchRequests(compress.rawValue) + } + } + + func createAdmin(adminAdapter: ObjectAdapter?, adminId: Identity) throws -> ObjectPrx { + return try autoreleasepool { + let handle = try self.handle.createAdmin((adminAdapter as? ObjectAdapterI)?.handle, + name: adminId.name, + category: adminId.category) + if let adapter = adminAdapter { + // Register the admin OA's id with the servant manager. This is used to distingish between + // ObjectNotExistException and FacetNotExistException when a servant is not found on + // a Swift Admin OA. + (adapter as! ObjectAdapterI).servantManager.setAdminId(adminId) + } + + return ObjectPrxI(handle: handle, communicator: self) + } + } + + func getAdmin() throws -> ObjectPrx? { + return try autoreleasepool { + guard let handle = try handle.getAdmin() as? ICEObjectPrx else { + return nil + } + + return ObjectPrxI(handle: handle, communicator: self) + } + } + + func addAdminFacet(servant disp: Disp, facet: String) throws { + try autoreleasepool { + try handle.addAdminFacet(AdminFacetFacade(communicator: self, disp: disp), facet: facet) + } + } + + func removeAdminFacet(_ facet: String) throws -> Disp { + return try autoreleasepool { + guard let facade = try handle.removeAdminFacet(facet) as? AdminFacetFacade else { + preconditionFailure() + } + + return facade.disp + } + } + + func findAdminFacet(_ facet: String) -> Disp? { + do { + return try autoreleasepool { + guard let facade = try handle.findAdminFacet(facet) as? AdminFacetFacade else { + return nil + } + return facade.disp + } + } catch is CommunicatorDestroyedException { + // Ignored + return nil + } catch { + fatalError("\(error)") + } + } + + func findAllAdminFacets() -> FacetMap { + do { + return try autoreleasepool { + try handle.findAllAdminFacets().mapValues { facade in + (facade as! AdminFacetFacade).disp + } + } + } catch is CommunicatorDestroyedException { + // Ignored + return FacetMap() + } catch { + fatalError("\(error)") + } + } + + func getClientDispatchQueue() throws -> DispatchQueue { + return try autoreleasepool { + try handle.getClientDispatchQueue() + } + } + + func getServerDispatchQueue() throws -> DispatchQueue { + return try autoreleasepool { + try handle.getServerDispatchQueue() + } + } +} + +public extension Communicator { + func flushBatchRequestsAsync(_ compress: CompressBatch, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + let impl = self as! CommunicatorI + let sentCB = createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent) + return Promise { seal in + impl.handle.flushBatchRequestsAsync(compress.rawValue, + exception: { seal.reject($0) }, + sent: { + seal.fulfill(()) + if let sentCB = sentCB { + sentCB($0) + } + }) + } + } + + /// Establish the password prompt object. This must be done before + /// the IceSSL plug-in is initialized. + /// + /// - parameter prompt: `(() -> String)` - The password prompt. + func setSslPasswordPrompt(prompt: @escaping (() -> String)) { + (self as! CommunicatorI).handle.setSslPasswordPrompt(prompt) + } + + /// Establish the certificate verifier objet. This must be done before + /// any connection are established. + /// + /// - parameter prompt: `((SSLConnectionInfo) -> Bool)` The certificate verifier. + func setSslCertificateVerifier(verifier: @escaping ((SSLConnectionInfo) -> Bool)) { + (self as! CommunicatorI).handle.setSslCertificateVerifier { info in + verifier(info as! SSLConnectionInfo) + } + } + + /// Initialize the configured plug-ins. The communicator automatically initializes + /// the plug-ins by default, but an application may need to interact directly with + /// a plug-in prior to initialization. In this case, the application must set + /// `Ice.InitPlugins=0` and then invoke `initializePlugins` manually. The plug-ins are + /// initialized in the order in which they are loaded. If a plug-in raises an exception + /// during initialization, the communicator invokes destroy on the plug-ins that have + /// already been initialized. + /// + /// - throws: `InitializationException` Raised if the plug-ins have already been + /// initialized. + func initializePlugins() throws { + try autoreleasepool { + try (self as! CommunicatorI).handle.initializePlugins() + } + } +} + +struct DefaultsAndOverrides { + init(handle: ICECommunicator) { + var defaultEncoding = EncodingVersion() + handle.getDefaultEncoding(major: &defaultEncoding.major, minor: &defaultEncoding.minor) + self.defaultEncoding = defaultEncoding + defaultFormat = FormatType(rawValue: handle.getDefaultFormat())! + } + + let defaultEncoding: EncodingVersion + let defaultFormat: FormatType +} diff --git a/Sources/Ice/ConnectionI.swift b/Sources/Ice/ConnectionI.swift new file mode 100644 index 0000000..6cf1ac9 --- /dev/null +++ b/Sources/Ice/ConnectionI.swift @@ -0,0 +1,162 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl +import PromiseKit + +public extension Connection { + func flushBatchRequestsAsync(_ compress: CompressBatch, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + let impl = self as! ConnectionI + let sentCB = createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent) + return Promise { seal in + impl.handle.flushBatchRequestsAsync(compress.rawValue, + exception: { error in seal.reject(error) }, + sent: { + seal.fulfill(()) + if let sentCB = sentCB { + sentCB($0) + } + }) + } + } + + func heartbeatAsync(sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + let impl = self as! ConnectionI + return Promise { seal in + impl.handle.heartbeatAsync(exception: { error in seal.reject(error) }, + sent: createSentCallback(sentOn: sentOn, + sentFlags: sentFlags, + sent: sent)) + } + } + + // CustomStringConvertible implementation + var description: String { + return toString() + } +} + +class ConnectionI: LocalObject, Connection { + func close(_ mode: ConnectionClose) { + handle.close(mode.rawValue) + } + + func createProxy(_ id: Identity) throws -> ObjectPrx { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try autoreleasepool { + let handle = try self.handle.createProxy(id.name, category: id.category) + let communicator = handle.ice_getCommunicator().getCachedSwiftObject(CommunicatorI.self) + return ObjectPrxI(handle: handle, communicator: communicator) + } + } + + func setAdapter(_ oa: ObjectAdapter?) throws { + try autoreleasepool { + try handle.setAdapter((oa as? ObjectAdapterI)?.handle) + } + } + + func getAdapter() -> ObjectAdapter? { + guard let handle = handle.getAdapter() else { + return nil + } + + return handle.getCachedSwiftObject(ObjectAdapterI.self) + } + + func getEndpoint() -> Endpoint { + let handle = self.handle.getEndpoint() + return handle.getSwiftObject(EndpointI.self) { + EndpointI(handle: handle) + } + } + + func flushBatchRequests(_ compress: CompressBatch) throws { + return try autoreleasepool { + try handle.flushBatchRequests(compress.rawValue) + } + } + + func setCloseCallback(_ callback: CloseCallback?) throws { + return try autoreleasepool { + guard let cb = callback else { + try handle.setCloseCallback(nil) + return + } + + try handle.setCloseCallback { c in + precondition(c.getCachedSwiftObject(ConnectionI.self) === self) + cb(self) + } + } + } + + func setHeartbeatCallback(_ callback: HeartbeatCallback?) { + guard let cb = callback else { + handle.setHeartbeatCallback(nil) + return + } + + handle.setHeartbeatCallback { c in + precondition(c.getCachedSwiftObject(ConnectionI.self) === self) + cb(self) + } + } + + func heartbeat() throws { + return try autoreleasepool { + try handle.heartbeat() + } + } + + func setACM(timeout: Int32?, close: ACMClose?, heartbeat: ACMHeartbeat?) { + precondition(timeout ?? 0 >= 0, "Invalid negative ACM timeout value") + handle.setACM(timeout as NSNumber?, + close: close != nil ? close.unsafelyUnwrapped.rawValue as NSNumber : nil, + heartbeat: heartbeat != nil ? heartbeat.unsafelyUnwrapped.rawValue as NSNumber : nil) + } + + func getACM() -> ACM { + var timeout = Int32() + var close = UInt8() + var heartbeat = UInt8() + handle.getACM(&timeout, close: &close, heartbeat: &heartbeat) + return ACM(timeout: timeout, close: ACMClose(rawValue: close)!, heartbeat: ACMHeartbeat(rawValue: heartbeat)!) + } + + func type() -> String { + return handle.type() + } + + func timeout() -> Int32 { + return handle.timeout() + } + + func toString() -> String { + return handle.toString() + } + + func getInfo() throws -> ConnectionInfo { + // swiftlint:disable force_cast + return try handle.getInfo() as! ConnectionInfo + // swiftlint:enable force_cast + } + + func setBufferSize(rcvSize: Int32, sndSize: Int32) throws { + return try autoreleasepool { + try handle.setBufferSize(rcvSize, sndSize: sndSize) + } + } + + func throwException() throws { + return try autoreleasepool { + try handle.throwException() + } + } +} diff --git a/Sources/Ice/ConnectionInfoFactory.swift b/Sources/Ice/ConnectionInfoFactory.swift new file mode 100644 index 0000000..560682b --- /dev/null +++ b/Sources/Ice/ConnectionInfoFactory.swift @@ -0,0 +1,255 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import IceImpl + +private class ConnectionInfoI: ConnectionInfo { + var underlying: ConnectionInfo? + var incoming: Bool + var adapterName: String + var connectionId: String + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String) { + self.underlying = underlying + self.incoming = incoming + self.adapterName = adapterName + self.connectionId = connectionId + } +} + +private class IPConnectionInfoI: ConnectionInfoI, IPConnectionInfo { + var localAddress: String + var localPort: Int32 + var remoteAddress: String + var remotePort: Int32 + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + localAddress: String, localPort: Int32, remoteAddress: String, remotePort: Int32) { + self.localAddress = localAddress + self.localPort = localPort + self.remoteAddress = remoteAddress + self.remotePort = remotePort + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId) + } +} + +private class TCPConnectionInfoI: IPConnectionInfoI, TCPConnectionInfo { + var rcvSize: Int32 + var sndSize: Int32 + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + localAddress: String, localPort: Int32, remoteAddress: String, remotePort: Int32, + rcvSize: Int32, sndSize: Int32) { + self.rcvSize = rcvSize + self.sndSize = sndSize + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId, + localAddress: localAddress, localPort: localPort, + remoteAddress: remoteAddress, remotePort: remotePort) + } +} + +private class UDPConnectionInfoI: IPConnectionInfoI, UDPConnectionInfo { + var mcastAddress: String + var mcastPort: Int32 + var rcvSize: Int32 + var sndSize: Int32 + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + localAddress: String, localPort: Int32, remoteAddress: String, remotePort: Int32, + mcastAddress: String, mcastPort: Int32, rcvSize: Int32, sndSize: Int32) { + self.mcastAddress = mcastAddress + self.mcastPort = mcastPort + self.rcvSize = rcvSize + self.sndSize = sndSize + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId, + localAddress: localAddress, localPort: localPort, + remoteAddress: remoteAddress, remotePort: remotePort) + } +} + +private class WSConnectionInfoI: ConnectionInfoI, WSConnectionInfo { + var headers: HeaderDict + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + headers: HeaderDict) { + self.headers = headers + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId) + } +} + +private class SSLConnectionInfoI: ConnectionInfoI, SSLConnectionInfo { + var cipher: String + var certs: [SecCertificate] + var verified: Bool + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + cipher: String, certs: StringSeq, verified: Bool) { + self.cipher = cipher + self.certs = [] + let beginPrefix = "-----BEGIN CERTIFICATE-----\n" + let endPrefix = "\n-----END CERTIFICATE-----\n" + + for cert in certs { + var raw = cert + if raw.hasPrefix(beginPrefix) { + raw = String(raw.dropFirst(beginPrefix.count)) + raw = String(raw.dropLast(endPrefix.count)) + } + + if let data = NSData(base64Encoded: raw, options: .ignoreUnknownCharacters) { + if let c = SecCertificateCreateWithData(kCFAllocatorDefault, data) { + self.certs.append(c) + } + } + } + self.verified = verified + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId) + } +} + +#if os(iOS) || os(watchOS) || os(tvOS) + private class IAPConnectionInfoI: ConnectionInfoI, IAPConnectionInfo { + var name: String + var manufacturer: String + var modelNumber: String + var firmwareRevision: String + var hardwareRevision: String + var `protocol`: String + + init(underlying: ConnectionInfo?, incoming: Bool, adapterName: String, connectionId: String, + name: String, manufacturer: String, modelNumber: String, firmwareRevision: String, + hardwareRevision: String, + protocol: String) { + self.name = name + self.manufacturer = manufacturer + self.modelNumber = modelNumber + self.firmwareRevision = firmwareRevision + self.hardwareRevision = hardwareRevision + self.protocol = `protocol` + super.init(underlying: underlying, incoming: incoming, adapterName: adapterName, connectionId: connectionId) + } + } +#endif + +class ConnectionInfoFactory: ICEConnectionInfoFactory { + static func createIPConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + localAddress: String, + localPort: Int32, + remoteAddress: String, + remotePort: Int32) -> Any { + return IPConnectionInfoI(underlying: getUnderlying(underlying), + incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + localAddress: localAddress, + localPort: localPort, + remoteAddress: remoteAddress, + remotePort: remotePort) + } + + static func createTCPConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + localAddress: String, + localPort: Int32, + remoteAddress: String, + remotePort: Int32, + rcvSize: Int32, + sndSize: Int32) -> Any { + return TCPConnectionInfoI(underlying: getUnderlying(underlying), incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + localAddress: localAddress, + localPort: localPort, + remoteAddress: remoteAddress, + remotePort: remotePort, + rcvSize: rcvSize, + sndSize: sndSize) + } + + static func createUDPConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + localAddress: String, + localPort: Int32, + remoteAddress: String, + remotePort: Int32, mcastAddress: String, mcastPort: Int32, + rcvSize: Int32, + sndSize: Int32) -> Any { + return UDPConnectionInfoI(underlying: getUnderlying(underlying), incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + localAddress: localAddress, + localPort: localPort, + remoteAddress: remoteAddress, + remotePort: remotePort, + mcastAddress: mcastAddress, + mcastPort: mcastPort, + rcvSize: rcvSize, + sndSize: sndSize) + } + + static func createWSConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + headers: [String: String]) -> Any { + return WSConnectionInfoI(underlying: getUnderlying(underlying), + incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + headers: headers) + } + + static func createSSLConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + cipher: String, + certs: [String], verified: Bool) -> Any { + return SSLConnectionInfoI(underlying: getUnderlying(underlying), + incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + cipher: cipher, + certs: certs, + verified: verified) + } + + #if os(iOS) || os(watchOS) || os(tvOS) + + static func createIAPConnectionInfo(_ underlying: Any, + incoming: Bool, + adapterName: String, + connectionId: String, + name: String, + manufacturer: String, + modelNumber: String, + firmwareRevision: String, + hardwareRevision: String, + protocol: String) -> Any { + return IAPConnectionInfoI(underlying: getUnderlying(underlying), + incoming: incoming, + adapterName: adapterName, + connectionId: connectionId, + name: name, + manufacturer: manufacturer, + modelNumber: modelNumber, + firmwareRevision: firmwareRevision, + hardwareRevision: hardwareRevision, + protocol: `protocol`) + } + + #endif + + static func getUnderlying(_ info: Any) -> ConnectionInfo? { + return info as? ConnectionInfo + } +} diff --git a/Sources/Ice/EndpointI.swift b/Sources/Ice/EndpointI.swift new file mode 100644 index 0000000..8b6d1cd --- /dev/null +++ b/Sources/Ice/EndpointI.swift @@ -0,0 +1,185 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class EndpointI: LocalObject, Endpoint { + func toString() -> String { + return handle.toString() + } + + func getInfo() -> EndpointInfo? { + return handle.getInfo() as? EndpointInfo + } + + // CustomStringConvertible implementation + var description: String { + return toString() + } +} + +public func != (lhs: Endpoint?, rhs: Endpoint?) -> Bool { + return !(lhs == rhs) +} + +public func == (lhs: Endpoint?, rhs: Endpoint?) -> Bool { + if lhs === rhs { + return true + } else if lhs === nil && rhs === nil { + return true + } else if lhs === nil || rhs === nil { + return false + } else { + let lhsI = lhs as! EndpointI + let rhsI = rhs as! EndpointI + return lhsI.handle.isEqual(rhsI.handle) + } +} + +// We implement EndpointInfo as a LocalObject that delegates to an ObjC/C++ object. +// The alternative - delegating to the Endpoint object - is not practical since the public API +// of Endpoint in C++ does not expose type, datagram or secure. +class EndpointInfoI: LocalObject, EndpointInfo { + var underlying: EndpointInfo? + var timeout: Int32 + var compress: Bool + + init(handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool) { + self.underlying = underlying + self.timeout = timeout + self.compress = compress + super.init(handle: handle) + } + + func type() -> Int16 { + return handle.getType() + } + + func datagram() -> Bool { + return handle.getDatagram() + } + + func secure() -> Bool { + return handle.getSecure() + } +} + +// This class is logically abstract and only derived classes should be created. +class IPEndpointInfoI: EndpointInfoI, IPEndpointInfo { + var host: String + var port: Int32 + var sourceAddress: String + + init(handle: ICEEndpointInfo, + underlying: EndpointInfo?, + timeout: Int32, + compress: Bool, + host: String, + port: Int32, + sourceAddress: String) { + self.host = host + self.port = port + self.sourceAddress = sourceAddress + super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress) + } +} + +class TCPEndpointInfoI: IPEndpointInfoI, TCPEndpointInfo {} + +class UDPEndpointInfoI: IPEndpointInfoI, UDPEndpointInfo { + var mcastInterface: String + var mcastTtl: Int32 + + init(handle: ICEEndpointInfo, + underlying: EndpointInfo?, + timeout: Int32, + compress: Bool, + host: String, + port: Int32, + sourceAddress: String, + mcastInterface: String, + mcastTtl: Int32) { + self.mcastInterface = mcastInterface + self.mcastTtl = mcastTtl + super.init(handle: handle, + underlying: underlying, + timeout: timeout, + compress: compress, + host: host, + port: port, + sourceAddress: sourceAddress) + } +} + +class WSEndpointInfoI: EndpointInfoI, WSEndpointInfo { + var resource: String + + init(handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool, resource: String) { + self.resource = resource + super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress) + } +} + +class OpaqueEndpointInfoI: EndpointInfoI, OpaqueEndpointInfo { + var rawEncoding: EncodingVersion + var rawBytes: ByteSeq + + init(handle: ICEEndpointInfo, + underlying: EndpointInfo?, + timeout: Int32, + compress: Bool, + rawEncoding: EncodingVersion, + rawBytes: ByteSeq) { + self.rawEncoding = rawEncoding + self.rawBytes = rawBytes + super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress) + } +} + +// +// IceSSL +// +class SSLEndpointInfoI: EndpointInfoI, SSLEndpointInfo {} + +#if os(iOS) || os(watchOS) || os(tvOS) + + // IceIAP (iOS only) + class IAPEndpointInfoI: EndpointInfoI, IAPEndpointInfo { + var manufacturer: String + var modelNumber: String + var name: String + var `protocol`: String + + init(handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool, + manufacturer: String, modelNumber: String, name: String, protocol: String) { + self.manufacturer = manufacturer + self.modelNumber = modelNumber + self.name = name + self.protocol = `protocol` + super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress) + } + } + +#endif + +// +// Internal helpers to convert from ObjC to Swift objects +// +extension Array where Element == ICEEndpoint { + func fromObjc() -> EndpointSeq { + return map { objcEndpt in + objcEndpt.getSwiftObject(EndpointI.self) { + EndpointI(handle: objcEndpt) + } + } + } +} + +extension Array where Element == Endpoint { + func toObjc() -> [ICEEndpoint] { + return map { endpt in + (endpt as! EndpointI).handle + } + } +} diff --git a/Sources/Ice/EndpointInfoFactory.swift b/Sources/Ice/EndpointInfoFactory.swift new file mode 100644 index 0000000..51b4f37 --- /dev/null +++ b/Sources/Ice/EndpointInfoFactory.swift @@ -0,0 +1,106 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class EndpointInfoFactory: ICEEndpointInfoFactory { + static func createTCPEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool, + host: String, + port: Int32, + sourceAddress: String) -> Any { + return TCPEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress, + host: host, + port: port, + sourceAddress: sourceAddress) + } + + static func createUDPEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool, + host: String, + port: Int32, + sourceAddress: String, + mcastInterface: String, + mcastTtl: Int32) -> Any { + return UDPEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress, + host: host, + port: port, + sourceAddress: sourceAddress, + mcastInterface: mcastInterface, + mcastTtl: mcastTtl) + } + + static func createWSEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool, + resource: String) -> Any { + return WSEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress, + resource: resource) + } + + static func createOpaqueEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool, + encodingMajor: UInt8, + encodingMinor: UInt8, + rawBytes: Data) -> Any { + return OpaqueEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress, + rawEncoding: EncodingVersion(major: encodingMajor, minor: encodingMinor), + rawBytes: rawBytes) + } + + static func createSSLEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool) -> Any { + return SSLEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress) + } + + #if os(iOS) || os(watchOS) || os(tvOS) + + static func createIAPEndpointInfo(_ handle: ICEEndpointInfo, + underlying: Any, + timeout: Int32, + compress: Bool, + manufacturer: String, + modelNumber: String, + name: String, + protocol: String) -> Any { + return IAPEndpointInfoI(handle: handle, + underlying: getUnderlying(underlying), + timeout: timeout, + compress: compress, + manufacturer: manufacturer, + modelNumber: modelNumber, + name: name, + protocol: `protocol`) + } + + #endif + + static func getUnderlying(_ info: Any) -> EndpointInfo? { + return info as? EndpointInfo + } +} diff --git a/Sources/Ice/Exception.swift b/Sources/Ice/Exception.swift new file mode 100644 index 0000000..474c9fa --- /dev/null +++ b/Sources/Ice/Exception.swift @@ -0,0 +1,100 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// Base protocol for Ice exceptions. +public protocol Exception: Error { + /// Returns the type id of this exception. + /// + /// - returns: `String` - The type id of this exception. + func ice_id() -> String + static func ice_staticId() -> String +} + +public extension Exception { + func ice_id() -> String { + return type(of: self).ice_staticId() + } +} + +/// Base class for Ice run-time exceptions. +open class LocalException: Exception, CustomStringConvertible { + public let file: String + public let line: Int + + public var description: String { + return "\(file): \(line): \(ice_id())\(ice_print())" + } + + public init(file: String = #file, line: Int = #line) { + self.file = file + self.line = line + } + + open class func ice_staticId() -> String { + return "::Ice::LocalException" + } + + /// Returns a stringified description of this exception. + /// + /// - returns: `String` - The exception description. + open func ice_print() -> String { + return "" + } +} + +/// Base class for Ice user exceptions. +open class UserException: Exception { + public required init() {} + + open func _iceReadImpl(from _: InputStream) throws {} + open func _iceWriteImpl(to _: OutputStream) {} + + open func _usesClasses() -> Bool { + return false + } + + /// Returns the Slice type ID of the exception. + /// + /// - returns: `String` The Slice type ID. + open class func ice_staticId() -> String { + return "::Ice::UserException" + } + + open func _iceRead(from istr: InputStream) throws { + istr.startException() + try _iceReadImpl(from: istr) + try istr.endException(preserve: false) + } + + open func _iceWrite(to ostr: OutputStream) { + ostr.startException(data: nil) + _iceWriteImpl(to: ostr) + ostr.endException() + } + + /// Returns the sliced data if the exception has a preserved-slice base class and has been sliced during + /// un-marshaling, nil is returned otherwise. + /// + /// - returns: `SlicedData?` - The sliced data or nil. + open func ice_getSlicedData() -> SlicedData? { + return nil + } +} + +/// Error used to wrap C++ std::exception errors. +public class RuntimeError: LocalException { + private let message: String + + public override var description: String { + return message + } + + open override class func ice_staticId() -> String { + return "::Ice::RuntimeError" + } + + public init(_ message: String) { + self.message = message + } +} diff --git a/Sources/Ice/FormatType.swift b/Sources/Ice/FormatType.swift new file mode 100644 index 0000000..0104a77 --- /dev/null +++ b/Sources/Ice/FormatType.swift @@ -0,0 +1,10 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// This enumeration describes the possible formats for classes and exceptions. +public enum FormatType: UInt8 { + case DefaultFormat = 0 + case CompactFormat = 1 + case SlicedFormat = 2 +} diff --git a/Sources/Ice/IceIAP_ConnectionInfo.swift b/Sources/Ice/IceIAP_ConnectionInfo.swift new file mode 100644 index 0000000..f2d12bd --- /dev/null +++ b/Sources/Ice/IceIAP_ConnectionInfo.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// Provides access to the connection details of an IAP connection +public protocol IAPConnectionInfo: ConnectionInfo { + /// The accessory name. + var name: Swift.String { get set } + /// The accessory manufacturer. + var manufacturer: Swift.String { get set } + /// The accessory model number. + var modelNumber: Swift.String { get set } + /// The accessory firmare revision. + var firmwareRevision: Swift.String { get set } + /// The accessory hardware revision. + var hardwareRevision: Swift.String { get set } + /// The protocol used by the accessory. + var `protocol`: Swift.String { get set } +} diff --git a/Sources/Ice/IceIAP_EndpointInfo.swift b/Sources/Ice/IceIAP_EndpointInfo.swift new file mode 100644 index 0000000..2e710ab --- /dev/null +++ b/Sources/Ice/IceIAP_EndpointInfo.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// Provides access to an IAP endpoint information. +public protocol IAPEndpointInfo: EndpointInfo { + /// The accessory manufacturer or empty to not match against + /// a manufacturer. + var manufacturer: Swift.String { get set } + /// The accessory model number or empty to not match against + /// a model number. + var modelNumber: Swift.String { get set } + /// The accessory name or empty to not match against + /// the accessory name. + var name: Swift.String { get set } + /// The protocol supported by the accessory. + var `protocol`: Swift.String { get set } +} diff --git a/Sources/Ice/IceSSL_ConnectionInfo.swift b/Sources/Ice/IceSSL_ConnectionInfo.swift new file mode 100644 index 0000000..a9ddddf --- /dev/null +++ b/Sources/Ice/IceSSL_ConnectionInfo.swift @@ -0,0 +1,26 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// Provides access to the connection details of an SSL connection +public protocol SSLConnectionInfo: ConnectionInfo { + /// The negotiated cipher suite. + var cipher: Swift.String { get set } + /// The certificate chain. + var certs: [SecCertificate] { get set } + /// The certificate chain verification status. + var verified: Swift.Bool { get set } +} diff --git a/Sources/Ice/IceSSL_ConnectionInfoF.swift b/Sources/Ice/IceSSL_ConnectionInfoF.swift new file mode 100644 index 0000000..4b8dc51 --- /dev/null +++ b/Sources/Ice/IceSSL_ConnectionInfoF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfoF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/IceSSL_EndpointInfo.swift b/Sources/Ice/IceSSL_EndpointInfo.swift new file mode 100644 index 0000000..53d1b5b --- /dev/null +++ b/Sources/Ice/IceSSL_EndpointInfo.swift @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// Provides access to an SSL endpoint information. +public protocol SSLEndpointInfo: EndpointInfo {} diff --git a/Sources/Ice/Ice_BuiltinSequences.swift b/Sources/Ice/Ice_BuiltinSequences.swift new file mode 100644 index 0000000..51665e2 --- /dev/null +++ b/Sources/Ice/Ice_BuiltinSequences.swift @@ -0,0 +1,174 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `BuiltinSequences.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A sequence of bools. +public typealias BoolSeq = [Swift.Bool] + +/// A sequence of bytes. +public typealias ByteSeq = Foundation.Data + +/// A sequence of shorts. +public typealias ShortSeq = [Swift.Int16] + +/// A sequence of ints. +public typealias IntSeq = [Swift.Int32] + +/// A sequence of longs. +public typealias LongSeq = [Swift.Int64] + +/// A sequence of floats. +public typealias FloatSeq = [Swift.Float] + +/// A sequence of doubles. +public typealias DoubleSeq = [Swift.Double] + +/// A sequence of strings. +public typealias StringSeq = [Swift.String] + +/// A sequence of objects. +public typealias ObjectSeq = [Value?] + +/// Helper class to read and write `ObjectSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ObjectSeqHelper { + /// Read a `ObjectSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ObjectSeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> ObjectSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 1) + var v = ObjectSeq(repeating: nil, count: sz) + for i in 0 ..< sz { + try Swift.withUnsafeMutablePointer(to: &v[i]) { p in + try istr.read() { p.pointee = $0 } + } + } + return v + } + /// Read an optional `ObjectSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectSeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> ObjectSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ObjectSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ObjectSeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: ObjectSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ObjectSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectSeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: ObjectSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A sequence of object proxies. +public typealias ObjectProxySeq = [ObjectPrx?] + +/// Helper class to read and write `ObjectProxySeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ObjectProxySeqHelper { + /// Read a `ObjectProxySeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ObjectProxySeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> ObjectProxySeq { + let sz = try istr.readAndCheckSeqSize(minSize: 2) + var v = ObjectProxySeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ObjectPrx? = try istr.read(ObjectPrx.self) + v.append(j) + } + return v + } + /// Read an optional `ObjectProxySeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectProxySeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> ObjectProxySeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ObjectProxySeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ObjectProxySeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: ObjectProxySeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ObjectProxySeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectProxySeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: ObjectProxySeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} diff --git a/Sources/Ice/Ice_Communicator.swift b/Sources/Ice/Ice_Communicator.swift new file mode 100644 index 0000000..13a22f0 --- /dev/null +++ b/Sources/Ice/Ice_Communicator.swift @@ -0,0 +1,381 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Communicator.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// The output mode for xxxToString method such as identityToString and proxyToString. +/// The actual encoding format for the string is the same for all modes: you +/// don't need to specify an encoding format or mode when reading such a string. +public enum ToStringMode: Swift.UInt8 { + /// Unicode Characters with ordinal values greater than 127 are kept as-is in the resulting string. + /// Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + /// or \\unnnn. + case Unicode = 0 + /// ASCII Characters with ordinal values greater than 127 are encoded as universal character names in + /// the resulting string: \\unnnn for BMP characters and \\Unnnnnnnn for non-BMP characters. + /// Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + /// or \\unnnn. + case ASCII = 1 + /// Compat Characters with ordinal values greater than 127 are encoded as a sequence of UTF-8 bytes using + /// octal escapes. Characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) or + /// an octal escape. Use this mode to generate strings compatible with Ice 3.6 and earlier. + case Compat = 2 + public init() { + self = .Unicode + } +} + +/// An `Ice.InputStream` extension to read `ToStringMode` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `ToStringMode` - The enumarated value. + func read() throws -> ToStringMode { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 2) + guard let val = ToStringMode(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `ToStringMode` - The enumerated value. + func read(tag: Swift.Int32) throws -> ToStringMode? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as ToStringMode + } +} + +/// An `Ice.OutputStream` extension to write `ToStringMode` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `ToStringMode` - The enumerator to write. + func write(_ v: ToStringMode) { + write(enum: v.rawValue, maxValue: 2) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `ToStringMode` - The enumerator to write. + func write(tag: Swift.Int32, value: ToStringMode?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 2) + } +} + +/// The central object in Ice. One or more communicators can be +/// instantiated for an Ice application. Communicator instantiation +/// is language-specific, and not specified in Slice code. +public protocol Communicator: Swift.AnyObject { + /// Destroy the communicator. This operation calls shutdown + /// implicitly. Calling destroy cleans up memory, and shuts down + /// this communicator's client functionality and destroys all object + /// adapters. Subsequent calls to destroy are ignored. + func destroy() + + /// Shuts down this communicator's server functionality, which + /// includes the deactivation of all object adapters. Attempts to use a + /// deactivated object adapter raise ObjectAdapterDeactivatedException. + /// Subsequent calls to shutdown are ignored. + /// + /// After shutdown returns, no new requests are processed. However, requests + /// that have been started before shutdown was called might still be active. + /// You can use waitForShutdown to wait for the completion of all + /// requests. + func shutdown() + + /// Wait until the application has called shutdown (or destroy). + /// On the server side, this operation blocks the calling thread + /// until all currently-executing operations have completed. + /// On the client side, the operation simply blocks until another + /// thread has called shutdown or destroy. + /// + /// A typical use of this operation is to call it from the main thread, + /// which then waits until some other thread calls shutdown. + /// After shut-down is complete, the main thread returns and can do some + /// cleanup work before it finally calls destroy to shut down + /// the client functionality, and then exits the application. + func waitForShutdown() + + /// Check whether communicator has been shut down. + /// + /// - returns: `Swift.Bool` - True if the communicator has been shut down; false otherwise. + func isShutdown() -> Swift.Bool + + /// Convert a stringified proxy into a proxy. For example, + /// MyCategory/MyObject:tcp -h some_host -p + /// 10000 creates a proxy that refers to the Ice object + /// having an identity with a name "MyObject" and a category + /// "MyCategory", with the server running on host "some_host", port + /// 10000. If the stringified proxy does not parse correctly, the + /// operation throws one of ProxyParseException, EndpointParseException, + /// or IdentityParseException. Refer to the Ice manual for a detailed + /// description of the syntax supported by stringified proxies. + /// + /// - parameter _: `Swift.String` The stringified proxy to convert into a proxy. + /// + /// - returns: `ObjectPrx?` - The proxy, or nil if str is an empty string. + func stringToProxy(_ str: Swift.String) throws -> ObjectPrx? + + /// Convert a proxy into a string. + /// + /// - parameter _: `ObjectPrx?` The proxy to convert into a stringified proxy. + /// + /// - returns: `Swift.String` - The stringified proxy, or an empty string if + /// obj is nil. + func proxyToString(_ obj: ObjectPrx?) -> Swift.String + + /// Convert a set of proxy properties into a proxy. The "base" + /// name supplied in the property argument refers to a + /// property containing a stringified proxy, such as + /// MyProxy=id:tcp -h localhost -p 10000. Additional + /// properties configure local settings for the proxy, such as + /// MyProxy.PreferSecure=1. The "Properties" + /// appendix in the Ice manual describes each of the supported + /// proxy properties. + /// + /// - parameter _: `Swift.String` The base property name. + /// + /// - returns: `ObjectPrx?` - The proxy. + func propertyToProxy(_ property: Swift.String) throws -> ObjectPrx? + + /// Convert a proxy to a set of proxy properties. + /// + /// - parameter proxy: `ObjectPrx` The proxy. + /// + /// - parameter property: `Swift.String` The base property name. + /// + /// - returns: `PropertyDict` - The property set. + func proxyToProperty(proxy: ObjectPrx, property: Swift.String) -> PropertyDict + + /// Convert an identity into a string. + /// + /// - parameter _: `Identity` The identity to convert into a string. + /// + /// - returns: `Swift.String` - The "stringified" identity. + func identityToString(_ ident: Identity) -> Swift.String + + /// Create a new object adapter. The endpoints for the object + /// adapter are taken from the property name.Endpoints. + /// + /// It is legal to create an object adapter with the empty string as + /// its name. Such an object adapter is accessible via bidirectional + /// connections or by collocated invocations that originate from the + /// same communicator as is used by the adapter. + /// + /// Attempts to create a named object adapter for which no configuration + /// can be found raise InitializationException. + /// + /// - parameter _: `Swift.String` The object adapter name. + /// + /// - returns: `ObjectAdapter` - The new object adapter. + func createObjectAdapter(_ name: Swift.String) throws -> ObjectAdapter + + /// Create a new object adapter with endpoints. This operation sets + /// the property name.Endpoints, and then calls + /// createObjectAdapter. It is provided as a convenience + /// function. + /// + /// Calling this operation with an empty name will result in a + /// UUID being generated for the name. + /// + /// - parameter name: `Swift.String` The object adapter name. + /// + /// - parameter endpoints: `Swift.String` The endpoints for the object adapter. + /// + /// - returns: `ObjectAdapter` - The new object adapter. + func createObjectAdapterWithEndpoints(name: Swift.String, endpoints: Swift.String) throws -> ObjectAdapter + + /// Create a new object adapter with a router. This operation + /// creates a routed object adapter. + /// + /// Calling this operation with an empty name will result in a + /// UUID being generated for the name. + /// + /// - parameter name: `Swift.String` The object adapter name. + /// + /// - parameter rtr: `RouterPrx` The router. + /// + /// - returns: `ObjectAdapter` - The new object adapter. + func createObjectAdapterWithRouter(name: Swift.String, rtr: RouterPrx) throws -> ObjectAdapter + + /// Get the implicit context associated with this communicator. + /// + /// - returns: `ImplicitContext` - The implicit context associated with this communicator; + /// returns null when the property Ice.ImplicitContext is not set + /// or is set to None. + func getImplicitContext() -> ImplicitContext + + /// Get the properties for this communicator. + /// + /// - returns: `Properties` - This communicator's properties. + func getProperties() -> Properties + + /// Get the logger for this communicator. + /// + /// - returns: `Logger` - This communicator's logger. + func getLogger() -> Logger + + /// Get the default router this communicator. + /// + /// - returns: `RouterPrx?` - The default router for this communicator. + func getDefaultRouter() -> RouterPrx? + + /// Set a default router for this communicator. All newly + /// created proxies will use this default router. To disable the + /// default router, null can be used. Note that this + /// operation has no effect on existing proxies. + /// + /// You can also set a router for an individual proxy + /// by calling the operation ice_router on the proxy. + /// + /// - parameter _: `RouterPrx?` The default router to use for this communicator. + func setDefaultRouter(_ rtr: RouterPrx?) + + /// Get the default locator this communicator. + /// + /// - returns: `LocatorPrx?` - The default locator for this communicator. + func getDefaultLocator() -> LocatorPrx? + + /// Set a default Ice locator for this communicator. All newly + /// created proxy and object adapters will use this default + /// locator. To disable the default locator, null can be used. + /// Note that this operation has no effect on existing proxies or + /// object adapters. + /// + /// You can also set a locator for an individual proxy by calling the + /// operation ice_locator on the proxy, or for an object adapter + /// by calling ObjectAdapter.setLocator on the object adapter. + /// + /// - parameter _: `LocatorPrx?` The default locator to use for this communicator. + func setDefaultLocator(_ loc: LocatorPrx?) + + /// Get the value factory manager for this communicator. + /// + /// - returns: `ValueFactoryManager` - This communicator's value factory manager. + func getValueFactoryManager() -> ValueFactoryManager + + /// Flush any pending batch requests for this communicator. + /// This means all batch requests invoked on fixed proxies + /// for all connections associated with the communicator. + /// Any errors that occur while flushing a connection are ignored. + /// + /// - parameter _: `CompressBatch` Specifies whether or not the queued batch requests + /// should be compressed before being sent over the wire. + func flushBatchRequests(_ compress: CompressBatch) throws + + /// Flush any pending batch requests for this communicator. + /// This means all batch requests invoked on fixed proxies + /// for all connections associated with the communicator. + /// Any errors that occur while flushing a connection are ignored. + /// + /// - parameter _: `CompressBatch` Specifies whether or not the queued batch requests + /// should be compressed before being sent over the wire. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func flushBatchRequestsAsync(_ compress: CompressBatch, sentOn: Dispatch.DispatchQueue?, sentFlags: Dispatch.DispatchWorkItemFlags?, sent: ((Swift.Bool) -> Swift.Void)?) -> PromiseKit.Promise + + /// Add the Admin object with all its facets to the provided object adapter. + /// If Ice.Admin.ServerId is set and the provided object adapter has a Locator, + /// createAdmin registers the Admin's Process facet with the Locator's LocatorRegistry. + /// + /// createAdmin must only be called once; subsequent calls raise InitializationException. + /// + /// - parameter adminAdapter: `ObjectAdapter?` The object adapter used to host the Admin object; if null and + /// Ice.Admin.Endpoints is set, create, activate and use the Ice.Admin object adapter. + /// + /// - parameter adminId: `Identity` The identity of the Admin object. + /// + /// - returns: `ObjectPrx` - A proxy to the main ("") facet of the Admin object. Never returns a null proxy. + func createAdmin(adminAdapter: ObjectAdapter?, adminId: Identity) throws -> ObjectPrx + + /// Get a proxy to the main facet of the Admin object. + /// + /// getAdmin also creates the Admin object and creates and activates the Ice.Admin object + /// adapter to host this Admin object if Ice.Admin.Enpoints is set. The identity of the Admin + /// object created by getAdmin is {value of Ice.Admin.InstanceName}/admin, or {UUID}/admin + /// when Ice.Admin.InstanceName is not set. + /// + /// If Ice.Admin.DelayCreation is 0 or not set, getAdmin is called by the communicator + /// initialization, after initialization of all plugins. + /// + /// - returns: `ObjectPrx?` - A proxy to the main ("") facet of the Admin object, or a null proxy if no + /// Admin object is configured. + func getAdmin() throws -> ObjectPrx? + + /// Add a new facet to the Admin object. + /// Adding a servant with a facet that is already registered + /// throws AlreadyRegisteredException. + /// + /// - parameter servant: `Disp` The servant that implements the new Admin facet. + /// + /// - parameter facet: `Swift.String` The name of the new Admin facet. + func addAdminFacet(servant: Disp, facet: Swift.String) throws + + /// Remove the following facet to the Admin object. + /// Removing a facet that was not previously registered throws + /// NotRegisteredException. + /// + /// - parameter _: `Swift.String` The name of the Admin facet. + /// + /// - returns: `Disp` - The servant associated with this Admin facet. + @discardableResult + func removeAdminFacet(_ facet: Swift.String) throws -> Disp + + /// Returns a facet of the Admin object. + /// + /// - parameter _: `Swift.String` The name of the Admin facet. + /// + /// - returns: `Disp?` - The servant associated with this Admin facet, or + /// null if no facet is registered with the given name. + func findAdminFacet(_ facet: Swift.String) -> Disp? + + /// Returns a map of all facets of the Admin object. + /// + /// - returns: `FacetMap` - A collection containing all the facet names and + /// servants of the Admin object. + func findAllAdminFacets() -> FacetMap + + /// Returns the client dispatch queue. + /// + /// - returns: `Dispatch.DispatchQueue` - The dispatch queue associated wih this Communicator's + /// client thread pool. + func getClientDispatchQueue() throws -> Dispatch.DispatchQueue + + /// Returns the server dispatch queue. + /// + /// - returns: `Dispatch.DispatchQueue` - The dispatch queue associated wih the Communicator's + /// server thread pool. + func getServerDispatchQueue() throws -> Dispatch.DispatchQueue +} diff --git a/Sources/Ice/Ice_CommunicatorF.swift b/Sources/Ice/Ice_CommunicatorF.swift new file mode 100644 index 0000000..cfc186e --- /dev/null +++ b/Sources/Ice/Ice_CommunicatorF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `CommunicatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Connection.swift b/Sources/Ice/Ice_Connection.swift new file mode 100644 index 0000000..8933181 --- /dev/null +++ b/Sources/Ice/Ice_Connection.swift @@ -0,0 +1,585 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Connection.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// The batch compression option when flushing queued batch requests. +public enum CompressBatch: Swift.UInt8 { + /// Yes Compress the batch requests. + case Yes = 0 + /// No Don't compress the batch requests. + case No = 1 + /// BasedOnProxy Compress the batch requests if at least one request was + /// made on a compressed proxy. + case BasedOnProxy = 2 + public init() { + self = .Yes + } +} + +/// An `Ice.InputStream` extension to read `CompressBatch` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `CompressBatch` - The enumarated value. + func read() throws -> CompressBatch { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 2) + guard let val = CompressBatch(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `CompressBatch` - The enumerated value. + func read(tag: Swift.Int32) throws -> CompressBatch? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as CompressBatch + } +} + +/// An `Ice.OutputStream` extension to write `CompressBatch` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `CompressBatch` - The enumerator to write. + func write(_ v: CompressBatch) { + write(enum: v.rawValue, maxValue: 2) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `CompressBatch` - The enumerator to write. + func write(tag: Swift.Int32, value: CompressBatch?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 2) + } +} + +/// Specifies the close semantics for Active Connection Management. +public enum ACMClose: Swift.UInt8 { + /// CloseOff Disables automatic connection closure. + case CloseOff = 0 + /// CloseOnIdle Gracefully closes a connection that has been idle for the configured timeout period. + case CloseOnIdle = 1 + /// CloseOnInvocation Forcefully closes a connection that has been idle for the configured timeout period, + /// but only if the connection has pending invocations. + case CloseOnInvocation = 2 + /// CloseOnInvocationAndIdle Combines the behaviors of CloseOnIdle and CloseOnInvocation. + case CloseOnInvocationAndIdle = 3 + /// CloseOnIdleForceful Forcefully closes a connection that has been idle for the configured timeout period, + /// regardless of whether the connection has pending invocations or dispatch. + case CloseOnIdleForceful = 4 + public init() { + self = .CloseOff + } +} + +/// An `Ice.InputStream` extension to read `ACMClose` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `ACMClose` - The enumarated value. + func read() throws -> ACMClose { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 4) + guard let val = ACMClose(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `ACMClose` - The enumerated value. + func read(tag: Swift.Int32) throws -> ACMClose? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as ACMClose + } +} + +/// An `Ice.OutputStream` extension to write `ACMClose` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `ACMClose` - The enumerator to write. + func write(_ v: ACMClose) { + write(enum: v.rawValue, maxValue: 4) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `ACMClose` - The enumerator to write. + func write(tag: Swift.Int32, value: ACMClose?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 4) + } +} + +/// Specifies the heartbeat semantics for Active Connection Management. +public enum ACMHeartbeat: Swift.UInt8 { + /// HeartbeatOff Disables heartbeats. + case HeartbeatOff = 0 + /// HeartbeatOnDispatch Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. + case HeartbeatOnDispatch = 1 + /// HeartbeatOnIdle Send a heartbeat at regular intervals when the connection is idle. + case HeartbeatOnIdle = 2 + /// HeartbeatAlways Send a heartbeat at regular intervals until the connection is closed. + case HeartbeatAlways = 3 + public init() { + self = .HeartbeatOff + } +} + +/// An `Ice.InputStream` extension to read `ACMHeartbeat` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `ACMHeartbeat` - The enumarated value. + func read() throws -> ACMHeartbeat { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 3) + guard let val = ACMHeartbeat(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `ACMHeartbeat` - The enumerated value. + func read(tag: Swift.Int32) throws -> ACMHeartbeat? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as ACMHeartbeat + } +} + +/// An `Ice.OutputStream` extension to write `ACMHeartbeat` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `ACMHeartbeat` - The enumerator to write. + func write(_ v: ACMHeartbeat) { + write(enum: v.rawValue, maxValue: 3) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `ACMHeartbeat` - The enumerator to write. + func write(tag: Swift.Int32, value: ACMHeartbeat?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 3) + } +} + +/// A collection of Active Connection Management configuration settings. +public struct ACM: Swift.Hashable { + /// A timeout value in seconds. + public var timeout: Swift.Int32 = 0 + /// The close semantics. + public var close: ACMClose = .CloseOff + /// The heartbeat semantics. + public var heartbeat: ACMHeartbeat = .HeartbeatOff + + public init() {} + + public init(timeout: Swift.Int32, close: ACMClose, heartbeat: ACMHeartbeat) { + self.timeout = timeout + self.close = close + self.heartbeat = heartbeat + } +} + +/// Determines the behavior when manually closing a connection. +public enum ConnectionClose: Swift.UInt8 { + /// Forcefully Close the connection immediately without sending a close connection protocol message to the peer + /// and waiting for the peer to acknowledge it. + case Forcefully = 0 + /// Gracefully Close the connection by notifying the peer but do not wait for pending outgoing invocations to complete. + /// On the server side, the connection will not be closed until all incoming invocations have completed. + case Gracefully = 1 + /// GracefullyWithWait Wait for all pending invocations to complete before closing the connection. + case GracefullyWithWait = 2 + public init() { + self = .Forcefully + } +} + +/// An `Ice.InputStream` extension to read `ConnectionClose` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `ConnectionClose` - The enumarated value. + func read() throws -> ConnectionClose { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 2) + guard let val = ConnectionClose(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `ConnectionClose` - The enumerated value. + func read(tag: Swift.Int32) throws -> ConnectionClose? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as ConnectionClose + } +} + +/// An `Ice.OutputStream` extension to write `ConnectionClose` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `ConnectionClose` - The enumerator to write. + func write(_ v: ConnectionClose) { + write(enum: v.rawValue, maxValue: 2) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `ConnectionClose` - The enumerator to write. + func write(tag: Swift.Int32, value: ConnectionClose?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 2) + } +} + +/// A collection of HTTP headers. +public typealias HeaderDict = [Swift.String: Swift.String] + +/// Helper class to read and write `HeaderDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct HeaderDictHelper { + /// Read a `HeaderDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `HeaderDict` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> HeaderDict { + let sz = try Swift.Int(istr.readSize()) + var v = HeaderDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `HeaderDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `HeaderDict` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> HeaderDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `HeaderDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `HeaderDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: HeaderDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `HeaderDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `HeaderDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: HeaderDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Base class providing access to the connection details. +public protocol ConnectionInfo: Swift.AnyObject { + /// The information of the underyling transport or null if there's + /// no underlying transport. + var underlying: ConnectionInfo? { get set } + /// Whether or not the connection is an incoming or outgoing + /// connection. + var incoming: Swift.Bool { get set } + /// The name of the adapter associated with the connection. + var adapterName: Swift.String { get set } + /// The connection id. + var connectionId: Swift.String { get set } +} + +/// An application can implement this interface to receive notifications when +/// a connection closes. +/// +/// This method is called by the the connection when the connection +/// is closed. If the callback needs more information about the closure, +/// it can call Connection.throwException. +/// +/// - parameter _: `Connection?` The connection that closed. +public typealias CloseCallback = (Connection?) -> Swift.Void + +/// An application can implement this interface to receive notifications when +/// a connection receives a heartbeat message. +/// +/// This method is called by the the connection when a heartbeat is +/// received from the peer. +/// +/// - parameter _: `Connection?` The connection on which a heartbeat was received. +public typealias HeartbeatCallback = (Connection?) -> Swift.Void + +/// The user-level interface to a connection. +public protocol Connection: Swift.AnyObject, Swift.CustomStringConvertible { + /// Manually close the connection using the specified closure mode. + /// + /// - parameter _: `ConnectionClose` Determines how the connection will be closed. + func close(_ mode: ConnectionClose) throws + + /// Create a special proxy that always uses this connection. This + /// can be used for callbacks from a server to a client if the + /// server cannot directly establish a connection to the client, + /// for example because of firewalls. In this case, the server + /// would create a proxy using an already established connection + /// from the client. + /// + /// - parameter _: `Identity` The identity for which a proxy is to be created. + /// + /// - returns: `ObjectPrx` - A proxy that matches the given identity and uses this + /// connection. + func createProxy(_ id: Identity) throws -> ObjectPrx + + /// Explicitly set an object adapter that dispatches requests that + /// are received over this connection. A client can invoke an + /// operation on a server using a proxy, and then set an object + /// adapter for the outgoing connection that is used by the proxy + /// in order to receive callbacks. This is useful if the server + /// cannot establish a connection back to the client, for example + /// because of firewalls. + /// + /// - parameter _: `ObjectAdapter?` The object adapter that should be used by this + /// connection to dispatch requests. The object adapter must be + /// activated. When the object adapter is deactivated, it is + /// automatically removed from the connection. Attempts to use a + /// deactivated object adapter raise ObjectAdapterDeactivatedException + func setAdapter(_ adapter: ObjectAdapter?) throws + + /// Get the object adapter that dispatches requests for this + /// connection. + /// + /// - returns: `ObjectAdapter?` - The object adapter that dispatches requests for the + /// connection, or null if no adapter is set. + func getAdapter() -> ObjectAdapter? + + /// Get the endpoint from which the connection was created. + /// + /// - returns: `Endpoint` - The endpoint from which the connection was created. + func getEndpoint() -> Endpoint + + /// Flush any pending batch requests for this connection. + /// This means all batch requests invoked on fixed proxies + /// associated with the connection. + /// + /// - parameter _: `CompressBatch` Specifies whether or not the queued batch requests + /// should be compressed before being sent over the wire. + func flushBatchRequests(_ compress: CompressBatch) throws + + /// Flush any pending batch requests for this connection. + /// This means all batch requests invoked on fixed proxies + /// associated with the connection. + /// + /// - parameter _: `CompressBatch` Specifies whether or not the queued batch requests + /// should be compressed before being sent over the wire. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func flushBatchRequestsAsync(_ compress: CompressBatch, sentOn: Dispatch.DispatchQueue?, sentFlags: Dispatch.DispatchWorkItemFlags?, sent: ((Swift.Bool) -> Swift.Void)?) -> PromiseKit.Promise + + /// Set a close callback on the connection. The callback is called by the + /// connection when it's closed. The callback is called from the + /// Ice thread pool associated with the connection. If the callback needs + /// more information about the closure, it can call Connection.throwException. + /// + /// - parameter _: `CloseCallback?` The close callback object. + func setCloseCallback(_ callback: CloseCallback?) throws + + /// Set a heartbeat callback on the connection. The callback is called by the + /// connection when a heartbeat is received. The callback is called + /// from the Ice thread pool associated with the connection. + /// + /// - parameter _: `HeartbeatCallback?` The heartbeat callback object. + func setHeartbeatCallback(_ callback: HeartbeatCallback?) + + /// Send a heartbeat message. + func heartbeat() throws + + /// Send a heartbeat message. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func heartbeatAsync(sentOn: Dispatch.DispatchQueue?, sentFlags: Dispatch.DispatchWorkItemFlags?, sent: ((Swift.Bool) -> Swift.Void)?) -> PromiseKit.Promise + + /// Set the active connection management parameters. + /// + /// - parameter timeout: `Swift.Int32?` The timeout value in seconds, must be >= 0. + /// + /// - parameter close: `ACMClose?` The close condition + /// + /// - parameter heartbeat: `ACMHeartbeat?` The hertbeat condition + func setACM(timeout: Swift.Int32?, close: ACMClose?, heartbeat: ACMHeartbeat?) + + /// Get the ACM parameters. + /// + /// - returns: `ACM` - The ACM parameters. + func getACM() -> ACM + + /// Return the connection type. This corresponds to the endpoint + /// type, i.e., "tcp", "udp", etc. + /// + /// - returns: `Swift.String` - The type of the connection. + func `type`() -> Swift.String + + /// Get the timeout for the connection. + /// + /// - returns: `Swift.Int32` - The connection's timeout. + func timeout() -> Swift.Int32 + + /// Return a description of the connection as human readable text, + /// suitable for logging or error messages. + /// + /// - returns: `Swift.String` - The description of the connection as human readable + /// text. + func toString() -> Swift.String + + /// Returns the connection information. + /// + /// - returns: `ConnectionInfo` - The connection information. + func getInfo() throws -> ConnectionInfo + + /// Set the connection buffer receive/send size. + /// + /// - parameter rcvSize: `Swift.Int32` The connection receive buffer size. + /// + /// - parameter sndSize: `Swift.Int32` The connection send buffer size. + func setBufferSize(rcvSize: Swift.Int32, sndSize: Swift.Int32) throws + + /// Throw an exception indicating the reason for connection closure. For example, + /// CloseConnectionException is raised if the connection was closed gracefully, + /// whereas ConnectionManuallyClosedException is raised if the connection was + /// manually closed by the application. This operation does nothing if the connection is + /// not yet closed. + func throwException() throws +} + +/// Provides access to the connection details of an IP connection +public protocol IPConnectionInfo: ConnectionInfo { + /// The local address. + var localAddress: Swift.String { get set } + /// The local port. + var localPort: Swift.Int32 { get set } + /// The remote address. + var remoteAddress: Swift.String { get set } + /// The remote port. + var remotePort: Swift.Int32 { get set } +} + +/// Provides access to the connection details of a TCP connection +public protocol TCPConnectionInfo: IPConnectionInfo { + /// The connection buffer receive size. + var rcvSize: Swift.Int32 { get set } + /// The connection buffer send size. + var sndSize: Swift.Int32 { get set } +} + +/// Provides access to the connection details of a UDP connection +public protocol UDPConnectionInfo: IPConnectionInfo { + /// The multicast address. + var mcastAddress: Swift.String { get set } + /// The multicast port. + var mcastPort: Swift.Int32 { get set } + /// The connection buffer receive size. + var rcvSize: Swift.Int32 { get set } + /// The connection buffer send size. + var sndSize: Swift.Int32 { get set } +} + +/// Provides access to the connection details of a WebSocket connection +public protocol WSConnectionInfo: ConnectionInfo { + /// The headers from the HTTP upgrade request. + var headers: HeaderDict { get set } +} diff --git a/Sources/Ice/Ice_ConnectionF.swift b/Sources/Ice/Ice_ConnectionF.swift new file mode 100644 index 0000000..3d0ccf6 --- /dev/null +++ b/Sources/Ice/Ice_ConnectionF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Current.swift b/Sources/Ice/Ice_Current.swift new file mode 100644 index 0000000..6f52fea --- /dev/null +++ b/Sources/Ice/Ice_Current.swift @@ -0,0 +1,212 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Current.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A request context. Context is used to transmit metadata about a +/// request from the server to the client, such as Quality-of-Service +/// (QoS) parameters. Each operation on the client has a Context as +/// its implicit final parameter. +public typealias Context = [Swift.String: Swift.String] + +/// Helper class to read and write `Context` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ContextHelper { + /// Read a `Context` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `Context` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> Context { + let sz = try Swift.Int(istr.readSize()) + var v = Context() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `Context?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `Context` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> Context? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `Context` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `Context` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: Context) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `Context?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `Context` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: Context?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Determines the retry behavior an invocation in case of a (potentially) recoverable error. +public enum OperationMode: Swift.UInt8 { + /// Normal Ordinary operations have Normal mode. These operations + /// modify object state; invoking such an operation twice in a row + /// has different semantics than invoking it once. The Ice run time + /// guarantees that it will not violate at-most-once semantics for + /// Normal operations. + case Normal = 0 + /// `Nonmutating` Operations that use the Slice nonmutating keyword must not + /// modify object state. For C++, nonmutating operations generate + /// const member functions in the skeleton. In addition, the Ice + /// run time will attempt to transparently recover from certain + /// run-time errors by re-issuing a failed request and propagate + /// the failure to the application only if the second attempt + /// fails. + /// + /// Nonmutating is deprecated; Use the + /// idempotent keyword instead. For C++, to retain the mapping + /// of nonmutating operations to C++ const + /// member functions, use the ["cpp:const"] metadata + /// directive. + case `Nonmutating` = 1 + /// Idempotent Operations that use the Slice idempotent keyword can modify + /// object state, but invoking an operation twice in a row must + /// result in the same object state as invoking it once. For + /// example, x = 1 is an idempotent statement, + /// whereas x += 1 is not. For idempotent + /// operations, the Ice run-time uses the same retry behavior + /// as for nonmutating operations in case of a potentially + /// recoverable error. + case Idempotent = 2 + public init() { + self = .Normal + } +} + +/// An `Ice.InputStream` extension to read `OperationMode` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `OperationMode` - The enumarated value. + func read() throws -> OperationMode { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 2) + guard let val = OperationMode(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `OperationMode` - The enumerated value. + func read(tag: Swift.Int32) throws -> OperationMode? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as OperationMode + } +} + +/// An `Ice.OutputStream` extension to write `OperationMode` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `OperationMode` - The enumerator to write. + func write(_ v: OperationMode) { + write(enum: v.rawValue, maxValue: 2) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `OperationMode` - The enumerator to write. + func write(tag: Swift.Int32, value: OperationMode?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 2) + } +} + +/// Information about the current method invocation for servers. Each +/// operation on the server has a Current as its implicit final +/// parameter. Current is mostly used for Ice services. Most +/// applications ignore this parameter. +public class Current { + /// The object adapter. + public var adapter: ObjectAdapter? = nil + /// Information about the connection over which the current method + /// invocation was received. If the invocation is direct due to + /// collocation optimization, this value is set to null. + public var con: Connection? = nil + /// The Ice object identity. + public var id: Identity = Identity() + /// The facet. + public var facet: Swift.String = "" + /// The operation name. + public var operation: Swift.String = "" + /// The mode of the operation. + public var mode: OperationMode = .Normal + /// The request context, as received from the client. + public var ctx: Context = Context() + /// The request id unless oneway (0). + public var requestId: Swift.Int32 = 0 + /// The encoding version used to encode the input and output parameters. + public var encoding: EncodingVersion = EncodingVersion() + + public init() {} + + public init(adapter: ObjectAdapter?, con: Connection?, id: Identity, facet: Swift.String, operation: Swift.String, mode: OperationMode, ctx: Context, requestId: Swift.Int32, encoding: EncodingVersion) { + self.adapter = adapter + self.con = con + self.id = id + self.facet = facet + self.operation = operation + self.mode = mode + self.ctx = ctx + self.requestId = requestId + self.encoding = encoding + } +} diff --git a/Sources/Ice/Ice_Endpoint.swift b/Sources/Ice/Ice_Endpoint.swift new file mode 100644 index 0000000..588ea23 --- /dev/null +++ b/Sources/Ice/Ice_Endpoint.swift @@ -0,0 +1,120 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Endpoint.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +/// Uniquely identifies TCP endpoints. +public let TCPEndpointType: Swift.Int16 = 1 + +/// Uniquely identifies SSL endpoints. +public let SSLEndpointType: Swift.Int16 = 2 + +/// Uniquely identifies UDP endpoints. +public let UDPEndpointType: Swift.Int16 = 3 + +/// Uniquely identifies TCP-based WebSocket endpoints. +public let WSEndpointType: Swift.Int16 = 4 + +/// Uniquely identifies SSL-based WebSocket endpoints. +public let WSSEndpointType: Swift.Int16 = 5 + +/// Uniquely identifies Bluetooth endpoints. +public let BTEndpointType: Swift.Int16 = 6 + +/// Uniquely identifies SSL Bluetooth endpoints. +public let BTSEndpointType: Swift.Int16 = 7 + +/// Uniquely identifies iAP-based endpoints. +public let iAPEndpointType: Swift.Int16 = 8 + +/// Uniquely identifies SSL iAP-based endpoints. +public let iAPSEndpointType: Swift.Int16 = 9 + + +/// Base class providing access to the endpoint details. +public protocol EndpointInfo: Swift.AnyObject { + /// The information of the underyling endpoint of null if there's + /// no underlying endpoint. + var underlying: EndpointInfo? { get set } + /// The timeout for the endpoint in milliseconds. 0 means + /// non-blocking, -1 means no timeout. + var timeout: Swift.Int32 { get set } + /// Specifies whether or not compression should be used if + /// available when using this endpoint. + var compress: Swift.Bool { get set } + + /// Returns the type of the endpoint. + /// + /// - returns: `Swift.Int16` - The endpoint type. + func `type`() -> Swift.Int16 + + /// Returns true if this endpoint is a datagram endpoint. + /// + /// - returns: `Swift.Bool` - True for a datagram endpoint. + func datagram() -> Swift.Bool + + /// Returns true if this endpoint is a secure endpoint. + /// + /// - returns: `Swift.Bool` - True for a secure endpoint. + func secure() -> Swift.Bool +} + +/// The user-level interface to an endpoint. +public protocol Endpoint: Swift.AnyObject, Swift.CustomStringConvertible { + /// Return a string representation of the endpoint. + /// + /// - returns: `Swift.String` - The string representation of the endpoint. + func toString() -> Swift.String + + /// Returns the endpoint information. + /// + /// - returns: `EndpointInfo?` - The endpoint information class. + func getInfo() -> EndpointInfo? +} + +/// Provides access to the address details of a IP endpoint. +public protocol IPEndpointInfo: EndpointInfo { + /// The host or address configured with the endpoint. + var host: Swift.String { get set } + /// The port number. + var port: Swift.Int32 { get set } + /// The source IP address. + var sourceAddress: Swift.String { get set } +} + +/// Provides access to a TCP endpoint information. +public protocol TCPEndpointInfo: IPEndpointInfo {} + +/// Provides access to an UDP endpoint information. +public protocol UDPEndpointInfo: IPEndpointInfo { + /// The multicast interface. + var mcastInterface: Swift.String { get set } + /// The multicast time-to-live (or hops). + var mcastTtl: Swift.Int32 { get set } +} + +/// Provides access to a WebSocket endpoint information. +public protocol WSEndpointInfo: EndpointInfo { + /// The URI configured with the endpoint. + var resource: Swift.String { get set } +} + +/// Provides access to the details of an opaque endpoint. +public protocol OpaqueEndpointInfo: EndpointInfo { + /// The encoding version of the opaque endpoint (to decode or + /// encode the rawBytes). + var rawEncoding: EncodingVersion { get set } + /// The raw encoding of the opaque endpoint. + var rawBytes: ByteSeq { get set } +} diff --git a/Sources/Ice/Ice_EndpointF.swift b/Sources/Ice/Ice_EndpointF.swift new file mode 100644 index 0000000..862f8a7 --- /dev/null +++ b/Sources/Ice/Ice_EndpointF.swift @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A sequence of endpoints. +public typealias EndpointSeq = [Endpoint] diff --git a/Sources/Ice/Ice_EndpointTypes.swift b/Sources/Ice/Ice_EndpointTypes.swift new file mode 100644 index 0000000..0d4d7a5 --- /dev/null +++ b/Sources/Ice/Ice_EndpointTypes.swift @@ -0,0 +1,77 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointTypes.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// Determines the order in which the Ice run time uses the endpoints +/// in a proxy when establishing a connection. +public enum EndpointSelectionType: Swift.UInt8 { + /// Random Random causes the endpoints to be arranged in a random order. + case Random = 0 + /// Ordered Ordered forces the Ice run time to use the endpoints in the + /// order they appeared in the proxy. + case Ordered = 1 + public init() { + self = .Random + } +} + +/// An `Ice.InputStream` extension to read `EndpointSelectionType` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `EndpointSelectionType` - The enumarated value. + func read() throws -> EndpointSelectionType { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 1) + guard let val = EndpointSelectionType(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `EndpointSelectionType` - The enumerated value. + func read(tag: Swift.Int32) throws -> EndpointSelectionType? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as EndpointSelectionType + } +} + +/// An `Ice.OutputStream` extension to write `EndpointSelectionType` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `EndpointSelectionType` - The enumerator to write. + func write(_ v: EndpointSelectionType) { + write(enum: v.rawValue, maxValue: 1) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `EndpointSelectionType` - The enumerator to write. + func write(tag: Swift.Int32, value: EndpointSelectionType?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 1) + } +} diff --git a/Sources/Ice/Ice_FacetMap.swift b/Sources/Ice/Ice_FacetMap.swift new file mode 100644 index 0000000..ae8e419 --- /dev/null +++ b/Sources/Ice/Ice_FacetMap.swift @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `FacetMap.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A mapping from facet name to servant. +public typealias FacetMap = [Swift.String: Disp] diff --git a/Sources/Ice/Ice_Identity.swift b/Sources/Ice/Ice_Identity.swift new file mode 100644 index 0000000..d89c0c1 --- /dev/null +++ b/Sources/Ice/Ice_Identity.swift @@ -0,0 +1,155 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Identity.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// The identity of an Ice object. In a proxy, an empty Identity.name denotes a nil +/// proxy. An identity with an empty Identity.name and a non-empty Identity.category +/// is illegal. You cannot add a servant with an empty name to the Active Servant Map. +public struct Identity: Swift.Hashable { + /// The name of the Ice object. + public var name: Swift.String = "" + /// The Ice object category. + public var category: Swift.String = "" + + public init() {} + + public init(name: Swift.String, category: Swift.String) { + self.name = name + self.category = category + } +} + +/// An `Ice.InputStream` extension to read `Identity` structured values from the stream. +public extension InputStream { + /// Read a `Identity` structured value from the stream. + /// + /// - returns: `Identity` - The structured value read from the stream. + func read() throws -> Identity { + var v = Identity() + v.name = try self.read() + v.category = try self.read() + return v + } + + /// Read an optional `Identity?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `Identity?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> Identity? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as Identity + } +} + +/// An `Ice.OutputStream` extension to write `Identity` structured values from the stream. +public extension OutputStream { + /// Write a `Identity` structured value to the stream. + /// + /// - parameter _: `Identity` - The value to write to the stream. + func write(_ v: Identity) { + self.write(v.name) + self.write(v.category) + } + + /// Write an optional `Identity?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `Identity?` - The value to write to the stream. + func write(tag: Swift.Int32, value: Identity?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A mapping between identities and Ice objects. +public typealias ObjectDict = [Identity: Disp?] + +/// A sequence of identities. +public typealias IdentitySeq = [Identity] + +/// Helper class to read and write `IdentitySeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct IdentitySeqHelper { + /// Read a `IdentitySeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `IdentitySeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> IdentitySeq { + let sz = try istr.readAndCheckSeqSize(minSize: 2) + var v = IdentitySeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: Identity = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `IdentitySeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `IdentitySeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> IdentitySeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `IdentitySeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `IdentitySeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: IdentitySeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `IdentitySeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `IdentitySeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: IdentitySeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} diff --git a/Sources/Ice/Ice_ImplicitContext.swift b/Sources/Ice/Ice_ImplicitContext.swift new file mode 100644 index 0000000..b29c2ad --- /dev/null +++ b/Sources/Ice/Ice_ImplicitContext.swift @@ -0,0 +1,82 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContext.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// An interface to associate implict contexts with communicators. +/// +/// When you make a remote invocation without an explicit context parameter, +/// Ice uses the per-proxy context (if any) combined with the ImplicitContext +/// associated with the communicator. +/// +/// Ice provides several implementations of ImplicitContext. The implementation +/// used depends on the value of the Ice.ImplicitContext property. +/// +/// None (default) +/// No implicit context at all. +/// PerThread +/// The implementation maintains a context per thread. +/// Shared +/// The implementation maintains a single context shared by all threads. +/// +/// +/// ImplicitContext also provides a number of operations to create, update or retrieve +/// an entry in the underlying context without first retrieving a copy of the entire +/// context. These operations correspond to a subset of the java.util.Map methods, +/// with java.lang.Object replaced by string and null replaced by the empty-string. +public protocol ImplicitContext: Swift.AnyObject { + /// Get a copy of the underlying context. + /// + /// - returns: `Context` - A copy of the underlying context. + func getContext() -> Context + + /// Set the underlying context. + /// + /// - parameter _: `Context` The new context. + func setContext(_ newContext: Context) + + /// Check if this key has an associated value in the underlying context. + /// + /// - parameter _: `Swift.String` The key. + /// + /// - returns: `Swift.Bool` - True if the key has an associated value, False otherwise. + func containsKey(_ key: Swift.String) -> Swift.Bool + + /// Get the value associated with the given key in the underlying context. + /// Returns an empty string if no value is associated with the key. + /// containsKey allows you to distinguish between an empty-string value and + /// no value at all. + /// + /// - parameter _: `Swift.String` The key. + /// + /// - returns: `Swift.String` - The value associated with the key. + func `get`(_ key: Swift.String) -> Swift.String + + /// Create or update a key/value entry in the underlying context. + /// + /// - parameter key: `Swift.String` The key. + /// + /// - parameter value: `Swift.String` The value. + /// + /// - returns: `Swift.String` - The previous value associated with the key, if any. + func put(key: Swift.String, value: Swift.String) -> Swift.String + + /// Remove the entry for the given key in the underlying context. + /// + /// - parameter _: `Swift.String` The key. + /// + /// - returns: `Swift.String` - The value associated with the key, if any. + func remove(_ key: Swift.String) -> Swift.String +} diff --git a/Sources/Ice/Ice_ImplicitContextF.swift b/Sources/Ice/Ice_ImplicitContextF.swift new file mode 100644 index 0000000..ec06057 --- /dev/null +++ b/Sources/Ice/Ice_ImplicitContextF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContextF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Instrumentation.swift b/Sources/Ice/Ice_Instrumentation.swift new file mode 100644 index 0000000..85171d8 --- /dev/null +++ b/Sources/Ice/Ice_Instrumentation.swift @@ -0,0 +1,389 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Instrumentation.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// The thread state enumeration keeps track of the different possible +/// states of Ice threads. +public enum InstrumentationThreadState: Swift.UInt8 { + /// ThreadStateIdle The thread is idle. + case ThreadStateIdle = 0 + /// ThreadStateInUseForIO The thread is in use performing reads or writes for Ice + /// connections. This state is only for threads from an Ice thread + /// pool. + case ThreadStateInUseForIO = 1 + /// ThreadStateInUseForUser The thread is calling user code (servant implementation, AMI + /// callbacks). This state is only for threads from an Ice thread + /// pool. + case ThreadStateInUseForUser = 2 + /// ThreadStateInUseForOther The thread is performing other internal activities (DNS + /// lookups, timer callbacks, etc). + case ThreadStateInUseForOther = 3 + public init() { + self = .ThreadStateIdle + } +} + +/// An `Ice.InputStream` extension to read `InstrumentationThreadState` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `InstrumentationThreadState` - The enumarated value. + func read() throws -> InstrumentationThreadState { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 3) + guard let val = InstrumentationThreadState(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `InstrumentationThreadState` - The enumerated value. + func read(tag: Swift.Int32) throws -> InstrumentationThreadState? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as InstrumentationThreadState + } +} + +/// An `Ice.OutputStream` extension to write `InstrumentationThreadState` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `InstrumentationThreadState` - The enumerator to write. + func write(_ v: InstrumentationThreadState) { + write(enum: v.rawValue, maxValue: 3) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `InstrumentationThreadState` - The enumerator to write. + func write(tag: Swift.Int32, value: InstrumentationThreadState?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 3) + } +} + +/// The state of an Ice connection. +public enum InstrumentationConnectionState: Swift.UInt8 { + /// ConnectionStateValidating The connection is being validated. + case ConnectionStateValidating = 0 + /// ConnectionStateHolding The connection is holding the reception of new messages. + case ConnectionStateHolding = 1 + /// ConnectionStateActive The connection is active and can send and receive messages. + case ConnectionStateActive = 2 + /// ConnectionStateClosing The connection is being gracefully shutdown and waits for the + /// peer to close its end of the connection. + case ConnectionStateClosing = 3 + /// ConnectionStateClosed The connection is closed and waits for potential dispatch to be + /// finished before being destroyed and detached from the observer. + case ConnectionStateClosed = 4 + public init() { + self = .ConnectionStateValidating + } +} + +/// An `Ice.InputStream` extension to read `InstrumentationConnectionState` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `InstrumentationConnectionState` - The enumarated value. + func read() throws -> InstrumentationConnectionState { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 4) + guard let val = InstrumentationConnectionState(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `InstrumentationConnectionState` - The enumerated value. + func read(tag: Swift.Int32) throws -> InstrumentationConnectionState? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as InstrumentationConnectionState + } +} + +/// An `Ice.OutputStream` extension to write `InstrumentationConnectionState` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `InstrumentationConnectionState` - The enumerator to write. + func write(_ v: InstrumentationConnectionState) { + write(enum: v.rawValue, maxValue: 4) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `InstrumentationConnectionState` - The enumerator to write. + func write(tag: Swift.Int32, value: InstrumentationConnectionState?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 4) + } +} + +/// The object observer interface used by instrumented objects to +/// notify the observer of their existence. +public protocol InstrumentationObserver: Swift.AnyObject { + /// This method is called when the instrumented object is created + /// or when the observer is attached to an existing object. + func attach() throws + + /// This method is called when the instrumented object is destroyed + /// and as a result the observer detached from the object. + func detach() throws + + /// Notification of a failure. + /// + /// - parameter _: `Swift.String` The name of the exception. + func failed(_ exceptionName: Swift.String) throws +} + +/// The thread observer interface to instrument Ice threads. This can +/// be threads from the Ice thread pool or utility threads used by the +/// Ice core. +public protocol InstrumentationThreadObserver: InstrumentationObserver { + /// Notification of thread state change. + /// + /// - parameter oldState: `InstrumentationThreadState` The previous thread state. + /// + /// - parameter newState: `InstrumentationThreadState` The new thread state. + func stateChanged(oldState: InstrumentationThreadState, newState: InstrumentationThreadState) throws +} + +/// The connection observer interface to instrument Ice connections. +public protocol InstrumentationConnectionObserver: InstrumentationObserver { + /// Notification of sent bytes over the connection. + /// + /// - parameter _: `Swift.Int32` The number of bytes sent. + func sentBytes(_ num: Swift.Int32) throws + + /// Notification of received bytes over the connection. + /// + /// - parameter _: `Swift.Int32` The number of bytes received. + func receivedBytes(_ num: Swift.Int32) throws +} + +/// The dispatch observer to instrument servant dispatch. +public protocol InstrumentationDispatchObserver: InstrumentationObserver { + /// Notification of a user exception. + func userException() throws + + /// Reply notification. + /// + /// - parameter _: `Swift.Int32` The size of the reply. + func reply(_ size: Swift.Int32) throws +} + +/// The child invocation observer to instrument remote or collocated +/// invocations. +public protocol InstrumentationChildInvocationObserver: InstrumentationObserver { + /// Reply notification. + /// + /// - parameter _: `Swift.Int32` The size of the reply. + func reply(_ size: Swift.Int32) throws +} + +/// The remote observer to instrument invocations that are sent over +/// the wire. +public protocol InstrumentationRemoteObserver: InstrumentationChildInvocationObserver {} + +/// The collocated observer to instrument invocations that are +/// collocated. +public protocol InstrumentationCollocatedObserver: InstrumentationChildInvocationObserver {} + +/// The invocation observer to instrument invocations on proxies. A +/// proxy invocation can either result in a collocated or remote +/// invocation. If it results in a remote invocation, a sub-observer is +/// requested for the remote invocation. +public protocol InstrumentationInvocationObserver: InstrumentationObserver { + /// Notification of the invocation being retried. + func retried() throws + + /// Notification of a user exception. + func userException() throws + + /// Get a remote observer for this invocation. + /// + /// - parameter con: `ConnectionInfo?` The connection information. + /// + /// - parameter endpt: `Endpoint?` The connection endpoint. + /// + /// - parameter requestId: `Swift.Int32` The ID of the invocation. + /// + /// - parameter size: `Swift.Int32` The size of the invocation. + /// + /// - returns: `InstrumentationRemoteObserver?` - The observer to instrument the remote invocation. + func getRemoteObserver(con: ConnectionInfo?, endpt: Endpoint?, requestId: Swift.Int32, size: Swift.Int32) throws -> InstrumentationRemoteObserver? + + /// Get a collocated observer for this invocation. + /// + /// - parameter adapter: `ObjectAdapter?` The object adapter hosting the collocated Ice object. + /// + /// - parameter requestId: `Swift.Int32` The ID of the invocation. + /// + /// - parameter size: `Swift.Int32` The size of the invocation. + /// + /// - returns: `InstrumentationCollocatedObserver?` - The observer to instrument the collocated invocation. + func getCollocatedObserver(adapter: ObjectAdapter?, requestId: Swift.Int32, size: Swift.Int32) throws -> InstrumentationCollocatedObserver? +} + +/// The observer updater interface. This interface is implemented by +/// the Ice run-time and an instance of this interface is provided by +/// the Ice communicator on initialization to the +/// CommunicatorObserver object set with the communicator +/// initialization data. The Ice communicator calls +/// CommunicatorObserver.setObserverUpdater to provide the observer +/// updater. +/// +/// This interface can be used by add-ins implementing the +/// CommunicatorObserver interface to update the observers of +/// connections and threads. +public protocol InstrumentationObserverUpdater: Swift.AnyObject { + /// Update connection observers associated with each of the Ice + /// connection from the communicator and its object adapters. + /// + /// When called, this method goes through all the connections and + /// for each connection CommunicatorObserver.getConnectionObserver + /// is called. The implementation of getConnectionObserver has the + /// possibility to return an updated observer if necessary. + func updateConnectionObservers() throws + + /// Update thread observers associated with each of the Ice thread + /// from the communicator and its object adapters. + /// + /// When called, this method goes through all the threads and for + /// each thread CommunicatorObserver.getThreadObserver is + /// called. The implementation of getThreadObserver has the + /// possibility to return an updated observer if necessary. + func updateThreadObservers() throws +} + +/// The communicator observer interface used by the Ice run-time to +/// obtain and update observers for its observable objects. This +/// interface should be implemented by add-ins that wish to observe Ice +/// objects in order to collect statistics. An instance of this +/// interface can be provided to the Ice run-time through the Ice +/// communicator initialization data. +public protocol InstrumentationCommunicatorObserver: Swift.AnyObject { + /// This method should return an observer for the given endpoint + /// information and connector. The Ice run-time calls this method + /// for each connection establishment attempt. + /// + /// - parameter endpt: `Endpoint?` The endpoint. + /// + /// - parameter connector: `Swift.String` The description of the connector. For IP + /// transports, this is typically the IP address to connect to. + /// + /// - returns: `InstrumentationObserver?` - The observer to instrument the connection establishment. + func getConnectionEstablishmentObserver(endpt: Endpoint?, connector: Swift.String) throws -> InstrumentationObserver? + + /// This method should return an observer for the given endpoint + /// information. The Ice run-time calls this method to resolve an + /// endpoint and obtain the list of connectors. + /// + /// For IP endpoints, this typically involves doing a DNS lookup to + /// obtain the IP addresses associated with the DNS name. + /// + /// - parameter _: `Endpoint?` The endpoint. + /// + /// - returns: `InstrumentationObserver?` - The observer to instrument the endpoint lookup. + func getEndpointLookupObserver(_ endpt: Endpoint?) throws -> InstrumentationObserver? + + /// This method should return a connection observer for the given + /// connection. The Ice run-time calls this method for each new + /// connection and for all the Ice communicator connections when + /// ObserverUpdater.updateConnectionObservers is called. + /// + /// - parameter c: `ConnectionInfo?` The connection information. + /// + /// - parameter e: `Endpoint?` The connection endpoint. + /// + /// - parameter s: `InstrumentationConnectionState` The state of the connection. + /// + /// - parameter o: `InstrumentationConnectionObserver?` The old connection observer if one is already set or a + /// null reference otherwise. + /// + /// - returns: `InstrumentationConnectionObserver?` - The connection observer to instrument the connection. + func getConnectionObserver(c: ConnectionInfo?, e: Endpoint?, s: InstrumentationConnectionState, o: InstrumentationConnectionObserver?) throws -> InstrumentationConnectionObserver? + + /// This method should return a thread observer for the given + /// thread. The Ice run-time calls this method for each new thread + /// and for all the Ice communicator threads when + /// ObserverUpdater.updateThreadObservers is called. + /// + /// - parameter parent: `Swift.String` The parent of the thread. + /// + /// - parameter id: `Swift.String` The ID of the thread to observe. + /// + /// - parameter s: `InstrumentationThreadState` The state of the thread. + /// + /// - parameter o: `InstrumentationThreadObserver?` The old thread observer if one is already set or a + /// null reference otherwise. + /// + /// - returns: `InstrumentationThreadObserver?` - The thread observer to instrument the thread. + func getThreadObserver(parent: Swift.String, id: Swift.String, s: InstrumentationThreadState, o: InstrumentationThreadObserver?) throws -> InstrumentationThreadObserver? + + /// This method should return an invocation observer for the given + /// invocation. The Ice run-time calls this method for each new + /// invocation on a proxy. + /// + /// - parameter prx: `ObjectPrx?` The proxy used for the invocation. + /// + /// - parameter operation: `Swift.String` The name of the invocation. + /// + /// - parameter ctx: `Context` The context specified by the user. + /// + /// - returns: `InstrumentationInvocationObserver?` - The invocation observer to instrument the invocation. + func getInvocationObserver(prx: ObjectPrx?, operation: Swift.String, ctx: Context) throws -> InstrumentationInvocationObserver? + + /// This method should return a dispatch observer for the given + /// dispatch. The Ice run-time calls this method each time it + /// receives an incoming invocation to be dispatched for an Ice + /// object. + /// + /// - parameter c: `Current` The current object as provided to the Ice servant + /// dispatching the invocation. + /// + /// - parameter size: `Swift.Int32` The size of the dispatch. + /// + /// - returns: `InstrumentationDispatchObserver?` - The dispatch observer to instrument the dispatch. + func getDispatchObserver(c: Current, size: Swift.Int32) throws -> InstrumentationDispatchObserver? + + /// The Ice run-time calls this method when the communicator is + /// initialized. The add-in implementing this interface can use + /// this object to get the Ice run-time to re-obtain observers for + /// observed objects. + /// + /// - parameter _: `InstrumentationObserverUpdater?` The observer updater object. + func setObserverUpdater(_ updater: InstrumentationObserverUpdater?) throws +} diff --git a/Sources/Ice/Ice_InstrumentationF.swift b/Sources/Ice/Ice_InstrumentationF.swift new file mode 100644 index 0000000..e39bd1c --- /dev/null +++ b/Sources/Ice/Ice_InstrumentationF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `InstrumentationF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_LocalException.swift b/Sources/Ice/Ice_LocalException.swift new file mode 100644 index 0000000..facafee --- /dev/null +++ b/Sources/Ice/Ice_LocalException.swift @@ -0,0 +1,1644 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocalException.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// This exception is raised when a failure occurs during initialization. +open class InitializationException: LocalException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.reason = reason + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::InitializationException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _InitializationExceptionDescription + } +} + +/// This exception indicates that a failure occurred while initializing +/// a plug-in. +open class PluginInitializationException: LocalException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.reason = reason + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::PluginInitializationException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _PluginInitializationExceptionDescription + } +} + +/// This exception is raised if a feature is requested that is not +/// supported with collocation optimization. +/// +/// ## Deprecated +/// This exception is no longer used by the Ice run time +open class CollocationOptimizationException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CollocationOptimizationException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CollocationOptimizationExceptionDescription + } +} + +/// An attempt was made to register something more than once with +/// the Ice run time. +/// +/// This exception is raised if an attempt is made to register a +/// servant, servant locator, facet, value factory, plug-in, object +/// adapter, object, or user exception factory more than once for the +/// same ID. +open class AlreadyRegisteredException: LocalException { + /// The kind of object that could not be removed: "servant", "facet", + /// "object", "default servant", "servant locator", "value factory", "plugin", + /// "object adapter", "object adapter with router", "replica group". + public var kindOfObject: Swift.String = "" + /// The ID (or name) of the object that is registered already. + public var id: Swift.String = "" + + public required init() { + super.init() + } + + public init(kindOfObject: Swift.String, id: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.kindOfObject = kindOfObject + self.id = id + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::AlreadyRegisteredException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _AlreadyRegisteredExceptionDescription + } +} + +/// An attempt was made to find or deregister something that is not +/// registered with the Ice run time or Ice locator. +/// +/// This exception is raised if an attempt is made to remove a servant, +/// servant locator, facet, value factory, plug-in, object adapter, +/// object, or user exception factory that is not currently registered. +/// +/// It's also raised if the Ice locator can't find an object or object +/// adapter when resolving an indirect proxy or when an object adapter +/// is activated. +open class NotRegisteredException: LocalException { + /// The kind of object that could not be removed: "servant", "facet", + /// "object", "default servant", "servant locator", "value factory", "plugin", + /// "object adapter", "object adapter with router", "replica group". + public var kindOfObject: Swift.String = "" + /// The ID (or name) of the object that could not be removed. + public var id: Swift.String = "" + + public required init() { + super.init() + } + + public init(kindOfObject: Swift.String, id: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.kindOfObject = kindOfObject + self.id = id + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::NotRegisteredException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _NotRegisteredExceptionDescription + } +} + +/// The operation can only be invoked with a twoway request. +/// +/// This exception is raised if an attempt is made to invoke an +/// operation with ice_oneway, ice_batchOneway, ice_datagram, +/// or ice_batchDatagram and the operation has a return value, +/// out-parameters, or an exception specification. +open class TwowayOnlyException: LocalException { + /// The name of the operation that was invoked. + public var operation: Swift.String = "" + + public required init() { + super.init() + } + + public init(operation: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.operation = operation + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::TwowayOnlyException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _TwowayOnlyExceptionDescription + } +} + +/// An attempt was made to clone a class that does not support +/// cloning. +/// +/// This exception is raised if ice_clone is called on +/// a class that is derived from an abstract Slice class (that is, +/// a class containing operations), and the derived class does not +/// provide an implementation of the ice_clone operation (C++ only). +open class CloneNotImplementedException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CloneNotImplementedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CloneNotImplementedExceptionDescription + } +} + +/// This exception is raised if an operation call on a server raises an +/// unknown exception. For example, for C++, this exception is raised +/// if the server throws a C++ exception that is not directly or +/// indirectly derived from Ice::LocalException or +/// Ice::UserException. +open class UnknownException: LocalException { + /// This field is set to the textual representation of the unknown + /// exception if available. + public var unknown: Swift.String = "" + + public required init() { + super.init() + } + + public init(unknown: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.unknown = unknown + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownExceptionDescription + } +} + +/// This exception is raised if an operation call on a server raises a +/// local exception. Because local exceptions are not transmitted by +/// the Ice protocol, the client receives all local exceptions raised +/// by the server as UnknownLocalException. The only exception to this +/// rule are all exceptions derived from RequestFailedException, +/// which are transmitted by the Ice protocol even though they are +/// declared local. +open class UnknownLocalException: UnknownException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownLocalException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownLocalExceptionDescription + } +} + +/// An operation raised an incorrect user exception. +/// +/// This exception is raised if an operation raises a +/// user exception that is not declared in the exception's +/// throws clause. Such undeclared exceptions are +/// not transmitted from the server to the client by the Ice +/// protocol, but instead the client just gets an +/// UnknownUserException. This is necessary in order to not violate +/// the contract established by an operation's signature: Only local +/// exceptions and user exceptions declared in the +/// throws clause can be raised. +open class UnknownUserException: UnknownException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownUserException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownUserExceptionDescription + } +} + +/// This exception is raised if the Ice library version does not match +/// the version in the Ice header files. +open class VersionMismatchException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::VersionMismatchException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _VersionMismatchExceptionDescription + } +} + +/// This exception is raised if the Communicator has been destroyed. +open class CommunicatorDestroyedException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CommunicatorDestroyedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CommunicatorDestroyedExceptionDescription + } +} + +/// This exception is raised if an attempt is made to use a deactivated +/// ObjectAdapter. +open class ObjectAdapterDeactivatedException: LocalException { + /// Name of the adapter. + public var name: Swift.String = "" + + public required init() { + super.init() + } + + public init(name: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.name = name + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ObjectAdapterDeactivatedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ObjectAdapterDeactivatedExceptionDescription + } +} + +/// This exception is raised if an ObjectAdapter cannot be activated. +/// +/// This happens if the Locator detects another active ObjectAdapter with +/// the same adapter id. +open class ObjectAdapterIdInUseException: LocalException { + /// Adapter ID. + public var id: Swift.String = "" + + public required init() { + super.init() + } + + public init(id: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.id = id + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ObjectAdapterIdInUseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ObjectAdapterIdInUseExceptionDescription + } +} + +/// This exception is raised if no suitable endpoint is available. +open class NoEndpointException: LocalException { + /// The stringified proxy for which no suitable endpoint is + /// available. + public var proxy: Swift.String = "" + + public required init() { + super.init() + } + + public init(proxy: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.proxy = proxy + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::NoEndpointException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _NoEndpointExceptionDescription + } +} + +/// This exception is raised if there was an error while parsing an +/// endpoint. +open class EndpointParseException: LocalException { + /// Describes the failure and includes the string that could not be parsed. + public var str: Swift.String = "" + + public required init() { + super.init() + } + + public init(str: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.str = str + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::EndpointParseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _EndpointParseExceptionDescription + } +} + +/// This exception is raised if there was an error while parsing an +/// endpoint selection type. +open class EndpointSelectionTypeParseException: LocalException { + /// Describes the failure and includes the string that could not be parsed. + public var str: Swift.String = "" + + public required init() { + super.init() + } + + public init(str: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.str = str + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::EndpointSelectionTypeParseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _EndpointSelectionTypeParseExceptionDescription + } +} + +/// This exception is raised if there was an error while parsing a +/// version. +open class VersionParseException: LocalException { + /// Describes the failure and includes the string that could not be parsed. + public var str: Swift.String = "" + + public required init() { + super.init() + } + + public init(str: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.str = str + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::VersionParseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _VersionParseExceptionDescription + } +} + +/// This exception is raised if there was an error while parsing a +/// stringified identity. +open class IdentityParseException: LocalException { + /// Describes the failure and includes the string that could not be parsed. + public var str: Swift.String = "" + + public required init() { + super.init() + } + + public init(str: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.str = str + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::IdentityParseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _IdentityParseExceptionDescription + } +} + +/// This exception is raised if there was an error while parsing a +/// stringified proxy. +open class ProxyParseException: LocalException { + /// Describes the failure and includes the string that could not be parsed. + public var str: Swift.String = "" + + public required init() { + super.init() + } + + public init(str: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.str = str + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ProxyParseException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ProxyParseExceptionDescription + } +} + +/// This exception is raised if an illegal identity is encountered. +open class IllegalIdentityException: LocalException { + /// The illegal identity. + public var id: Identity = Identity() + + public required init() { + super.init() + } + + public init(id: Identity, file: Swift.String = #file, line: Swift.Int = #line) { + self.id = id + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::IllegalIdentityException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _IllegalIdentityExceptionDescription + } +} + +/// This exception is raised to reject an illegal servant (typically +/// a null servant) +open class IllegalServantException: LocalException { + /// Describes why this servant is illegal. + public var reason: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.reason = reason + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::IllegalServantException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _IllegalServantExceptionDescription + } +} + +/// This exception is raised if a request failed. This exception, and +/// all exceptions derived from RequestFailedException, are +/// transmitted by the Ice protocol, even though they are declared +/// local. +open class RequestFailedException: LocalException { + /// The identity of the Ice Object to which the request was sent. + public var id: Identity = Identity() + /// The facet to which the request was sent. + public var facet: Swift.String = "" + /// The operation name of the request. + public var operation: Swift.String = "" + + public required init() { + super.init() + } + + public init(id: Identity, facet: Swift.String, operation: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.id = id + self.facet = facet + self.operation = operation + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::RequestFailedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _RequestFailedExceptionDescription + } +} + +/// This exception is raised if an object does not exist on the server, +/// that is, if no facets with the given identity exist. +open class ObjectNotExistException: RequestFailedException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ObjectNotExistException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ObjectNotExistExceptionDescription + } +} + +/// This exception is raised if no facet with the given name exists, +/// but at least one facet with the given identity exists. +open class FacetNotExistException: RequestFailedException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::FacetNotExistException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _FacetNotExistExceptionDescription + } +} + +/// This exception is raised if an operation for a given object does +/// not exist on the server. Typically this is caused by either the +/// client or the server using an outdated Slice specification. +open class OperationNotExistException: RequestFailedException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::OperationNotExistException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _OperationNotExistExceptionDescription + } +} + +/// This exception is raised if a system error occurred in the server +/// or client process. There are many possible causes for such a system +/// exception. For details on the cause, SyscallException.error +/// should be inspected. +open class SyscallException: LocalException { + /// The error number describing the system exception. For C++ and + /// Unix, this is equivalent to errno. For C++ + /// and Windows, this is the value returned by + /// GetLastError() or + /// WSAGetLastError(). + public var error: Swift.Int32 = 0 + + public required init() { + super.init() + } + + public init(error: Swift.Int32, file: Swift.String = #file, line: Swift.Int = #line) { + self.error = error + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::SyscallException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _SyscallExceptionDescription + } +} + +/// This exception indicates socket errors. +open class SocketException: SyscallException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::SocketException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _SocketExceptionDescription + } +} + +/// This exception indicates CFNetwork errors. +open class CFNetworkException: SocketException { + /// The domain of the error. + public var domain: Swift.String = "" + + public required init() { + super.init() + } + + public init(error: Swift.Int32, domain: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.domain = domain + super.init(error: error, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CFNetworkException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CFNetworkExceptionDescription + } +} + +/// This exception indicates file errors. +open class FileException: SyscallException { + /// The path of the file responsible for the error. + public var path: Swift.String = "" + + public required init() { + super.init() + } + + public init(error: Swift.Int32, path: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.path = path + super.init(error: error, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::FileException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _FileExceptionDescription + } +} + +/// This exception indicates connection failures. +open class ConnectFailedException: SocketException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectFailedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectFailedExceptionDescription + } +} + +/// This exception indicates a connection failure for which +/// the server host actively refuses a connection. +open class ConnectionRefusedException: ConnectFailedException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectionRefusedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectionRefusedExceptionDescription + } +} + +/// This exception indicates a lost connection. +open class ConnectionLostException: SocketException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectionLostException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectionLostExceptionDescription + } +} + +/// This exception indicates a DNS problem. For details on the cause, +/// DNSException.error should be inspected. +open class DNSException: LocalException { + /// The error number describing the DNS problem. For C++ and Unix, + /// this is equivalent to h_errno. For C++ and + /// Windows, this is the value returned by + /// WSAGetLastError(). + public var error: Swift.Int32 = 0 + /// The host name that could not be resolved. + public var host: Swift.String = "" + + public required init() { + super.init() + } + + public init(error: Swift.Int32, host: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.error = error + self.host = host + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::DNSException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _DNSExceptionDescription + } +} + +/// This exception indicates a request was interrupted. +open class OperationInterruptedException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::OperationInterruptedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _OperationInterruptedExceptionDescription + } +} + +/// This exception indicates a timeout condition. +open class TimeoutException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::TimeoutException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _TimeoutExceptionDescription + } +} + +/// This exception indicates a connection establishment timeout condition. +open class ConnectTimeoutException: TimeoutException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectTimeoutException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectTimeoutExceptionDescription + } +} + +/// This exception indicates a connection closure timeout condition. +open class CloseTimeoutException: TimeoutException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CloseTimeoutException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CloseTimeoutExceptionDescription + } +} + +/// This exception indicates that a connection has been shut down because it has been +/// idle for some time. +open class ConnectionTimeoutException: TimeoutException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectionTimeoutException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectionTimeoutExceptionDescription + } +} + +/// This exception indicates that an invocation failed because it timed +/// out. +open class InvocationTimeoutException: TimeoutException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::InvocationTimeoutException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _InvocationTimeoutExceptionDescription + } +} + +/// This exception indicates that an asynchronous invocation failed +/// because it was canceled explicitly by the user. +open class InvocationCanceledException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::InvocationCanceledException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _InvocationCanceledExceptionDescription + } +} + +/// A generic exception base for all kinds of protocol error +/// conditions. +open class ProtocolException: LocalException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.reason = reason + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ProtocolException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ProtocolExceptionDescription + } +} + +/// This exception indicates that a message did not start with the expected +/// magic number ('I', 'c', 'e', 'P'). +open class BadMagicException: ProtocolException { + /// A sequence containing the first four bytes of the incorrect message. + public var badMagic: ByteSeq = ByteSeq() + + public required init() { + super.init() + } + + public init(reason: Swift.String, badMagic: ByteSeq, file: Swift.String = #file, line: Swift.Int = #line) { + self.badMagic = badMagic + super.init(reason: reason, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::BadMagicException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _BadMagicExceptionDescription + } +} + +/// This exception indicates an unsupported protocol version. +open class UnsupportedProtocolException: ProtocolException { + /// The version of the unsupported protocol. + public var bad: ProtocolVersion = ProtocolVersion() + /// The version of the protocol that is supported. + public var supported: ProtocolVersion = ProtocolVersion() + + public required init() { + super.init() + } + + public init(reason: Swift.String, bad: ProtocolVersion, supported: ProtocolVersion, file: Swift.String = #file, line: Swift.Int = #line) { + self.bad = bad + self.supported = supported + super.init(reason: reason, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnsupportedProtocolException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnsupportedProtocolExceptionDescription + } +} + +/// This exception indicates an unsupported data encoding version. +open class UnsupportedEncodingException: ProtocolException { + /// The version of the unsupported encoding. + public var bad: EncodingVersion = EncodingVersion() + /// The version of the encoding that is supported. + public var supported: EncodingVersion = EncodingVersion() + + public required init() { + super.init() + } + + public init(reason: Swift.String, bad: EncodingVersion, supported: EncodingVersion, file: Swift.String = #file, line: Swift.Int = #line) { + self.bad = bad + self.supported = supported + super.init(reason: reason, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnsupportedEncodingException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnsupportedEncodingExceptionDescription + } +} + +/// This exception indicates that an unknown protocol message has been received. +open class UnknownMessageException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownMessageException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownMessageExceptionDescription + } +} + +/// This exception is raised if a message is received over a connection +/// that is not yet validated. +open class ConnectionNotValidatedException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectionNotValidatedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectionNotValidatedExceptionDescription + } +} + +/// This exception indicates that a response for an unknown request ID has been +/// received. +open class UnknownRequestIdException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownRequestIdException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownRequestIdExceptionDescription + } +} + +/// This exception indicates that an unknown reply status has been received. +open class UnknownReplyStatusException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnknownReplyStatusException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnknownReplyStatusExceptionDescription + } +} + +/// This exception indicates that the connection has been gracefully shut down by the +/// server. The operation call that caused this exception has not been +/// executed by the server. In most cases you will not get this +/// exception, because the client will automatically retry the +/// operation call in case the server shut down the connection. However, +/// if upon retry the server shuts down the connection again, and the +/// retry limit has been reached, then this exception is propagated to +/// the application code. +open class CloseConnectionException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CloseConnectionException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CloseConnectionExceptionDescription + } +} + +/// This exception is raised by an operation call if the application +/// closes the connection locally using Connection.close. +open class ConnectionManuallyClosedException: LocalException { + /// True if the connection was closed gracefully, false otherwise. + public var graceful: Swift.Bool = false + + public required init() { + super.init() + } + + public init(graceful: Swift.Bool, file: Swift.String = #file, line: Swift.Int = #line) { + self.graceful = graceful + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ConnectionManuallyClosedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ConnectionManuallyClosedExceptionDescription + } +} + +/// This exception indicates that a message size is less +/// than the minimum required size. +open class IllegalMessageSizeException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::IllegalMessageSizeException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _IllegalMessageSizeExceptionDescription + } +} + +/// This exception indicates a problem with compressing or uncompressing data. +open class CompressionException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::CompressionException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _CompressionExceptionDescription + } +} + +/// A datagram exceeds the configured size. +/// +/// This exception is raised if a datagram exceeds the configured send or receive buffer +/// size, or exceeds the maximum payload size of a UDP packet (65507 bytes). +open class DatagramLimitException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::DatagramLimitException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _DatagramLimitExceptionDescription + } +} + +/// This exception is raised for errors during marshaling or unmarshaling data. +open class MarshalException: ProtocolException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::MarshalException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _MarshalExceptionDescription + } +} + +/// This exception is raised if inconsistent data is received while unmarshaling a proxy. +open class ProxyUnmarshalException: MarshalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ProxyUnmarshalException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ProxyUnmarshalExceptionDescription + } +} + +/// This exception is raised if an out-of-bounds condition occurs during unmarshaling. +open class UnmarshalOutOfBoundsException: MarshalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnmarshalOutOfBoundsException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnmarshalOutOfBoundsExceptionDescription + } +} + +/// This exception is raised if no suitable value factory was found during +/// unmarshaling of a Slice class instance. +open class NoValueFactoryException: MarshalException { + /// The Slice type ID of the class instance for which no + /// no factory could be found. + public var `type`: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, `type`: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.`type` = `type` + super.init(reason: reason, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::NoValueFactoryException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _NoValueFactoryExceptionDescription + } +} + +/// This exception is raised if the type of an unmarshaled Slice class instance does +/// not match its expected type. +/// This can happen if client and server are compiled with mismatched Slice +/// definitions or if a class of the wrong type is passed as a parameter +/// or return value using dynamic invocation. This exception can also be +/// raised if IceStorm is used to send Slice class instances and +/// an operation is subscribed to the wrong topic. +open class UnexpectedObjectException: MarshalException { + /// The Slice type ID of the class instance that was unmarshaled. + public var `type`: Swift.String = "" + /// The Slice type ID that was expected by the receiving operation. + public var expectedType: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, `type`: Swift.String, expectedType: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.`type` = `type` + self.expectedType = expectedType + super.init(reason: reason, file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::UnexpectedObjectException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _UnexpectedObjectExceptionDescription + } +} + +/// This exception is raised when Ice receives a request or reply +/// message whose size exceeds the limit specified by the +/// Ice.MessageSizeMax property. +open class MemoryLimitException: MarshalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::MemoryLimitException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _MemoryLimitExceptionDescription + } +} + +/// This exception is raised when a string conversion to or from UTF-8 +/// fails during marshaling or unmarshaling. +open class StringConversionException: MarshalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::StringConversionException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _StringConversionExceptionDescription + } +} + +/// This exception indicates a malformed data encapsulation. +open class EncapsulationException: MarshalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::EncapsulationException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _EncapsulationExceptionDescription + } +} + +/// This exception is raised if an unsupported feature is used. The +/// unsupported feature string contains the name of the unsupported +/// feature +open class FeatureNotSupportedException: LocalException { + /// The name of the unsupported feature. + public var unsupportedFeature: Swift.String = "" + + public required init() { + super.init() + } + + public init(unsupportedFeature: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.unsupportedFeature = unsupportedFeature + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::FeatureNotSupportedException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _FeatureNotSupportedExceptionDescription + } +} + +/// This exception indicates a failure in a security subsystem, +/// such as the IceSSL plug-in. +open class SecurityException: LocalException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() { + super.init() + } + + public init(reason: Swift.String, file: Swift.String = #file, line: Swift.Int = #line) { + self.reason = reason + super.init(file: file, line: line) + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::SecurityException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _SecurityExceptionDescription + } +} + +/// This exception indicates that an attempt has been made to +/// change the connection properties of a fixed proxy. +open class FixedProxyException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::FixedProxyException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _FixedProxyExceptionDescription + } +} + +/// Indicates that the response to a request has already been sent; +/// re-dispatching such a request is not possible. +open class ResponseSentException: LocalException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ResponseSentException" + } + + /// Returns a string representation of this exception + /// + /// - returns: `Swift.String` - The string representaton of this exception. + open override func ice_print() -> Swift.String { + return _ResponseSentExceptionDescription + } +} diff --git a/Sources/Ice/Ice_Locator.swift b/Sources/Ice/Ice_Locator.swift new file mode 100644 index 0000000..c0ca646 --- /dev/null +++ b/Sources/Ice/Ice_Locator.swift @@ -0,0 +1,1336 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Locator.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// :nodoc: +public class AdapterNotFoundException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return AdapterNotFoundException.self + } +} + +public extension ClassResolver { + @objc static func Ice_AdapterNotFoundException() -> UserExceptionTypeResolver { + return AdapterNotFoundException_TypeResolver() + } +} + +/// This exception is raised if an adapter cannot be found. +open class AdapterNotFoundException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::AdapterNotFoundException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: AdapterNotFoundException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// :nodoc: +public class InvalidReplicaGroupIdException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return InvalidReplicaGroupIdException.self + } +} + +public extension ClassResolver { + @objc static func Ice_InvalidReplicaGroupIdException() -> UserExceptionTypeResolver { + return InvalidReplicaGroupIdException_TypeResolver() + } +} + +/// This exception is raised if the replica group provided by the +/// server is invalid. +open class InvalidReplicaGroupIdException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::InvalidReplicaGroupIdException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: InvalidReplicaGroupIdException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// :nodoc: +public class AdapterAlreadyActiveException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return AdapterAlreadyActiveException.self + } +} + +public extension ClassResolver { + @objc static func Ice_AdapterAlreadyActiveException() -> UserExceptionTypeResolver { + return AdapterAlreadyActiveException_TypeResolver() + } +} + +/// This exception is raised if a server tries to set endpoints for +/// an adapter that is already active. +open class AdapterAlreadyActiveException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::AdapterAlreadyActiveException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: AdapterAlreadyActiveException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// :nodoc: +public class ObjectNotFoundException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return ObjectNotFoundException.self + } +} + +public extension ClassResolver { + @objc static func Ice_ObjectNotFoundException() -> UserExceptionTypeResolver { + return ObjectNotFoundException_TypeResolver() + } +} + +/// This exception is raised if an object cannot be found. +open class ObjectNotFoundException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ObjectNotFoundException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: ObjectNotFoundException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// :nodoc: +public class ServerNotFoundException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return ServerNotFoundException.self + } +} + +public extension ClassResolver { + @objc static func Ice_ServerNotFoundException() -> UserExceptionTypeResolver { + return ServerNotFoundException_TypeResolver() + } +} + +/// This exception is raised if a server cannot be found. +open class ServerNotFoundException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::ServerNotFoundException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: ServerNotFoundException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// Traits for Slice interface `Locator`. +public struct LocatorTraits: SliceTraits { + public static let staticIds = ["::Ice::Locator", "::Ice::Object"] + public static let staticId = "::Ice::Locator" +} + +/// Traits for Slice interface `LocatorRegistry`. +public struct LocatorRegistryTraits: SliceTraits { + public static let staticIds = ["::Ice::LocatorRegistry", "::Ice::Object"] + public static let staticId = "::Ice::LocatorRegistry" +} + +/// Traits for Slice interface `LocatorFinder`. +public struct LocatorFinderTraits: SliceTraits { + public static let staticIds = ["::Ice::LocatorFinder", "::Ice::Object"] + public static let staticId = "::Ice::LocatorFinder" +} + +/// The Ice locator interface. This interface is used by clients to +/// lookup adapters and objects. It is also used by servers to get the +/// locator registry proxy. +/// +/// The Locator interface is intended to be used by +/// Ice internals and by locator implementations. Regular user code +/// should not attempt to use any functionality of this interface +/// directly. +/// +/// LocatorPrx Methods: +/// +/// - findObjectById: Find an object by identity and return a proxy that contains the adapter ID or endpoints which can be used to access the object. +/// +/// - findObjectByIdAsync: Find an object by identity and return a proxy that contains the adapter ID or endpoints which can be used to access the object. +/// +/// - findAdapterById: Find an adapter by id and return a proxy that contains its endpoints. +/// +/// - findAdapterByIdAsync: Find an adapter by id and return a proxy that contains its endpoints. +/// +/// - getRegistry: Get the locator registry. +/// +/// - getRegistryAsync: Get the locator registry. +public protocol LocatorPrx: ObjectPrx {} + +internal final class LocatorPrxI: ObjectPrxI, LocatorPrx { + public override class func ice_staticId() -> Swift.String { + return LocatorTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `LocatorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `LocatorPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: LocatorPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> LocatorPrx? { + return try LocatorPrxI.checkedCast(prx: prx, facet: facet, context: context) as LocatorPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `LocatorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `LocatorPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: LocatorPrx.Protocol, facet: Swift.String? = nil) -> LocatorPrx { + return LocatorPrxI.uncheckedCast(prx: prx, facet: facet) as LocatorPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `LocatorPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: LocatorPrx.Protocol) -> Swift.String { + return LocatorTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `LocatorPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `LocatorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorPrx?` - The extracted proxy + func read(_ type: LocatorPrx.Protocol) throws -> LocatorPrx? { + return try read() as LocatorPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `LocatorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: LocatorPrx.Protocol) throws -> LocatorPrx? { + return try read(tag: tag) as LocatorPrxI? + } +} + +/// The Ice locator interface. This interface is used by clients to +/// lookup adapters and objects. It is also used by servers to get the +/// locator registry proxy. +/// +/// The Locator interface is intended to be used by +/// Ice internals and by locator implementations. Regular user code +/// should not attempt to use any functionality of this interface +/// directly. +/// +/// LocatorPrx Methods: +/// +/// - findObjectById: Find an object by identity and return a proxy that contains the adapter ID or endpoints which can be used to access the object. +/// +/// - findObjectByIdAsync: Find an object by identity and return a proxy that contains the adapter ID or endpoints which can be used to access the object. +/// +/// - findAdapterById: Find an adapter by id and return a proxy that contains its endpoints. +/// +/// - findAdapterByIdAsync: Find an adapter by id and return a proxy that contains its endpoints. +/// +/// - getRegistry: Get the locator registry. +/// +/// - getRegistryAsync: Get the locator registry. +public extension LocatorPrx { + /// Find an object by identity and return a proxy that contains + /// the adapter ID or endpoints which can be used to access the + /// object. + /// + /// - parameter _: `Identity` The identity. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectPrx?` - The proxy, or null if the object is not active. + /// + /// - throws: + /// + /// - ObjectNotFoundException - Raised if the object cannot + /// be found. + func findObjectById(_ iceP_id: Identity, context: Context? = nil) throws -> ObjectPrx? { + return try _impl._invoke(operation: "findObjectById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ObjectNotFoundException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Find an object by identity and return a proxy that contains + /// the adapter ID or endpoints which can be used to access the + /// object. + /// + /// - parameter _: `Identity` The identity. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findObjectByIdAsync(_ iceP_id: Identity, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findObjectById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ObjectNotFoundException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Find an adapter by id and return a proxy that contains + /// its endpoints. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectPrx?` - The adapter proxy, or null if the adapter is not active. + /// + /// - throws: + /// + /// - AdapterNotFoundException - Raised if the adapter cannot be + /// found. + func findAdapterById(_ iceP_id: Swift.String, context: Context? = nil) throws -> ObjectPrx? { + return try _impl._invoke(operation: "findAdapterById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotFoundException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Find an adapter by id and return a proxy that contains + /// its endpoints. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findAdapterByIdAsync(_ iceP_id: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findAdapterById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotFoundException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the locator registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `LocatorRegistryPrx?` - The locator registry. + func getRegistry(context: Context? = nil) throws -> LocatorRegistryPrx? { + return try _impl._invoke(operation: "getRegistry", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: LocatorRegistryPrx? = try istr.read(LocatorRegistryPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the locator registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getRegistryAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getRegistry", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: LocatorRegistryPrx? = try istr.read(LocatorRegistryPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The Ice locator registry interface. This interface is used by +/// servers to register adapter endpoints with the locator. +/// +/// The LocatorRegistry interface is intended to be used +/// by Ice internals and by locator implementations. Regular user +/// code should not attempt to use any functionality of this interface +/// directly. +/// +/// LocatorRegistryPrx Methods: +/// +/// - setAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setAdapterDirectProxyAsync: Set the adapter endpoints with the locator registry. +/// +/// - setReplicatedAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setReplicatedAdapterDirectProxyAsync: Set the adapter endpoints with the locator registry. +/// +/// - setServerProcessProxy: Set the process proxy for a server. +/// +/// - setServerProcessProxyAsync: Set the process proxy for a server. +public protocol LocatorRegistryPrx: ObjectPrx {} + +internal final class LocatorRegistryPrxI: ObjectPrxI, LocatorRegistryPrx { + public override class func ice_staticId() -> Swift.String { + return LocatorRegistryTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `LocatorRegistryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `LocatorRegistryPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: LocatorRegistryPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> LocatorRegistryPrx? { + return try LocatorRegistryPrxI.checkedCast(prx: prx, facet: facet, context: context) as LocatorRegistryPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `LocatorRegistryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `LocatorRegistryPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: LocatorRegistryPrx.Protocol, facet: Swift.String? = nil) -> LocatorRegistryPrx { + return LocatorRegistryPrxI.uncheckedCast(prx: prx, facet: facet) as LocatorRegistryPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `LocatorRegistryPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: LocatorRegistryPrx.Protocol) -> Swift.String { + return LocatorRegistryTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `LocatorRegistryPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `LocatorRegistryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorRegistryPrx?` - The extracted proxy + func read(_ type: LocatorRegistryPrx.Protocol) throws -> LocatorRegistryPrx? { + return try read() as LocatorRegistryPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `LocatorRegistryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorRegistryPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: LocatorRegistryPrx.Protocol) throws -> LocatorRegistryPrx? { + return try read(tag: tag) as LocatorRegistryPrxI? + } +} + +/// The Ice locator registry interface. This interface is used by +/// servers to register adapter endpoints with the locator. +/// +/// The LocatorRegistry interface is intended to be used +/// by Ice internals and by locator implementations. Regular user +/// code should not attempt to use any functionality of this interface +/// directly. +/// +/// LocatorRegistryPrx Methods: +/// +/// - setAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setAdapterDirectProxyAsync: Set the adapter endpoints with the locator registry. +/// +/// - setReplicatedAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setReplicatedAdapterDirectProxyAsync: Set the adapter endpoints with the locator registry. +/// +/// - setServerProcessProxy: Set the process proxy for a server. +/// +/// - setServerProcessProxyAsync: Set the process proxy for a server. +public extension LocatorRegistryPrx { + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter proxy: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AdapterAlreadyActiveException - Raised if an adapter with the same + /// id is already active. + /// + /// - AdapterNotFoundException - Raised if the adapter cannot + /// be found, or if the locator only allows + /// registered adapters to set their active proxy and the + /// adapter is not registered with the locator. + func setAdapterDirectProxy(id iceP_id: Swift.String, proxy iceP_proxy: ObjectPrx?, context: Context? = nil) throws { + try _impl._invoke(operation: "setAdapterDirectProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_proxy) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterAlreadyActiveException { + throw error + } catch let error as AdapterNotFoundException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter proxy: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setAdapterDirectProxyAsync(id iceP_id: Swift.String, proxy iceP_proxy: ObjectPrx?, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setAdapterDirectProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_proxy) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterAlreadyActiveException { + throw error + } catch let error as AdapterNotFoundException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter adapterId: `Swift.String` The adapter id. + /// + /// - parameter replicaGroupId: `Swift.String` The replica group id. + /// + /// - parameter p: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AdapterAlreadyActiveException - Raised if an adapter with the same + /// id is already active. + /// + /// - AdapterNotFoundException - Raised if the adapter cannot + /// be found, or if the locator only allows registered adapters to + /// set their active proxy and the adapter is not registered with + /// the locator. + /// + /// - InvalidReplicaGroupIdException - Raised if the given + /// replica group doesn't match the one registered with the + /// locator registry for this object adapter. + func setReplicatedAdapterDirectProxy(adapterId iceP_adapterId: Swift.String, replicaGroupId iceP_replicaGroupId: Swift.String, p iceP_p: ObjectPrx?, context: Context? = nil) throws { + try _impl._invoke(operation: "setReplicatedAdapterDirectProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_adapterId) + ostr.write(iceP_replicaGroupId) + ostr.write(iceP_p) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterAlreadyActiveException { + throw error + } catch let error as AdapterNotFoundException { + throw error + } catch let error as InvalidReplicaGroupIdException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter adapterId: `Swift.String` The adapter id. + /// + /// - parameter replicaGroupId: `Swift.String` The replica group id. + /// + /// - parameter p: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setReplicatedAdapterDirectProxyAsync(adapterId iceP_adapterId: Swift.String, replicaGroupId iceP_replicaGroupId: Swift.String, p iceP_p: ObjectPrx?, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setReplicatedAdapterDirectProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_adapterId) + ostr.write(iceP_replicaGroupId) + ostr.write(iceP_p) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterAlreadyActiveException { + throw error + } catch let error as AdapterNotFoundException { + throw error + } catch let error as InvalidReplicaGroupIdException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Set the process proxy for a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter proxy: `ProcessPrx?` The process proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - ServerNotFoundException - Raised if the server cannot + /// be found. + func setServerProcessProxy(id iceP_id: Swift.String, proxy iceP_proxy: ProcessPrx?, context: Context? = nil) throws { + try _impl._invoke(operation: "setServerProcessProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_proxy) + }, + userException:{ ex in + do { + throw ex + } catch let error as ServerNotFoundException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Set the process proxy for a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter proxy: `ProcessPrx?` The process proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setServerProcessProxyAsync(id iceP_id: Swift.String, proxy iceP_proxy: ProcessPrx?, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setServerProcessProxy", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_proxy) + }, + userException:{ ex in + do { + throw ex + } catch let error as ServerNotFoundException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Locator interface. It should be advertised through an Ice +/// object with the identity `Ice/LocatorFinder'. This allows clients +/// to retrieve the locator proxy with just the endpoint information of +/// the service. +/// +/// LocatorFinderPrx Methods: +/// +/// - getLocator: Get the locator proxy implemented by the process hosting this finder object. +/// +/// - getLocatorAsync: Get the locator proxy implemented by the process hosting this finder object. +public protocol LocatorFinderPrx: ObjectPrx {} + +internal final class LocatorFinderPrxI: ObjectPrxI, LocatorFinderPrx { + public override class func ice_staticId() -> Swift.String { + return LocatorFinderTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `LocatorFinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `LocatorFinderPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: LocatorFinderPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> LocatorFinderPrx? { + return try LocatorFinderPrxI.checkedCast(prx: prx, facet: facet, context: context) as LocatorFinderPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `LocatorFinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `LocatorFinderPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: LocatorFinderPrx.Protocol, facet: Swift.String? = nil) -> LocatorFinderPrx { + return LocatorFinderPrxI.uncheckedCast(prx: prx, facet: facet) as LocatorFinderPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `LocatorFinderPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: LocatorFinderPrx.Protocol) -> Swift.String { + return LocatorFinderTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `LocatorFinderPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `LocatorFinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorFinderPrx?` - The extracted proxy + func read(_ type: LocatorFinderPrx.Protocol) throws -> LocatorFinderPrx? { + return try read() as LocatorFinderPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `LocatorFinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorFinderPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: LocatorFinderPrx.Protocol) throws -> LocatorFinderPrx? { + return try read(tag: tag) as LocatorFinderPrxI? + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Locator interface. It should be advertised through an Ice +/// object with the identity `Ice/LocatorFinder'. This allows clients +/// to retrieve the locator proxy with just the endpoint information of +/// the service. +/// +/// LocatorFinderPrx Methods: +/// +/// - getLocator: Get the locator proxy implemented by the process hosting this finder object. +/// +/// - getLocatorAsync: Get the locator proxy implemented by the process hosting this finder object. +public extension LocatorFinderPrx { + /// Get the locator proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `LocatorPrx?` - The locator proxy. + func getLocator(context: Context? = nil) throws -> LocatorPrx? { + return try _impl._invoke(operation: "getLocator", + mode: .Normal, + read: { istr in + let iceP_returnValue: LocatorPrx? = try istr.read(LocatorPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the locator proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getLocatorAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getLocator", + mode: .Normal, + read: { istr in + let iceP_returnValue: LocatorPrx? = try istr.read(LocatorPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Locator` servants. +public struct LocatorDisp: Disp { + public let servant: Locator + private static let defaultObject = ObjectI() + + public init(_ servant: Locator) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "findAdapterById": + return try servant._iceD_findAdapterById(incoming: request, current: current) + case "findObjectById": + return try servant._iceD_findObjectById(incoming: request, current: current) + case "getRegistry": + return try servant._iceD_getRegistry(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Ice locator interface. This interface is used by clients to +/// lookup adapters and objects. It is also used by servers to get the +/// locator registry proxy. +/// +/// The Locator interface is intended to be used by +/// Ice internals and by locator implementations. Regular user code +/// should not attempt to use any functionality of this interface +/// directly. +public protocol Locator { + /// Find an object by identity and return a proxy that contains + /// the adapter ID or endpoints which can be used to access the + /// object. + /// + /// - parameter id: `Identity` The identity. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findObjectByIdAsync(id: Identity, current: Current) -> PromiseKit.Promise + + /// Find an adapter by id and return a proxy that contains + /// its endpoints. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findAdapterByIdAsync(id: Swift.String, current: Current) -> PromiseKit.Promise + + /// Get the locator registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `LocatorRegistryPrx?` - The locator registry. + func getRegistry(current: Current) throws -> LocatorRegistryPrx? +} + + +/// Dispatcher for `LocatorRegistry` servants. +public struct LocatorRegistryDisp: Disp { + public let servant: LocatorRegistry + private static let defaultObject = ObjectI() + + public init(_ servant: LocatorRegistry) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? LocatorRegistryDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? LocatorRegistryDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? LocatorRegistryDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? LocatorRegistryDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "setAdapterDirectProxy": + return try servant._iceD_setAdapterDirectProxy(incoming: request, current: current) + case "setReplicatedAdapterDirectProxy": + return try servant._iceD_setReplicatedAdapterDirectProxy(incoming: request, current: current) + case "setServerProcessProxy": + return try servant._iceD_setServerProcessProxy(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Ice locator registry interface. This interface is used by +/// servers to register adapter endpoints with the locator. +/// +/// The LocatorRegistry interface is intended to be used +/// by Ice internals and by locator implementations. Regular user +/// code should not attempt to use any functionality of this interface +/// directly. +public protocol LocatorRegistry { + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter proxy: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setAdapterDirectProxyAsync(id: Swift.String, proxy: ObjectPrx?, current: Current) -> PromiseKit.Promise + + /// Set the adapter endpoints with the locator registry. + /// + /// - parameter adapterId: `Swift.String` The adapter id. + /// + /// - parameter replicaGroupId: `Swift.String` The replica group id. + /// + /// - parameter p: `ObjectPrx?` The adapter proxy (a dummy direct proxy created + /// by the adapter). The direct proxy contains the adapter + /// endpoints. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setReplicatedAdapterDirectProxyAsync(adapterId: Swift.String, replicaGroupId: Swift.String, p: ObjectPrx?, current: Current) -> PromiseKit.Promise + + /// Set the process proxy for a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter proxy: `ProcessPrx?` The process proxy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setServerProcessProxyAsync(id: Swift.String, proxy: ProcessPrx?, current: Current) -> PromiseKit.Promise +} + + +/// Dispatcher for `LocatorFinder` servants. +public struct LocatorFinderDisp: Disp { + public let servant: LocatorFinder + private static let defaultObject = ObjectI() + + public init(_ servant: LocatorFinder) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "getLocator": + return try servant._iceD_getLocator(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? LocatorFinderDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? LocatorFinderDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? LocatorFinderDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? LocatorFinderDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Locator interface. It should be advertised through an Ice +/// object with the identity `Ice/LocatorFinder'. This allows clients +/// to retrieve the locator proxy with just the endpoint information of +/// the service. +public protocol LocatorFinder { + /// Get the locator proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `LocatorPrx?` - The locator proxy. + func getLocator(current: Current) throws -> LocatorPrx? +} + +/// The Ice locator interface. This interface is used by clients to +/// lookup adapters and objects. It is also used by servers to get the +/// locator registry proxy. +/// +/// The Locator interface is intended to be used by +/// Ice internals and by locator implementations. Regular user code +/// should not attempt to use any functionality of this interface +/// directly. +/// +/// Locator Methods: +/// +/// - findObjectById: Find an object by identity and return a proxy that contains the adapter ID or endpoints which can be used to access the object. +/// +/// - findAdapterById: Find an adapter by id and return a proxy that contains its endpoints. +/// +/// - getRegistry: Get the locator registry. +public extension Locator { + func _iceD_findObjectById(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_id: Identity = try inS.read { istr in + let iceP_id: Identity = try istr.read() + return iceP_id + } + + return inS.setResultPromise(findObjectByIdAsync(id: iceP_id, current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_findAdapterById(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + return inS.setResultPromise(findAdapterByIdAsync(id: iceP_id, current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_getRegistry(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getRegistry(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} + +/// The Ice locator registry interface. This interface is used by +/// servers to register adapter endpoints with the locator. +/// +/// The LocatorRegistry interface is intended to be used +/// by Ice internals and by locator implementations. Regular user +/// code should not attempt to use any functionality of this interface +/// directly. +/// +/// LocatorRegistry Methods: +/// +/// - setAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setReplicatedAdapterDirectProxy: Set the adapter endpoints with the locator registry. +/// +/// - setServerProcessProxy: Set the process proxy for a server. +public extension LocatorRegistry { + func _iceD_setAdapterDirectProxy(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_proxy): (Swift.String, ObjectPrx?) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_proxy: ObjectPrx? = try istr.read(ObjectPrx.self) + return (iceP_id, iceP_proxy) + } + + return inS.setResultPromise(setAdapterDirectProxyAsync(id: iceP_id, proxy: iceP_proxy, current: current)) + } + + func _iceD_setReplicatedAdapterDirectProxy(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_adapterId, iceP_replicaGroupId, iceP_p): (Swift.String, Swift.String, ObjectPrx?) = try inS.read { istr in + let iceP_adapterId: Swift.String = try istr.read() + let iceP_replicaGroupId: Swift.String = try istr.read() + let iceP_p: ObjectPrx? = try istr.read(ObjectPrx.self) + return (iceP_adapterId, iceP_replicaGroupId, iceP_p) + } + + return inS.setResultPromise(setReplicatedAdapterDirectProxyAsync(adapterId: iceP_adapterId, replicaGroupId: iceP_replicaGroupId, p: iceP_p, current: current)) + } + + func _iceD_setServerProcessProxy(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_proxy): (Swift.String, ProcessPrx?) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_proxy: ProcessPrx? = try istr.read(ProcessPrx.self) + return (iceP_id, iceP_proxy) + } + + return inS.setResultPromise(setServerProcessProxyAsync(id: iceP_id, proxy: iceP_proxy, current: current)) + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Locator interface. It should be advertised through an Ice +/// object with the identity `Ice/LocatorFinder'. This allows clients +/// to retrieve the locator proxy with just the endpoint information of +/// the service. +/// +/// LocatorFinder Methods: +/// +/// - getLocator: Get the locator proxy implemented by the process hosting this finder object. +public extension LocatorFinder { + func _iceD_getLocator(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getLocator(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Ice/Ice_LocatorF.swift b/Sources/Ice/Ice_LocatorF.swift new file mode 100644 index 0000000..031e15a --- /dev/null +++ b/Sources/Ice/Ice_LocatorF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Logger.swift b/Sources/Ice/Ice_Logger.swift new file mode 100644 index 0000000..c11d130 --- /dev/null +++ b/Sources/Ice/Ice_Logger.swift @@ -0,0 +1,55 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Logger.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// The Ice message logger. Applications can provide their own logger +/// by implementing this interface and installing it in a communicator. +public protocol Logger: Swift.AnyObject { + /// Print a message. The message is printed literally, without + /// any decorations such as executable name or time stamp. + /// + /// - parameter _: `Swift.String` The message to log. + func print(_ message: Swift.String) + + /// Log a trace message. + /// + /// - parameter category: `Swift.String` The trace category. + /// + /// - parameter message: `Swift.String` The trace message to log. + func trace(category: Swift.String, message: Swift.String) + + /// Log a warning message. + /// + /// - parameter _: `Swift.String` The warning message to log. + func warning(_ message: Swift.String) + + /// Log an error message. + /// + /// - parameter _: `Swift.String` The error message to log. + func error(_ message: Swift.String) + + /// Returns this logger's prefix. + /// + /// - returns: `Swift.String` - The prefix. + func getPrefix() -> Swift.String + + /// Returns a clone of the logger with a new prefix. + /// + /// - parameter _: `Swift.String` The new prefix for the logger. + /// + /// - returns: `Logger` - A logger instance. + func cloneWithPrefix(_ prefix: Swift.String) -> Logger +} diff --git a/Sources/Ice/Ice_LoggerF.swift b/Sources/Ice/Ice_LoggerF.swift new file mode 100644 index 0000000..c7a8345 --- /dev/null +++ b/Sources/Ice/Ice_LoggerF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LoggerF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Metrics.swift b/Sources/Ice/Ice_Metrics.swift new file mode 100644 index 0000000..c833e63 --- /dev/null +++ b/Sources/Ice/Ice_Metrics.swift @@ -0,0 +1,1753 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Metrics.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// A dictionnary of strings to integers. +public typealias MXStringIntDict = [Swift.String: Swift.Int32] + +/// Helper class to read and write `MXStringIntDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct MXStringIntDictHelper { + /// Read a `MXStringIntDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `MXStringIntDict` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> MXStringIntDict { + let sz = try Swift.Int(istr.readSize()) + var v = MXStringIntDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.Int32 = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `MXStringIntDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `MXStringIntDict` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> MXStringIntDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `MXStringIntDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `MXStringIntDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: MXStringIntDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `MXStringIntDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `MXStringIntDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: MXStringIntDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `MXMetrics`. +public struct MXMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::Metrics"] + public static let staticId = "::IceMX::Metrics" +} + +/// A structure to keep track of failures associated with a given +/// metrics. +public struct MXMetricsFailures { + /// The identifier of the metrics object associated to the + /// failures. + public var id: Swift.String = "" + /// The failures observed for this metrics. + public var failures: MXStringIntDict = MXStringIntDict() + + public init() {} + + public init(id: Swift.String, failures: MXStringIntDict) { + self.id = id + self.failures = failures + } +} + +/// An `Ice.InputStream` extension to read `MXMetricsFailures` structured values from the stream. +public extension InputStream { + /// Read a `MXMetricsFailures` structured value from the stream. + /// + /// - returns: `MXMetricsFailures` - The structured value read from the stream. + func read() throws -> MXMetricsFailures { + var v = MXMetricsFailures() + v.id = try self.read() + v.failures = try MXStringIntDictHelper.read(from: self) + return v + } + + /// Read an optional `MXMetricsFailures?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `MXMetricsFailures?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> MXMetricsFailures? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as MXMetricsFailures + } +} + +/// An `Ice.OutputStream` extension to write `MXMetricsFailures` structured values from the stream. +public extension OutputStream { + /// Write a `MXMetricsFailures` structured value to the stream. + /// + /// - parameter _: `MXMetricsFailures` - The value to write to the stream. + func write(_ v: MXMetricsFailures) { + self.write(v.id) + MXStringIntDictHelper.write(to: self, value: v.failures) + } + + /// Write an optional `MXMetricsFailures?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `MXMetricsFailures?` - The value to write to the stream. + func write(tag: Swift.Int32, value: MXMetricsFailures?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of MetricsFailures. +public typealias MXMetricsFailuresSeq = [MXMetricsFailures] + +/// Helper class to read and write `MXMetricsFailuresSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct MXMetricsFailuresSeqHelper { + /// Read a `MXMetricsFailuresSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `MXMetricsFailuresSeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> MXMetricsFailuresSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 2) + var v = MXMetricsFailuresSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: MXMetricsFailures = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `MXMetricsFailuresSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `MXMetricsFailuresSeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> MXMetricsFailuresSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `MXMetricsFailuresSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `MXMetricsFailuresSeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: MXMetricsFailuresSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `MXMetricsFailuresSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `MXMetricsFailuresSeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: MXMetricsFailuresSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A metrics map is a sequence of metrics. We use a sequence here +/// instead of a map because the ID of the metrics is already included +/// in the Metrics class and using sequences of metrics objects is more +/// efficient than using dictionaries since lookup is not necessary. +public typealias MXMetricsMap = [MXMetrics?] + +/// Helper class to read and write `MXMetricsMap` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct MXMetricsMapHelper { + /// Read a `MXMetricsMap` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `MXMetricsMap` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> MXMetricsMap { + let sz = try istr.readAndCheckSeqSize(minSize: 1) + var v = MXMetricsMap(repeating: nil, count: sz) + for i in 0 ..< sz { + try Swift.withUnsafeMutablePointer(to: &v[i]) { p in + try istr.read(MXMetrics.self) { p.pointee = $0 } + } + } + return v + } + /// Read an optional `MXMetricsMap?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `MXMetricsMap` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> MXMetricsMap? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `MXMetricsMap` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `MXMetricsMap` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: MXMetricsMap) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `MXMetricsMap?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `MXMetricsMap` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: MXMetricsMap?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A metrics view is a dictionary of metrics map. The key of the +/// dictionary is the name of the metrics map. +public typealias MXMetricsView = [Swift.String: MXMetricsMap] + +/// Helper class to read and write `MXMetricsView` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct MXMetricsViewHelper { + /// Read a `MXMetricsView` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `MXMetricsView` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> MXMetricsView { + let sz = try Swift.Int(istr.readSize()) + var v = MXMetricsView() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: MXMetricsMap = try MXMetricsMapHelper.read(from: istr) + v[key] = value + } + return v + } + /// Read an optional `MXMetricsView?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `MXMetricsView` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> MXMetricsView? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `MXMetricsView` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `MXMetricsView` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: MXMetricsView) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + MXMetricsMapHelper.write(to: ostr, value: value) + } + } + + /// Wite an optional `MXMetricsView?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `MXMetricsView` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: MXMetricsView?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// :nodoc: +public class MXUnknownMetricsView_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return MXUnknownMetricsView.self + } +} + +public extension ClassResolver { + @objc static func IceMX_UnknownMetricsView() -> UserExceptionTypeResolver { + return MXUnknownMetricsView_TypeResolver() + } +} + +/// Raised if a metrics view cannot be found. +open class MXUnknownMetricsView: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceMX::UnknownMetricsView" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXUnknownMetricsView.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// Traits for Slice interface `MXMetricsAdmin`. +public struct MXMetricsAdminTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::MetricsAdmin"] + public static let staticId = "::IceMX::MetricsAdmin" +} + +/// Traits for Slice class `MXThreadMetrics`. +public struct MXThreadMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::Metrics", "::IceMX::ThreadMetrics"] + public static let staticId = "::IceMX::ThreadMetrics" +} + +/// Traits for Slice class `MXDispatchMetrics`. +public struct MXDispatchMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::DispatchMetrics", "::IceMX::Metrics"] + public static let staticId = "::IceMX::DispatchMetrics" +} + +/// Traits for Slice class `MXChildInvocationMetrics`. +public struct MXChildInvocationMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::ChildInvocationMetrics", "::IceMX::Metrics"] + public static let staticId = "::IceMX::ChildInvocationMetrics" +} + +/// Traits for Slice class `MXCollocatedMetrics`. +public struct MXCollocatedMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::ChildInvocationMetrics", "::IceMX::CollocatedMetrics", "::IceMX::Metrics"] + public static let staticId = "::IceMX::CollocatedMetrics" +} + +/// Traits for Slice class `MXRemoteMetrics`. +public struct MXRemoteMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::ChildInvocationMetrics", "::IceMX::Metrics", "::IceMX::RemoteMetrics"] + public static let staticId = "::IceMX::RemoteMetrics" +} + +/// Traits for Slice class `MXInvocationMetrics`. +public struct MXInvocationMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::InvocationMetrics", "::IceMX::Metrics"] + public static let staticId = "::IceMX::InvocationMetrics" +} + +/// Traits for Slice class `MXConnectionMetrics`. +public struct MXConnectionMetricsTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::ConnectionMetrics", "::IceMX::Metrics"] + public static let staticId = "::IceMX::ConnectionMetrics" +} + +/// The metrics administrative facet interface. This interface allows +/// remote administrative clients to access metrics of an application +/// that enabled the Ice administrative facility and configured some +/// metrics views. +/// +/// MXMetricsAdminPrx Methods: +/// +/// - getMetricsViewNames: Get the names of enabled and disabled metrics. +/// +/// - getMetricsViewNamesAsync: Get the names of enabled and disabled metrics. +/// +/// - enableMetricsView: Enables a metrics view. +/// +/// - enableMetricsViewAsync: Enables a metrics view. +/// +/// - disableMetricsView: Disable a metrics view. +/// +/// - disableMetricsViewAsync: Disable a metrics view. +/// +/// - getMetricsView: Get the metrics objects for the given metrics view. +/// +/// - getMetricsViewAsync: Get the metrics objects for the given metrics view. +/// +/// - getMapMetricsFailures: Get the metrics failures associated with the given view and map. +/// +/// - getMapMetricsFailuresAsync: Get the metrics failures associated with the given view and map. +/// +/// - getMetricsFailures: Get the metrics failure associated for the given metrics. +/// +/// - getMetricsFailuresAsync: Get the metrics failure associated for the given metrics. +public protocol MXMetricsAdminPrx: ObjectPrx {} + +internal final class MXMetricsAdminPrxI: ObjectPrxI, MXMetricsAdminPrx { + public override class func ice_staticId() -> Swift.String { + return MXMetricsAdminTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `MXMetricsAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `MXMetricsAdminPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: MXMetricsAdminPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> MXMetricsAdminPrx? { + return try MXMetricsAdminPrxI.checkedCast(prx: prx, facet: facet, context: context) as MXMetricsAdminPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `MXMetricsAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `MXMetricsAdminPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: MXMetricsAdminPrx.Protocol, facet: Swift.String? = nil) -> MXMetricsAdminPrx { + return MXMetricsAdminPrxI.uncheckedCast(prx: prx, facet: facet) as MXMetricsAdminPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `MXMetricsAdminPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: MXMetricsAdminPrx.Protocol) -> Swift.String { + return MXMetricsAdminTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `MXMetricsAdminPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `MXMetricsAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `MXMetricsAdminPrx?` - The extracted proxy + func read(_ type: MXMetricsAdminPrx.Protocol) throws -> MXMetricsAdminPrx? { + return try read() as MXMetricsAdminPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `MXMetricsAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `MXMetricsAdminPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: MXMetricsAdminPrx.Protocol) throws -> MXMetricsAdminPrx? { + return try read(tag: tag) as MXMetricsAdminPrxI? + } +} + +/// The metrics administrative facet interface. This interface allows +/// remote administrative clients to access metrics of an application +/// that enabled the Ice administrative facility and configured some +/// metrics views. +/// +/// MXMetricsAdminPrx Methods: +/// +/// - getMetricsViewNames: Get the names of enabled and disabled metrics. +/// +/// - getMetricsViewNamesAsync: Get the names of enabled and disabled metrics. +/// +/// - enableMetricsView: Enables a metrics view. +/// +/// - enableMetricsViewAsync: Enables a metrics view. +/// +/// - disableMetricsView: Disable a metrics view. +/// +/// - disableMetricsViewAsync: Disable a metrics view. +/// +/// - getMetricsView: Get the metrics objects for the given metrics view. +/// +/// - getMetricsViewAsync: Get the metrics objects for the given metrics view. +/// +/// - getMapMetricsFailures: Get the metrics failures associated with the given view and map. +/// +/// - getMapMetricsFailuresAsync: Get the metrics failures associated with the given view and map. +/// +/// - getMetricsFailures: Get the metrics failure associated for the given metrics. +/// +/// - getMetricsFailuresAsync: Get the metrics failure associated for the given metrics. +public extension MXMetricsAdminPrx { + /// Get the names of enabled and disabled metrics. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: StringSeq, disabledViews: StringSeq)`: + /// + /// - returnValue: `StringSeq` - The name of the enabled views. + /// + /// - disabledViews: `StringSeq` - The names of the disabled views. + func getMetricsViewNames(context: Context? = nil) throws -> (returnValue: StringSeq, disabledViews: StringSeq) { + return try _impl._invoke(operation: "getMetricsViewNames", + mode: .Normal, + format: .SlicedFormat, + read: { istr in + let iceP_disabledViews: StringSeq = try istr.read() + let iceP_returnValue: StringSeq = try istr.read() + return (iceP_returnValue, iceP_disabledViews) + }, + context: context) + } + + /// Get the names of enabled and disabled metrics. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: StringSeq, disabledViews: StringSeq)>` - The result of the operation + func getMetricsViewNamesAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: StringSeq, disabledViews: StringSeq)> { + return _impl._invokeAsync(operation: "getMetricsViewNames", + mode: .Normal, + format: .SlicedFormat, + read: { istr in + let iceP_disabledViews: StringSeq = try istr.read() + let iceP_returnValue: StringSeq = try istr.read() + return (iceP_returnValue, iceP_disabledViews) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Enables a metrics view. + /// + /// - parameter _: `Swift.String` The metrics view name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func enableMetricsView(_ iceP_name: Swift.String, context: Context? = nil) throws { + try _impl._invoke(operation: "enableMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Enables a metrics view. + /// + /// - parameter _: `Swift.String` The metrics view name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func enableMetricsViewAsync(_ iceP_name: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "enableMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Disable a metrics view. + /// + /// - parameter _: `Swift.String` The metrics view name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func disableMetricsView(_ iceP_name: Swift.String, context: Context? = nil) throws { + try _impl._invoke(operation: "disableMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Disable a metrics view. + /// + /// - parameter _: `Swift.String` The metrics view name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func disableMetricsViewAsync(_ iceP_name: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "disableMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the metrics objects for the given metrics view. This + /// returns a dictionnary of metric maps for each metrics class + /// configured with the view. The timestamp allows the client to + /// compute averages which are not dependent of the invocation + /// latency for this operation. + /// + /// - parameter _: `Swift.String` The name of the metrics view. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: MXMetricsView, timestamp: Swift.Int64)`: + /// + /// - returnValue: `MXMetricsView` - The metrics view data. + /// + /// - timestamp: `Swift.Int64` - The local time of the process when the metrics + /// object were retrieved. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMetricsView(_ iceP_view: Swift.String, context: Context? = nil) throws -> (returnValue: MXMetricsView, timestamp: Swift.Int64) { + return try _impl._invoke(operation: "getMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + }, + read: { istr in + let iceP_timestamp: Swift.Int64 = try istr.read() + let iceP_returnValue: MXMetricsView = try MXMetricsViewHelper.read(from: istr) + try istr.readPendingValues() + return (iceP_returnValue, iceP_timestamp) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Get the metrics objects for the given metrics view. This + /// returns a dictionnary of metric maps for each metrics class + /// configured with the view. The timestamp allows the client to + /// compute averages which are not dependent of the invocation + /// latency for this operation. + /// + /// - parameter _: `Swift.String` The name of the metrics view. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: MXMetricsView, timestamp: Swift.Int64)>` - The result of the operation + func getMetricsViewAsync(_ iceP_view: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: MXMetricsView, timestamp: Swift.Int64)> { + return _impl._invokeAsync(operation: "getMetricsView", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + }, + read: { istr in + let iceP_timestamp: Swift.Int64 = try istr.read() + let iceP_returnValue: MXMetricsView = try MXMetricsViewHelper.read(from: istr) + try istr.readPendingValues() + return (iceP_returnValue, iceP_timestamp) + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the metrics failures associated with the given view and map. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `MXMetricsFailuresSeq` - The metrics failures associated with the map. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMapMetricsFailures(view iceP_view: Swift.String, map iceP_map: Swift.String, context: Context? = nil) throws -> MXMetricsFailuresSeq { + return try _impl._invoke(operation: "getMapMetricsFailures", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + ostr.write(iceP_map) + }, + read: { istr in + let iceP_returnValue: MXMetricsFailuresSeq = try MXMetricsFailuresSeqHelper.read(from: istr) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Get the metrics failures associated with the given view and map. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getMapMetricsFailuresAsync(view iceP_view: Swift.String, map iceP_map: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getMapMetricsFailures", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + ostr.write(iceP_map) + }, + read: { istr in + let iceP_returnValue: MXMetricsFailuresSeq = try MXMetricsFailuresSeqHelper.read(from: istr) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the metrics failure associated for the given metrics. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter id: `Swift.String` The ID of the metrics. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `MXMetricsFailures` - The metrics failures associated with the metrics. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMetricsFailures(view iceP_view: Swift.String, map iceP_map: Swift.String, id iceP_id: Swift.String, context: Context? = nil) throws -> MXMetricsFailures { + return try _impl._invoke(operation: "getMetricsFailures", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + ostr.write(iceP_map) + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: MXMetricsFailures = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Get the metrics failure associated for the given metrics. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter id: `Swift.String` The ID of the metrics. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getMetricsFailuresAsync(view iceP_view: Swift.String, map iceP_map: Swift.String, id iceP_id: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getMetricsFailures", + mode: .Normal, + format: .SlicedFormat, + write: { ostr in + ostr.write(iceP_view) + ostr.write(iceP_map) + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: MXMetricsFailures = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as MXUnknownMetricsView { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// :nodoc: +public class MXMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_Metrics() -> ValueTypeResolver { + return MXMetrics_TypeResolver() + } +} + +/// The base class for metrics. A metrics object represents a +/// collection of measurements associated to a given a system. +open class MXMetrics: Value { + /// The metrics identifier. + public var id: Swift.String = "" + /// The total number of objects observed by this metrics. This includes + /// the number of currently observed objects and the number of objects + /// observed in the past. + public var total: Swift.Int64 = 0 + /// The number of objects currently observed by this metrics. + public var current: Swift.Int32 = 0 + /// The sum of the lifetime of each observed objects. This does not + /// include the lifetime of objects which are currently observed, + /// only the objects observed in the past. + public var totalLifetime: Swift.Int64 = 0 + /// The number of failures observed. + public var failures: Swift.Int32 = 0 + + public required init() {} + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32) { + self.id = id + self.total = total + self.current = current + self.totalLifetime = totalLifetime + self.failures = failures + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + self.total = try istr.read() + self.current = try istr.read() + self.totalLifetime = try istr.read() + self.failures = try istr.read() + try istr.endSlice() + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXMetricsTraits.staticId, compactId: -1, last: true) + ostr.write(self.id) + ostr.write(self.total) + ostr.write(self.current) + ostr.write(self.totalLifetime) + ostr.write(self.failures) + ostr.endSlice() + } +} + +/// :nodoc: +public class MXThreadMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXThreadMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_ThreadMetrics() -> ValueTypeResolver { + return MXThreadMetrics_TypeResolver() + } +} + +/// Provides information on the number of threads currently in use and +/// their activity. +open class MXThreadMetrics: MXMetrics { + /// The number of threads which are currently performing socket + /// read or writes. + public var inUseForIO: Swift.Int32 = 0 + /// The number of threads which are currently calling user code + /// (servant dispatch, AMI callbacks, etc). + public var inUseForUser: Swift.Int32 = 0 + /// The number of threads which are currently performing other + /// activities. These are all other that are not counted with + /// inUseForUser or inUseForIO, such as DNS + /// lookups, garbage collection). + public var inUseForOther: Swift.Int32 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, inUseForIO: Swift.Int32, inUseForUser: Swift.Int32, inUseForOther: Swift.Int32) { + self.inUseForIO = inUseForIO + self.inUseForUser = inUseForUser + self.inUseForOther = inUseForOther + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXThreadMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXThreadMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.inUseForIO = try istr.read() + self.inUseForUser = try istr.read() + self.inUseForOther = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXThreadMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.inUseForIO) + ostr.write(self.inUseForUser) + ostr.write(self.inUseForOther) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXDispatchMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXDispatchMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_DispatchMetrics() -> ValueTypeResolver { + return MXDispatchMetrics_TypeResolver() + } +} + +/// Provides information on servant dispatch. +open class MXDispatchMetrics: MXMetrics { + /// The number of dispatch that failed with a user exception. + public var userException: Swift.Int32 = 0 + /// The size of the dispatch. This corresponds to the size of the + /// marshalled input parameters. + public var size: Swift.Int64 = 0 + /// The size of the dispatch reply. This corresponds to the size of + /// the marshalled output and return parameters. + public var replySize: Swift.Int64 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, userException: Swift.Int32, size: Swift.Int64, replySize: Swift.Int64) { + self.userException = userException + self.size = size + self.replySize = replySize + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXDispatchMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXDispatchMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.userException = try istr.read() + self.size = try istr.read() + self.replySize = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXDispatchMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.userException) + ostr.write(self.size) + ostr.write(self.replySize) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXChildInvocationMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXChildInvocationMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_ChildInvocationMetrics() -> ValueTypeResolver { + return MXChildInvocationMetrics_TypeResolver() + } +} + +/// Provides information on child invocations. A child invocation is +/// either remote (sent over an Ice connection) or collocated. An +/// invocation can have multiple child invocation if it is +/// retried. Child invocation metrics are embedded within +/// InvocationMetrics. +open class MXChildInvocationMetrics: MXMetrics { + /// The size of the invocation. This corresponds to the size of the + /// marshalled input parameters. + public var size: Swift.Int64 = 0 + /// The size of the invocation reply. This corresponds to the size + /// of the marshalled output and return parameters. + public var replySize: Swift.Int64 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, size: Swift.Int64, replySize: Swift.Int64) { + self.size = size + self.replySize = replySize + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXChildInvocationMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXChildInvocationMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.size = try istr.read() + self.replySize = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXChildInvocationMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.size) + ostr.write(self.replySize) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXCollocatedMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXCollocatedMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_CollocatedMetrics() -> ValueTypeResolver { + return MXCollocatedMetrics_TypeResolver() + } +} + +/// Provides information on invocations that are collocated. Collocated +/// metrics are embedded within InvocationMetrics. +open class MXCollocatedMetrics: MXChildInvocationMetrics { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXCollocatedMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXCollocatedMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXCollocatedMetricsTraits.staticId, compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXRemoteMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXRemoteMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_RemoteMetrics() -> ValueTypeResolver { + return MXRemoteMetrics_TypeResolver() + } +} + +/// Provides information on invocations that are specifically sent over +/// Ice connections. Remote metrics are embedded within InvocationMetrics. +open class MXRemoteMetrics: MXChildInvocationMetrics { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXRemoteMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXRemoteMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXRemoteMetricsTraits.staticId, compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXInvocationMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXInvocationMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_InvocationMetrics() -> ValueTypeResolver { + return MXInvocationMetrics_TypeResolver() + } +} + +/// Provide measurements for proxy invocations. Proxy invocations can +/// either be sent over the wire or be collocated. +open class MXInvocationMetrics: MXMetrics { + /// The number of retries for the invocation(s). + public var retry: Swift.Int32 = 0 + /// The number of invocations that failed with a user exception. + public var userException: Swift.Int32 = 0 + /// The remote invocation metrics map. + public var remotes: MXMetricsMap = MXMetricsMap() + /// The collocated invocation metrics map. + public var collocated: MXMetricsMap = MXMetricsMap() + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, retry: Swift.Int32, userException: Swift.Int32, remotes: MXMetricsMap, collocated: MXMetricsMap) { + self.retry = retry + self.userException = userException + self.remotes = remotes + self.collocated = collocated + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXInvocationMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXInvocationMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.retry = try istr.read() + self.userException = try istr.read() + self.remotes = try MXMetricsMapHelper.read(from: istr) + self.collocated = try MXMetricsMapHelper.read(from: istr) + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXInvocationMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.retry) + ostr.write(self.userException) + MXMetricsMapHelper.write(to: ostr, value: self.remotes) + MXMetricsMapHelper.write(to: ostr, value: self.collocated) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXConnectionMetrics_TypeResolver: ValueTypeResolver { + public override func type() -> Value.Type { + return MXConnectionMetrics.self + } +} + +public extension ClassResolver { + @objc static func IceMX_ConnectionMetrics() -> ValueTypeResolver { + return MXConnectionMetrics_TypeResolver() + } +} + +/// Provides information on the data sent and received over Ice +/// connections. +open class MXConnectionMetrics: MXMetrics { + /// The number of bytes received by the connection. + public var receivedBytes: Swift.Int64 = 0 + /// The number of bytes sent by the connection. + public var sentBytes: Swift.Int64 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, receivedBytes: Swift.Int64, sentBytes: Swift.Int64) { + self.receivedBytes = receivedBytes + self.sentBytes = sentBytes + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXConnectionMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXConnectionMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + self.receivedBytes = try istr.read() + self.sentBytes = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: MXConnectionMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.receivedBytes) + ostr.write(self.sentBytes) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + + +/// Dispatcher for `MXMetricsAdmin` servants. +public struct MXMetricsAdminDisp: Disp { + public let servant: MXMetricsAdmin + private static let defaultObject = ObjectI() + + public init(_ servant: MXMetricsAdmin) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "disableMetricsView": + return try servant._iceD_disableMetricsView(incoming: request, current: current) + case "enableMetricsView": + return try servant._iceD_enableMetricsView(incoming: request, current: current) + case "getMapMetricsFailures": + return try servant._iceD_getMapMetricsFailures(incoming: request, current: current) + case "getMetricsFailures": + return try servant._iceD_getMetricsFailures(incoming: request, current: current) + case "getMetricsView": + return try servant._iceD_getMetricsView(incoming: request, current: current) + case "getMetricsViewNames": + return try servant._iceD_getMetricsViewNames(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? MXMetricsAdminDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? MXMetricsAdminDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? MXMetricsAdminDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? MXMetricsAdminDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The metrics administrative facet interface. This interface allows +/// remote administrative clients to access metrics of an application +/// that enabled the Ice administrative facility and configured some +/// metrics views. +public protocol MXMetricsAdmin { + /// Get the names of enabled and disabled metrics. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: StringSeq, disabledViews: StringSeq)`: + /// + /// - returnValue: `StringSeq` - The name of the enabled views. + /// + /// - disabledViews: `StringSeq` - The names of the disabled views. + func getMetricsViewNames(current: Current) throws -> (returnValue: StringSeq, disabledViews: StringSeq) + + /// Enables a metrics view. + /// + /// - parameter name: `Swift.String` The metrics view name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func enableMetricsView(name: Swift.String, current: Current) throws + + /// Disable a metrics view. + /// + /// - parameter name: `Swift.String` The metrics view name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func disableMetricsView(name: Swift.String, current: Current) throws + + /// Get the metrics objects for the given metrics view. This + /// returns a dictionnary of metric maps for each metrics class + /// configured with the view. The timestamp allows the client to + /// compute averages which are not dependent of the invocation + /// latency for this operation. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: MXMetricsView, timestamp: Swift.Int64)`: + /// + /// - returnValue: `MXMetricsView` - The metrics view data. + /// + /// - timestamp: `Swift.Int64` - The local time of the process when the metrics + /// object were retrieved. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMetricsView(view: Swift.String, current: Current) throws -> (returnValue: MXMetricsView, timestamp: Swift.Int64) + + /// Get the metrics failures associated with the given view and map. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `MXMetricsFailuresSeq` - The metrics failures associated with the map. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMapMetricsFailures(view: Swift.String, map: Swift.String, current: Current) throws -> MXMetricsFailuresSeq + + /// Get the metrics failure associated for the given metrics. + /// + /// - parameter view: `Swift.String` The name of the metrics view. + /// + /// - parameter map: `Swift.String` The name of the metrics map. + /// + /// - parameter id: `Swift.String` The ID of the metrics. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `MXMetricsFailures` - The metrics failures associated with the metrics. + /// + /// - throws: + /// + /// - UnknownMetricsView - Raised if the metrics view cannot be + /// found. + func getMetricsFailures(view: Swift.String, map: Swift.String, id: Swift.String, current: Current) throws -> MXMetricsFailures +} + +/// The metrics administrative facet interface. This interface allows +/// remote administrative clients to access metrics of an application +/// that enabled the Ice administrative facility and configured some +/// metrics views. +/// +/// MXMetricsAdmin Methods: +/// +/// - getMetricsViewNames: Get the names of enabled and disabled metrics. +/// +/// - enableMetricsView: Enables a metrics view. +/// +/// - disableMetricsView: Disable a metrics view. +/// +/// - getMetricsView: Get the metrics objects for the given metrics view. +/// +/// - getMapMetricsFailures: Get the metrics failures associated with the given view and map. +/// +/// - getMetricsFailures: Get the metrics failure associated for the given metrics. +public extension MXMetricsAdmin { + func _iceD_getMetricsViewNames(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + inS.setFormat(.SlicedFormat) + + let (iceP_returnValue, iceP_disabledViews) = try self.getMetricsViewNames(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_disabledViews) + ostr.write(iceP_returnValue) + } + } + + func _iceD_enableMetricsView(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + inS.setFormat(.SlicedFormat) + + try self.enableMetricsView(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_disableMetricsView(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + inS.setFormat(.SlicedFormat) + + try self.disableMetricsView(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_getMetricsView(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_view: Swift.String = try inS.read { istr in + let iceP_view: Swift.String = try istr.read() + return iceP_view + } + inS.setFormat(.SlicedFormat) + + let (iceP_returnValue, iceP_timestamp) = try self.getMetricsView(view: iceP_view, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_timestamp) + MXMetricsViewHelper.write(to: ostr, value: iceP_returnValue) + ostr.writePendingValues() + } + } + + func _iceD_getMapMetricsFailures(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_view, iceP_map): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_view: Swift.String = try istr.read() + let iceP_map: Swift.String = try istr.read() + return (iceP_view, iceP_map) + } + inS.setFormat(.SlicedFormat) + + let iceP_returnValue = try self.getMapMetricsFailures(view: iceP_view, map: iceP_map, current: current) + + return inS.setResult{ ostr in + MXMetricsFailuresSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_getMetricsFailures(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_view, iceP_map, iceP_id): (Swift.String, Swift.String, Swift.String) = try inS.read { istr in + let iceP_view: Swift.String = try istr.read() + let iceP_map: Swift.String = try istr.read() + let iceP_id: Swift.String = try istr.read() + return (iceP_view, iceP_map, iceP_id) + } + inS.setFormat(.SlicedFormat) + + let iceP_returnValue = try self.getMetricsFailures(view: iceP_view, map: iceP_map, id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Ice/Ice_ObjectAdapter.swift b/Sources/Ice/Ice_ObjectAdapter.swift new file mode 100644 index 0000000..dbfdd0a --- /dev/null +++ b/Sources/Ice/Ice_ObjectAdapter.swift @@ -0,0 +1,422 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapter.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// The object adapter provides an up-call interface from the Ice +/// run time to the implementation of Ice objects. +/// +/// The object adapter is responsible for receiving requests +/// from endpoints, and for mapping between servants, identities, and +/// proxies. +public protocol ObjectAdapter: Swift.AnyObject { + /// Get the name of this object adapter. + /// + /// - returns: `Swift.String` - This object adapter's name. + func getName() -> Swift.String + + /// Get the communicator this object adapter belongs to. + /// + /// - returns: `Communicator` - This object adapter's communicator. + func getCommunicator() -> Communicator + + /// Activate all endpoints that belong to this object adapter. + /// After activation, the object adapter can dispatch requests + /// received through its endpoints. + func activate() throws + + /// Temporarily hold receiving and dispatching requests. The object + /// adapter can be reactivated with the activate operation. + /// + /// Holding is not immediate, i.e., after hold + /// returns, the object adapter might still be active for some + /// time. You can use waitForHold to wait until holding is + /// complete. + func hold() + + /// Wait until the object adapter holds requests. Calling hold + /// initiates holding of requests, and waitForHold only returns + /// when holding of requests has been completed. + func waitForHold() + + /// Deactivate all endpoints that belong to this object adapter. + /// After deactivation, the object adapter stops receiving + /// requests through its endpoints. Object adapters that have been + /// deactivated must not be reactivated again, and cannot be used + /// otherwise. Attempts to use a deactivated object adapter raise + /// ObjectAdapterDeactivatedException however, attempts to + /// deactivate an already deactivated object adapter are + /// ignored and do nothing. Once deactivated, it is possible to + /// destroy the adapter to clean up resources and then create and + /// activate a new adapter with the same name. + /// + /// After deactivate returns, no new requests + /// are processed by the object adapter. However, requests that + /// have been started before deactivate was called might + /// still be active. You can use waitForDeactivate to wait + /// for the completion of all requests for this object adapter. + func deactivate() + + /// Wait until the object adapter has deactivated. Calling + /// deactivate initiates object adapter deactivation, and + /// waitForDeactivate only returns when deactivation has + /// been completed. + func waitForDeactivate() + + /// Check whether object adapter has been deactivated. + /// + /// - returns: `Swift.Bool` - Whether adapter has been deactivated. + func isDeactivated() -> Swift.Bool + + /// Destroys the object adapter and cleans up all resources held by + /// the object adapter. If the object adapter has not yet been + /// deactivated, destroy implicitly initiates the deactivation + /// and waits for it to finish. Subsequent calls to destroy are + /// ignored. Once destroy has returned, it is possible to create + /// another object adapter with the same name. + func destroy() + + /// Add a servant to this object adapter's Active Servant Map. Note + /// that one servant can implement several Ice objects by registering + /// the servant with multiple identities. Adding a servant with an + /// identity that is in the map already throws AlreadyRegisteredException. + /// + /// - parameter servant: `Disp` The servant to add. + /// + /// - parameter id: `Identity` The identity of the Ice object that is implemented by + /// the servant. + /// + /// - returns: `ObjectPrx` - A proxy that matches the given identity and this object + /// adapter. + @discardableResult + func add(servant: Disp, id: Identity) throws -> ObjectPrx + + /// Like add, but with a facet. Calling add(servant, id) + /// is equivalent to calling addFacet with an empty facet. + /// + /// - parameter servant: `Disp` The servant to add. + /// + /// - parameter id: `Identity` The identity of the Ice object that is implemented by + /// the servant. + /// + /// - parameter facet: `Swift.String` The facet. An empty facet means the default facet. + /// + /// - returns: `ObjectPrx` - A proxy that matches the given identity, facet, and + /// this object adapter. + @discardableResult + func addFacet(servant: Disp, id: Identity, facet: Swift.String) throws -> ObjectPrx + + /// Add a servant to this object adapter's Active Servant Map, + /// using an automatically generated UUID as its identity. Note that + /// the generated UUID identity can be accessed using the proxy's + /// ice_getIdentity operation. + /// + /// - parameter _: `Disp` The servant to add. + /// + /// - returns: `ObjectPrx` - A proxy that matches the generated UUID identity and + /// this object adapter. + @discardableResult + func addWithUUID(_ servant: Disp) throws -> ObjectPrx + + /// Like addWithUUID, but with a facet. Calling + /// addWithUUID(servant) is equivalent to calling + /// addFacetWithUUID with an empty facet. + /// + /// - parameter servant: `Disp` The servant to add. + /// + /// - parameter facet: `Swift.String` The facet. An empty facet means the default + /// facet. + /// + /// - returns: `ObjectPrx` - A proxy that matches the generated UUID identity, + /// facet, and this object adapter. + @discardableResult + func addFacetWithUUID(servant: Disp, facet: Swift.String) throws -> ObjectPrx + + /// Add a default servant to handle requests for a specific + /// category. Adding a default servant for a category for + /// which a default servant is already registered throws + /// AlreadyRegisteredException. To dispatch operation + /// calls on servants, the object adapter tries to find a servant + /// for a given Ice object identity and facet in the following + /// order: + /// + /// + /// + /// The object adapter tries to find a servant for the identity + /// and facet in the Active Servant Map. + /// + /// If no servant has been found in the Active Servant Map, the + /// object adapter tries to find a default servant for the category + /// component of the identity. + /// + /// If no servant has been found by any of the preceding steps, + /// the object adapter tries to find a default servant for an empty + /// category, regardless of the category contained in the identity. + /// + /// If no servant has been found by any of the preceding steps, + /// the object adapter gives up and the caller receives + /// ObjectNotExistException or FacetNotExistException. + /// + /// - parameter servant: `Disp` The default servant. + /// + /// - parameter category: `Swift.String` The category for which the default servant is + /// registered. An empty category means it will handle all categories. + func addDefaultServant(servant: Disp, category: Swift.String) throws + + /// Remove a servant (that is, the default facet) from the object + /// adapter's Active Servant Map. + /// + /// - parameter _: `Identity` The identity of the Ice object that is implemented by + /// the servant. If the servant implements multiple Ice objects, + /// remove has to be called for all those Ice objects. + /// Removing an identity that is not in the map throws + /// NotRegisteredException. + /// + /// - returns: `Disp` - The removed servant. + @discardableResult + func remove(_ id: Identity) throws -> Disp + + /// Like remove, but with a facet. Calling remove(id) + /// is equivalent to calling removeFacet with an empty facet. + /// + /// - parameter id: `Identity` The identity of the Ice object that is implemented by + /// the servant. + /// + /// - parameter facet: `Swift.String` The facet. An empty facet means the default facet. + /// + /// - returns: `Disp` - The removed servant. + @discardableResult + func removeFacet(id: Identity, facet: Swift.String) throws -> Disp + + /// Remove all facets with the given identity from the Active + /// Servant Map. The operation completely removes the Ice object, + /// including its default facet. Removing an identity that + /// is not in the map throws NotRegisteredException. + /// + /// - parameter _: `Identity` The identity of the Ice object to be removed. + /// + /// - returns: `FacetMap` - A collection containing all the facet names and + /// servants of the removed Ice object. + @discardableResult + func removeAllFacets(_ id: Identity) throws -> FacetMap + + /// Remove the default servant for a specific category. Attempting + /// to remove a default servant for a category that is not + /// registered throws NotRegisteredException. + /// + /// - parameter _: `Swift.String` The category of the default servant to remove. + /// + /// - returns: `Disp` - The default servant. + @discardableResult + func removeDefaultServant(_ category: Swift.String) throws -> Disp + + /// Look up a servant in this object adapter's Active Servant Map + /// by the identity of the Ice object it implements. + /// + /// This operation only tries to look up a servant in + /// the Active Servant Map. It does not attempt to find a servant + /// by using any installed ServantLocator. + /// + /// - parameter _: `Identity` The identity of the Ice object for which the servant + /// should be returned. + /// + /// - returns: `Disp?` - The servant that implements the Ice object with the + /// given identity, or null if no such servant has been found. + func find(_ id: Identity) -> Disp? + + /// Like find, but with a facet. Calling find(id) + /// is equivalent to calling findFacet with an empty + /// facet. + /// + /// - parameter id: `Identity` The identity of the Ice object for which the + /// servant should be returned. + /// + /// - parameter facet: `Swift.String` The facet. An empty facet means the default + /// facet. + /// + /// - returns: `Disp?` - The servant that implements the Ice object with the + /// given identity and facet, or null if no such servant has been + /// found. + func findFacet(id: Identity, facet: Swift.String) -> Disp? + + /// Find all facets with the given identity in the Active Servant + /// Map. + /// + /// - parameter _: `Identity` The identity of the Ice object for which the facets + /// should be returned. + /// + /// - returns: `FacetMap` - A collection containing all the facet names and + /// servants that have been found, or an empty map if there is no + /// facet for the given identity. + func findAllFacets(_ id: Identity) -> FacetMap + + /// Look up a servant in this object adapter's Active Servant Map, + /// given a proxy. + /// + /// This operation only tries to lookup a servant in + /// the Active Servant Map. It does not attempt to find a servant + /// by using any installed ServantLocator. + /// + /// - parameter _: `ObjectPrx` The proxy for which the servant should be returned. + /// + /// - returns: `Disp?` - The servant that matches the proxy, or null if no such + /// servant has been found. + func findByProxy(_ proxy: ObjectPrx) -> Disp? + + /// Add a Servant Locator to this object adapter. Adding a servant + /// locator for a category for which a servant locator is already + /// registered throws AlreadyRegisteredException. To dispatch + /// operation calls on servants, the object adapter tries to find a + /// servant for a given Ice object identity and facet in the + /// following order: + /// + /// + /// + /// The object adapter tries to find a servant for the identity + /// and facet in the Active Servant Map. + /// + /// If no servant has been found in the Active Servant Map, + /// the object adapter tries to find a servant locator for the + /// category component of the identity. If a locator is found, the + /// object adapter tries to find a servant using this locator. + /// + /// If no servant has been found by any of the preceding steps, + /// the object adapter tries to find a locator for an empty category, + /// regardless of the category contained in the identity. If a + /// locator is found, the object adapter tries to find a servant + /// using this locator. + /// + /// If no servant has been found by any of the preceding steps, + /// the object adapter gives up and the caller receives + /// ObjectNotExistException or FacetNotExistException. + /// + /// + /// + /// Only one locator for the empty category can be + /// installed. + /// + /// - parameter locator: `ServantLocator` The locator to add. + /// + /// - parameter category: `Swift.String` The category for which the Servant Locator can + /// locate servants, or an empty string if the Servant Locator does + /// not belong to any specific category. + func addServantLocator(locator: ServantLocator, category: Swift.String) throws + + /// Remove a Servant Locator from this object adapter. + /// + /// - parameter _: `Swift.String` The category for which the Servant Locator can + /// locate servants, or an empty string if the Servant Locator does + /// not belong to any specific category. + /// + /// - returns: `ServantLocator` - The Servant Locator, or throws NotRegisteredException + /// if no Servant Locator was found for the given category. + @discardableResult + func removeServantLocator(_ category: Swift.String) throws -> ServantLocator + + /// Find a Servant Locator installed with this object adapter. + /// + /// - parameter _: `Swift.String` The category for which the Servant Locator can + /// locate servants, or an empty string if the Servant Locator does + /// not belong to any specific category. + /// + /// - returns: `ServantLocator?` - The Servant Locator, or null if no Servant Locator was + /// found for the given category. + func findServantLocator(_ category: Swift.String) -> ServantLocator? + + /// Find the default servant for a specific category. + /// + /// - parameter _: `Swift.String` The category of the default servant to find. + /// + /// - returns: `Disp?` - The default servant or null if no default servant was + /// registered for the category. + func findDefaultServant(_ category: Swift.String) -> Disp? + + /// Create a proxy for the object with the given identity. If this + /// object adapter is configured with an adapter id, the return + /// value is an indirect proxy that refers to the adapter id. If + /// a replica group id is also defined, the return value is an + /// indirect proxy that refers to the replica group id. Otherwise, + /// if no adapter id is defined, the return value is a direct + /// proxy containing this object adapter's published endpoints. + /// + /// - parameter _: `Identity` The object's identity. + /// + /// - returns: `ObjectPrx` - A proxy for the object with the given identity. + func createProxy(_ id: Identity) throws -> ObjectPrx + + /// Create a direct proxy for the object with the given identity. + /// The returned proxy contains this object adapter's published + /// endpoints. + /// + /// - parameter _: `Identity` The object's identity. + /// + /// - returns: `ObjectPrx` - A proxy for the object with the given identity. + func createDirectProxy(_ id: Identity) throws -> ObjectPrx + + /// Create an indirect proxy for the object with the given identity. + /// If this object adapter is configured with an adapter id, the + /// return value refers to the adapter id. Otherwise, the return + /// value contains only the object identity. + /// + /// - parameter _: `Identity` The object's identity. + /// + /// - returns: `ObjectPrx` - A proxy for the object with the given identity. + func createIndirectProxy(_ id: Identity) throws -> ObjectPrx + + /// Set an Ice locator for this object adapter. By doing so, the + /// object adapter will register itself with the locator registry + /// when it is activated for the first time. Furthermore, the proxies + /// created by this object adapter will contain the adapter identifier + /// instead of its endpoints. The adapter identifier must be configured + /// using the AdapterId property. + /// + /// - parameter _: `LocatorPrx?` The locator used by this object adapter. + func setLocator(_ loc: LocatorPrx?) throws + + /// Get the Ice locator used by this object adapter. + /// + /// - returns: `LocatorPrx?` - The locator used by this object adapter, or null if no locator is + /// used by this object adapter. + func getLocator() -> LocatorPrx? + + /// Get the set of endpoints configured with this object adapter. + /// + /// - returns: `EndpointSeq` - The set of endpoints. + func getEndpoints() -> EndpointSeq + + /// Refresh the set of published endpoints. The run time re-reads + /// the PublishedEndpoints property if it is set and re-reads the + /// list of local interfaces if the adapter is configured to listen + /// on all endpoints. This operation is useful to refresh the endpoint + /// information that is published in the proxies that are created by + /// an object adapter if the network interfaces used by a host changes. + func refreshPublishedEndpoints() throws + + /// Get the set of endpoints that proxies created by this object + /// adapter will contain. + /// + /// - returns: `EndpointSeq` - The set of published endpoints. + func getPublishedEndpoints() -> EndpointSeq + + /// Set of the endpoints that proxies created by this object + /// adapter will contain. + /// + /// - parameter _: `EndpointSeq` The new set of endpoints that the object adapter will embed in proxies. + func setPublishedEndpoints(_ newEndpoints: EndpointSeq) throws + + /// + /// - returns: `Dispatch.DispatchQueue` + func getDispatchQueue() throws -> Dispatch.DispatchQueue +} diff --git a/Sources/Ice/Ice_ObjectAdapterF.swift b/Sources/Ice/Ice_ObjectAdapterF.swift new file mode 100644 index 0000000..80f2153 --- /dev/null +++ b/Sources/Ice/Ice_ObjectAdapterF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapterF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_ObjectFactory.swift b/Sources/Ice/Ice_ObjectFactory.swift new file mode 100644 index 0000000..7458197 --- /dev/null +++ b/Sources/Ice/Ice_ObjectFactory.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Plugin.swift b/Sources/Ice/Ice_Plugin.swift new file mode 100644 index 0000000..dc3df09 --- /dev/null +++ b/Sources/Ice/Ice_Plugin.swift @@ -0,0 +1,77 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Plugin.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A communicator plug-in. A plug-in generally adds a feature to a +/// communicator, such as support for a protocol. +/// +/// The communicator loads its plug-ins in two stages: the first stage +/// creates the plug-ins, and the second stage invokes Plugin.initialize on +/// each one. +public protocol Plugin: Swift.AnyObject { + /// Perform any necessary initialization steps. + func initialize() throws + + /// Called when the communicator is being destroyed. + func destroy() throws +} + +/// Each communicator has a plug-in manager to administer the set of +/// plug-ins. +public protocol PluginManager: Swift.AnyObject { + /// Initialize the configured plug-ins. The communicator automatically initializes + /// the plug-ins by default, but an application may need to interact directly with + /// a plug-in prior to initialization. In this case, the application must set + /// Ice.InitPlugins=0 and then invoke initializePlugins + /// manually. The plug-ins are initialized in the order in which they are loaded. + /// If a plug-in raises an exception during initialization, the communicator + /// invokes destroy on the plug-ins that have already been initialized. + /// + /// - throws: + /// + /// - InitializationException - Raised if the plug-ins have already been initialized. + func initializePlugins() throws + + /// Get a list of plugins installed. + /// + /// - returns: `StringSeq` - The names of the plugins installed. + func getPlugins() -> StringSeq + + /// Obtain a plug-in by name. + /// + /// - parameter _: `Swift.String` The plug-in's name. + /// + /// - returns: `Plugin?` - The plug-in. + /// + /// - throws: + /// + /// - NotRegisteredException - Raised if no plug-in is found with the given name. + func getPlugin(_ name: Swift.String) throws -> Plugin? + + /// Install a new plug-in. + /// + /// - parameter name: `Swift.String` The plug-in's name. + /// + /// - parameter pi: `Plugin?` The plug-in. + /// + /// - throws: + /// + /// - AlreadyRegisteredException - Raised if a plug-in already exists with the given name. + func addPlugin(name: Swift.String, pi: Plugin?) throws + + /// Called when the communicator is being destroyed. + func destroy() +} diff --git a/Sources/Ice/Ice_PluginF.swift b/Sources/Ice/Ice_PluginF.swift new file mode 100644 index 0000000..6e69071 --- /dev/null +++ b/Sources/Ice/Ice_PluginF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PluginF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Process.swift b/Sources/Ice/Ice_Process.swift new file mode 100644 index 0000000..797b9ab --- /dev/null +++ b/Sources/Ice/Ice_Process.swift @@ -0,0 +1,305 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Process.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// Traits for Slice interface `Process`. +public struct ProcessTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::Ice::Process"] + public static let staticId = "::Ice::Process" +} + +/// An administrative interface for process management. Managed servers must +/// implement this interface. +/// +/// A servant implementing this interface is a potential target +/// for denial-of-service attacks, therefore proper security precautions +/// should be taken. For example, the servant can use a UUID to make its +/// identity harder to guess, and be registered in an object adapter with +/// a secured endpoint. +/// +/// ProcessPrx Methods: +/// +/// - shutdown: Initiate a graceful shut-down. +/// +/// - shutdownAsync: Initiate a graceful shut-down. +/// +/// - writeMessage: Write a message on the process' stdout or stderr. +/// +/// - writeMessageAsync: Write a message on the process' stdout or stderr. +public protocol ProcessPrx: ObjectPrx {} + +internal final class ProcessPrxI: ObjectPrxI, ProcessPrx { + public override class func ice_staticId() -> Swift.String { + return ProcessTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `ProcessPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `ProcessPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: ProcessPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> ProcessPrx? { + return try ProcessPrxI.checkedCast(prx: prx, facet: facet, context: context) as ProcessPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `ProcessPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `ProcessPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: ProcessPrx.Protocol, facet: Swift.String? = nil) -> ProcessPrx { + return ProcessPrxI.uncheckedCast(prx: prx, facet: facet) as ProcessPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `ProcessPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: ProcessPrx.Protocol) -> Swift.String { + return ProcessTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `ProcessPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `ProcessPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ProcessPrx?` - The extracted proxy + func read(_ type: ProcessPrx.Protocol) throws -> ProcessPrx? { + return try read() as ProcessPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `ProcessPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ProcessPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: ProcessPrx.Protocol) throws -> ProcessPrx? { + return try read(tag: tag) as ProcessPrxI? + } +} + +/// An administrative interface for process management. Managed servers must +/// implement this interface. +/// +/// A servant implementing this interface is a potential target +/// for denial-of-service attacks, therefore proper security precautions +/// should be taken. For example, the servant can use a UUID to make its +/// identity harder to guess, and be registered in an object adapter with +/// a secured endpoint. +/// +/// ProcessPrx Methods: +/// +/// - shutdown: Initiate a graceful shut-down. +/// +/// - shutdownAsync: Initiate a graceful shut-down. +/// +/// - writeMessage: Write a message on the process' stdout or stderr. +/// +/// - writeMessageAsync: Write a message on the process' stdout or stderr. +public extension ProcessPrx { + /// Initiate a graceful shut-down. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func shutdown(context: Context? = nil) throws { + try _impl._invoke(operation: "shutdown", + mode: .Normal, + context: context) + } + + /// Initiate a graceful shut-down. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func shutdownAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "shutdown", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Write a message on the process' stdout or stderr. + /// + /// - parameter message: `Swift.String` The message. + /// + /// - parameter fd: `Swift.Int32` 1 for stdout, 2 for stderr. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func writeMessage(message iceP_message: Swift.String, fd iceP_fd: Swift.Int32, context: Context? = nil) throws { + try _impl._invoke(operation: "writeMessage", + mode: .Normal, + write: { ostr in + ostr.write(iceP_message) + ostr.write(iceP_fd) + }, + context: context) + } + + /// Write a message on the process' stdout or stderr. + /// + /// - parameter message: `Swift.String` The message. + /// + /// - parameter fd: `Swift.Int32` 1 for stdout, 2 for stderr. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func writeMessageAsync(message iceP_message: Swift.String, fd iceP_fd: Swift.Int32, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "writeMessage", + mode: .Normal, + write: { ostr in + ostr.write(iceP_message) + ostr.write(iceP_fd) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Process` servants. +public struct ProcessDisp: Disp { + public let servant: Process + private static let defaultObject = ObjectI() + + public init(_ servant: Process) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? ProcessDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? ProcessDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? ProcessDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? ProcessDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "shutdown": + return try servant._iceD_shutdown(incoming: request, current: current) + case "writeMessage": + return try servant._iceD_writeMessage(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// An administrative interface for process management. Managed servers must +/// implement this interface. +/// +/// A servant implementing this interface is a potential target +/// for denial-of-service attacks, therefore proper security precautions +/// should be taken. For example, the servant can use a UUID to make its +/// identity harder to guess, and be registered in an object adapter with +/// a secured endpoint. +public protocol Process { + /// Initiate a graceful shut-down. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func shutdown(current: Current) throws + + /// Write a message on the process' stdout or stderr. + /// + /// - parameter message: `Swift.String` The message. + /// + /// - parameter fd: `Swift.Int32` 1 for stdout, 2 for stderr. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func writeMessage(message: Swift.String, fd: Swift.Int32, current: Current) throws +} + +/// An administrative interface for process management. Managed servers must +/// implement this interface. +/// +/// A servant implementing this interface is a potential target +/// for denial-of-service attacks, therefore proper security precautions +/// should be taken. For example, the servant can use a UUID to make its +/// identity harder to guess, and be registered in an object adapter with +/// a secured endpoint. +/// +/// Process Methods: +/// +/// - shutdown: Initiate a graceful shut-down. +/// +/// - writeMessage: Write a message on the process' stdout or stderr. +public extension Process { + func _iceD_shutdown(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.shutdown(current: current) + + return inS.setResult() + } + + func _iceD_writeMessage(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_message, iceP_fd): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_message: Swift.String = try istr.read() + let iceP_fd: Swift.Int32 = try istr.read() + return (iceP_message, iceP_fd) + } + + try self.writeMessage(message: iceP_message, fd: iceP_fd, current: current) + + return inS.setResult() + } +} diff --git a/Sources/Ice/Ice_ProcessF.swift b/Sources/Ice/Ice_ProcessF.swift new file mode 100644 index 0000000..170aeae --- /dev/null +++ b/Sources/Ice/Ice_ProcessF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ProcessF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_Properties.swift b/Sources/Ice/Ice_Properties.swift new file mode 100644 index 0000000..165775d --- /dev/null +++ b/Sources/Ice/Ice_Properties.swift @@ -0,0 +1,154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Properties.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A property set used to configure Ice and Ice applications. +/// Properties are key/value pairs, with both keys and values +/// being strings. By convention, property keys should have the form +/// application-name[.category[.sub-category]].name. +public protocol Properties: Swift.AnyObject { + /// Get a property by key. If the property is not set, an empty + /// string is returned. + /// + /// - parameter _: `Swift.String` The property key. + /// + /// - returns: `Swift.String` - The property value. + func getProperty(_ key: Swift.String) -> Swift.String + + /// Get a property by key. If the property is not set, the + /// given default value is returned. + /// + /// - parameter key: `Swift.String` The property key. + /// + /// - parameter value: `Swift.String` The default value to use if the property does not + /// exist. + /// + /// - returns: `Swift.String` - The property value or the default value. + func getPropertyWithDefault(key: Swift.String, value: Swift.String) -> Swift.String + + /// Get a property as an integer. If the property is not set, 0 + /// is returned. + /// + /// - parameter _: `Swift.String` The property key. + /// + /// - returns: `Swift.Int32` - The property value interpreted as an integer. + func getPropertyAsInt(_ key: Swift.String) -> Swift.Int32 + + /// Get a property as an integer. If the property is not set, the + /// given default value is returned. + /// + /// - parameter key: `Swift.String` The property key. + /// + /// - parameter value: `Swift.Int32` The default value to use if the property does not + /// exist. + /// + /// - returns: `Swift.Int32` - The property value interpreted as an integer, or the + /// default value. + func getPropertyAsIntWithDefault(key: Swift.String, value: Swift.Int32) -> Swift.Int32 + + /// Get a property as a list of strings. The strings must be + /// separated by whitespace or comma. If the property is not set, + /// an empty list is returned. The strings in the list can contain + /// whitespace and commas if they are enclosed in single or double + /// quotes. If quotes are mismatched, an empty list is returned. + /// Within single quotes or double quotes, you can escape the + /// quote in question with a backslash, e.g. O'Reilly can be written as + /// O'Reilly, "O'Reilly" or 'O\'Reilly'. + /// + /// - parameter _: `Swift.String` The property key. + /// + /// - returns: `StringSeq` - The property value interpreted as a list of strings. + func getPropertyAsList(_ key: Swift.String) -> StringSeq + + /// Get a property as a list of strings. The strings must be + /// separated by whitespace or comma. If the property is not set, + /// the default list is returned. The strings in the list can contain + /// whitespace and commas if they are enclosed in single or double + /// quotes. If quotes are mismatched, the default list is returned. + /// Within single quotes or double quotes, you can escape the + /// quote in question with a backslash, e.g. O'Reilly can be written as + /// O'Reilly, "O'Reilly" or 'O\'Reilly'. + /// + /// - parameter key: `Swift.String` The property key. + /// + /// - parameter value: `StringSeq` The default value to use if the property is not set. + /// + /// - returns: `StringSeq` - The property value interpreted as list of strings, or the + /// default value. + func getPropertyAsListWithDefault(key: Swift.String, value: StringSeq) -> StringSeq + + /// Get all properties whose keys begins with + /// prefix. If + /// prefix is an empty string, + /// then all properties are returned. + /// + /// - parameter _: `Swift.String` The prefix to search for (empty string if none). + /// + /// - returns: `PropertyDict` - The matching property set. + func getPropertiesForPrefix(_ prefix: Swift.String) -> PropertyDict + + /// Set a property. To unset a property, set it to + /// the empty string. + /// + /// - parameter key: `Swift.String` The property key. + /// + /// - parameter value: `Swift.String` The property value. + func setProperty(key: Swift.String, value: Swift.String) + + /// Get a sequence of command-line options that is equivalent to + /// this property set. Each element of the returned sequence is + /// a command-line option of the form + /// --key=value. + /// + /// - returns: `StringSeq` - The command line options for this property set. + func getCommandLineOptions() -> StringSeq + + /// Convert a sequence of command-line options into properties. + /// All options that begin with + /// --prefix. are + /// converted into properties. If the prefix is empty, all options + /// that begin with -- are converted to properties. + /// + /// - parameter prefix: `Swift.String` The property prefix, or an empty string to + /// convert all options starting with --. + /// + /// - parameter options: `StringSeq` The command-line options. + /// + /// - returns: `StringSeq` - The command-line options that do not start with the specified + /// prefix, in their original order. + func parseCommandLineOptions(prefix: Swift.String, options: StringSeq) throws -> StringSeq + + /// Convert a sequence of command-line options into properties. + /// All options that begin with one of the following prefixes + /// are converted into properties: --Ice, --IceBox, --IceGrid, + /// --IcePatch2, --IceSSL, --IceStorm, --Freeze, and --Glacier2. + /// + /// - parameter _: `StringSeq` The command-line options. + /// + /// - returns: `StringSeq` - The command-line options that do not start with one of + /// the listed prefixes, in their original order. + func parseIceCommandLineOptions(_ options: StringSeq) throws -> StringSeq + + /// Load properties from a file. + /// + /// - parameter _: `Swift.String` The property file. + func load(_ file: Swift.String) throws + + /// Create a copy of this property set. + /// + /// - returns: `Properties` - A copy of this property set. + func clone() -> Properties +} diff --git a/Sources/Ice/Ice_PropertiesAdmin.swift b/Sources/Ice/Ice_PropertiesAdmin.swift new file mode 100644 index 0000000..2003ae5 --- /dev/null +++ b/Sources/Ice/Ice_PropertiesAdmin.swift @@ -0,0 +1,476 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesAdmin.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// A simple collection of properties, represented as a dictionary of +/// key/value pairs. Both key and value are strings. +public typealias PropertyDict = [Swift.String: Swift.String] + +/// Helper class to read and write `PropertyDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct PropertyDictHelper { + /// Read a `PropertyDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `PropertyDict` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> PropertyDict { + let sz = try Swift.Int(istr.readSize()) + var v = PropertyDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `PropertyDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `PropertyDict` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> PropertyDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `PropertyDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `PropertyDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: PropertyDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `PropertyDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `PropertyDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: PropertyDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice interface `PropertiesAdmin`. +public struct PropertiesAdminTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::Ice::PropertiesAdmin"] + public static let staticId = "::Ice::PropertiesAdmin" +} + +/// The PropertiesAdmin interface provides remote access to the properties +/// of a communicator. +/// +/// PropertiesAdminPrx Methods: +/// +/// - getProperty: Get a property by key. +/// +/// - getPropertyAsync: Get a property by key. +/// +/// - getPropertiesForPrefix: Get all properties whose keys begin with prefix. +/// +/// - getPropertiesForPrefixAsync: Get all properties whose keys begin with prefix. +/// +/// - setProperties: Update the communicator's properties with the given property set. +/// +/// - setPropertiesAsync: Update the communicator's properties with the given property set. +public protocol PropertiesAdminPrx: ObjectPrx {} + +internal final class PropertiesAdminPrxI: ObjectPrxI, PropertiesAdminPrx { + public override class func ice_staticId() -> Swift.String { + return PropertiesAdminTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `PropertiesAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `PropertiesAdminPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: PropertiesAdminPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> PropertiesAdminPrx? { + return try PropertiesAdminPrxI.checkedCast(prx: prx, facet: facet, context: context) as PropertiesAdminPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `PropertiesAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `PropertiesAdminPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: PropertiesAdminPrx.Protocol, facet: Swift.String? = nil) -> PropertiesAdminPrx { + return PropertiesAdminPrxI.uncheckedCast(prx: prx, facet: facet) as PropertiesAdminPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `PropertiesAdminPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: PropertiesAdminPrx.Protocol) -> Swift.String { + return PropertiesAdminTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `PropertiesAdminPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `PropertiesAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `PropertiesAdminPrx?` - The extracted proxy + func read(_ type: PropertiesAdminPrx.Protocol) throws -> PropertiesAdminPrx? { + return try read() as PropertiesAdminPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `PropertiesAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `PropertiesAdminPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: PropertiesAdminPrx.Protocol) throws -> PropertiesAdminPrx? { + return try read(tag: tag) as PropertiesAdminPrxI? + } +} + +/// The PropertiesAdmin interface provides remote access to the properties +/// of a communicator. +/// +/// PropertiesAdminPrx Methods: +/// +/// - getProperty: Get a property by key. +/// +/// - getPropertyAsync: Get a property by key. +/// +/// - getPropertiesForPrefix: Get all properties whose keys begin with prefix. +/// +/// - getPropertiesForPrefixAsync: Get all properties whose keys begin with prefix. +/// +/// - setProperties: Update the communicator's properties with the given property set. +/// +/// - setPropertiesAsync: Update the communicator's properties with the given property set. +public extension PropertiesAdminPrx { + /// Get a property by key. If the property is not set, an empty + /// string is returned. + /// + /// - parameter _: `Swift.String` The property key. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The property value. + func getProperty(_ iceP_key: Swift.String, context: Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getProperty", + mode: .Normal, + write: { ostr in + ostr.write(iceP_key) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get a property by key. If the property is not set, an empty + /// string is returned. + /// + /// - parameter _: `Swift.String` The property key. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getPropertyAsync(_ iceP_key: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getProperty", + mode: .Normal, + write: { ostr in + ostr.write(iceP_key) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all properties whose keys begin with prefix. If + /// prefix is an empty string then all properties are returned. + /// + /// - parameter _: `Swift.String` The prefix to search for (empty string if none). + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `PropertyDict` - The matching property set. + func getPropertiesForPrefix(_ iceP_prefix: Swift.String, context: Context? = nil) throws -> PropertyDict { + return try _impl._invoke(operation: "getPropertiesForPrefix", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prefix) + }, + read: { istr in + let iceP_returnValue: PropertyDict = try PropertyDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Get all properties whose keys begin with prefix. If + /// prefix is an empty string then all properties are returned. + /// + /// - parameter _: `Swift.String` The prefix to search for (empty string if none). + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getPropertiesForPrefixAsync(_ iceP_prefix: Swift.String, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getPropertiesForPrefix", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prefix) + }, + read: { istr in + let iceP_returnValue: PropertyDict = try PropertyDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Update the communicator's properties with the given property set. + /// + /// - parameter _: `PropertyDict` Properties to be added, changed, or removed. + /// If an entry in newProperties matches the name of an existing property, + /// that property's value is replaced with the new value. If the new value + /// is an empty string, the property is removed. Any existing properties + /// that are not modified or removed by the entries in newProperties are + /// retained with their original values. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func setProperties(_ iceP_newProperties: PropertyDict, context: Context? = nil) throws { + try _impl._invoke(operation: "setProperties", + mode: .Normal, + write: { ostr in + PropertyDictHelper.write(to: ostr, value: iceP_newProperties) + }, + context: context) + } + + /// Update the communicator's properties with the given property set. + /// + /// - parameter _: `PropertyDict` Properties to be added, changed, or removed. + /// If an entry in newProperties matches the name of an existing property, + /// that property's value is replaced with the new value. If the new value + /// is an empty string, the property is removed. Any existing properties + /// that are not modified or removed by the entries in newProperties are + /// retained with their original values. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setPropertiesAsync(_ iceP_newProperties: PropertyDict, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setProperties", + mode: .Normal, + write: { ostr in + PropertyDictHelper.write(to: ostr, value: iceP_newProperties) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `PropertiesAdmin` servants. +public struct PropertiesAdminDisp: Disp { + public let servant: PropertiesAdmin + private static let defaultObject = ObjectI() + + public init(_ servant: PropertiesAdmin) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "getPropertiesForPrefix": + return try servant._iceD_getPropertiesForPrefix(incoming: request, current: current) + case "getProperty": + return try servant._iceD_getProperty(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? PropertiesAdminDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? PropertiesAdminDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? PropertiesAdminDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? PropertiesAdminDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "setProperties": + return try servant._iceD_setProperties(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The PropertiesAdmin interface provides remote access to the properties +/// of a communicator. +public protocol PropertiesAdmin { + /// Get a property by key. If the property is not set, an empty + /// string is returned. + /// + /// - parameter key: `Swift.String` The property key. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The property value. + func getProperty(key: Swift.String, current: Current) throws -> Swift.String + + /// Get all properties whose keys begin with prefix. If + /// prefix is an empty string then all properties are returned. + /// + /// - parameter prefix: `Swift.String` The prefix to search for (empty string if none). + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PropertyDict` - The matching property set. + func getPropertiesForPrefix(prefix: Swift.String, current: Current) throws -> PropertyDict + + /// Update the communicator's properties with the given property set. + /// + /// - parameter newProperties: `PropertyDict` Properties to be added, changed, or removed. + /// If an entry in newProperties matches the name of an existing property, + /// that property's value is replaced with the new value. If the new value + /// is an empty string, the property is removed. Any existing properties + /// that are not modified or removed by the entries in newProperties are + /// retained with their original values. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func setProperties(newProperties: PropertyDict, current: Current) throws +} + +/// The PropertiesAdmin interface provides remote access to the properties +/// of a communicator. +/// +/// PropertiesAdmin Methods: +/// +/// - getProperty: Get a property by key. +/// +/// - getPropertiesForPrefix: Get all properties whose keys begin with prefix. +/// +/// - setProperties: Update the communicator's properties with the given property set. +public extension PropertiesAdmin { + func _iceD_getProperty(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_key: Swift.String = try inS.read { istr in + let iceP_key: Swift.String = try istr.read() + return iceP_key + } + + let iceP_returnValue = try self.getProperty(key: iceP_key, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getPropertiesForPrefix(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_prefix: Swift.String = try inS.read { istr in + let iceP_prefix: Swift.String = try istr.read() + return iceP_prefix + } + + let iceP_returnValue = try self.getPropertiesForPrefix(prefix: iceP_prefix, current: current) + + return inS.setResult{ ostr in + PropertyDictHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_setProperties(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_newProperties: PropertyDict = try inS.read { istr in + let iceP_newProperties: PropertyDict = try PropertyDictHelper.read(from: istr) + return iceP_newProperties + } + + try self.setProperties(newProperties: iceP_newProperties, current: current) + + return inS.setResult() + } +} diff --git a/Sources/Ice/Ice_PropertiesF.swift b/Sources/Ice/Ice_PropertiesF.swift new file mode 100644 index 0000000..a473f55 --- /dev/null +++ b/Sources/Ice/Ice_PropertiesF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_RemoteLogger.swift b/Sources/Ice/Ice_RemoteLogger.swift new file mode 100644 index 0000000..360f2e4 --- /dev/null +++ b/Sources/Ice/Ice_RemoteLogger.swift @@ -0,0 +1,1087 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RemoteLogger.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// An enumeration representing the different types of log messages. +public enum LogMessageType: Swift.UInt8 { + /// PrintMessage The Logger received a print message. + case PrintMessage = 0 + /// TraceMessage The Logger received a trace message. + case TraceMessage = 1 + /// WarningMessage The Logger received a warning message. + case WarningMessage = 2 + /// ErrorMessage The Logger received an error message. + case ErrorMessage = 3 + public init() { + self = .PrintMessage + } +} + +/// An `Ice.InputStream` extension to read `LogMessageType` enumerated values from the stream. +public extension InputStream { + /// Read an enumerated value. + /// + /// - returns: `LogMessageType` - The enumarated value. + func read() throws -> LogMessageType { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 3) + guard let val = LogMessageType(rawValue: rawValue) else { + throw MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `LogMessageType` - The enumerated value. + func read(tag: Swift.Int32) throws -> LogMessageType? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as LogMessageType + } +} + +/// An `Ice.OutputStream` extension to write `LogMessageType` enumerated values to the stream. +public extension OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `LogMessageType` - The enumerator to write. + func write(_ v: LogMessageType) { + write(enum: v.rawValue, maxValue: 3) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `LogMessageType` - The enumerator to write. + func write(tag: Swift.Int32, value: LogMessageType?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 3) + } +} + +/// A sequence of LogMessageType +public typealias LogMessageTypeSeq = [LogMessageType] + +/// Helper class to read and write `LogMessageTypeSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct LogMessageTypeSeqHelper { + /// Read a `LogMessageTypeSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `LogMessageTypeSeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> LogMessageTypeSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 1) + var v = LogMessageTypeSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: LogMessageType = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `LogMessageTypeSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LogMessageTypeSeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> LogMessageTypeSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `LogMessageTypeSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `LogMessageTypeSeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: LogMessageTypeSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `LogMessageTypeSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LogMessageTypeSeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: LogMessageTypeSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A complete log message. +public struct LogMessage: Swift.Hashable { + /// The type of message sent to the Logger. + public var `type`: LogMessageType = .PrintMessage + /// The date and time when the Logger received this message, expressed + /// as the number of microseconds since the Unix Epoch (00:00:00 UTC on 1 January 1970) + public var timestamp: Swift.Int64 = 0 + /// For a message of type trace, the trace category of this log message; + /// otherwise, the empty string. + public var traceCategory: Swift.String = "" + /// The log message itself. + public var message: Swift.String = "" + + public init() {} + + public init(`type`: LogMessageType, timestamp: Swift.Int64, traceCategory: Swift.String, message: Swift.String) { + self.`type` = `type` + self.timestamp = timestamp + self.traceCategory = traceCategory + self.message = message + } +} + +/// An `Ice.InputStream` extension to read `LogMessage` structured values from the stream. +public extension InputStream { + /// Read a `LogMessage` structured value from the stream. + /// + /// - returns: `LogMessage` - The structured value read from the stream. + func read() throws -> LogMessage { + var v = LogMessage() + v.`type` = try self.read() + v.timestamp = try self.read() + v.traceCategory = try self.read() + v.message = try self.read() + return v + } + + /// Read an optional `LogMessage?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LogMessage?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> LogMessage? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as LogMessage + } +} + +/// An `Ice.OutputStream` extension to write `LogMessage` structured values from the stream. +public extension OutputStream { + /// Write a `LogMessage` structured value to the stream. + /// + /// - parameter _: `LogMessage` - The value to write to the stream. + func write(_ v: LogMessage) { + self.write(v.`type`) + self.write(v.timestamp) + self.write(v.traceCategory) + self.write(v.message) + } + + /// Write an optional `LogMessage?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LogMessage?` - The value to write to the stream. + func write(tag: Swift.Int32, value: LogMessage?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of LogMessage. +public typealias LogMessageSeq = [LogMessage] + +/// Helper class to read and write `LogMessageSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct LogMessageSeqHelper { + /// Read a `LogMessageSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `LogMessageSeq` - The sequence read from the stream. + public static func read(from istr: InputStream) throws -> LogMessageSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 11) + var v = LogMessageSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: LogMessage = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `LogMessageSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LogMessageSeq` - The sequence read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> LogMessageSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `LogMessageSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `LogMessageSeq` - The sequence value to write to the stream. + public static func write(to ostr: OutputStream, value v: LogMessageSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `LogMessageSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LogMessageSeq` The sequence value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: LogMessageSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice interface `RemoteLogger`. +public struct RemoteLoggerTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::Ice::RemoteLogger"] + public static let staticId = "::Ice::RemoteLogger" +} + +/// :nodoc: +public class RemoteLoggerAlreadyAttachedException_TypeResolver: UserExceptionTypeResolver { + public override func type() -> UserException.Type { + return RemoteLoggerAlreadyAttachedException.self + } +} + +public extension ClassResolver { + @objc static func Ice_RemoteLoggerAlreadyAttachedException() -> UserExceptionTypeResolver { + return RemoteLoggerAlreadyAttachedException_TypeResolver() + } +} + +/// Thrown when the provided RemoteLogger was previously attached to a LoggerAdmin. +open class RemoteLoggerAlreadyAttachedException: UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::Ice::RemoteLoggerAlreadyAttachedException" + } + + open override func _iceWriteImpl(to ostr: OutputStream) { + ostr.startSlice(typeId: RemoteLoggerAlreadyAttachedException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// Traits for Slice interface `LoggerAdmin`. +public struct LoggerAdminTraits: SliceTraits { + public static let staticIds = ["::Ice::LoggerAdmin", "::Ice::Object"] + public static let staticId = "::Ice::LoggerAdmin" +} + +/// The Ice remote logger interface. An application can implement a +/// RemoteLogger to receive the log messages sent to the local Logger +/// of another Ice application. +/// +/// RemoteLoggerPrx Methods: +/// +/// - `init`: init is called by attachRemoteLogger when a RemoteLogger proxy is attached. +/// +/// - initAsync: init is called by attachRemoteLogger when a RemoteLogger proxy is attached. +/// +/// - log: Log a LogMessage. +/// +/// - logAsync: Log a LogMessage. +public protocol RemoteLoggerPrx: ObjectPrx {} + +internal final class RemoteLoggerPrxI: ObjectPrxI, RemoteLoggerPrx { + public override class func ice_staticId() -> Swift.String { + return RemoteLoggerTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RemoteLoggerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RemoteLoggerPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: RemoteLoggerPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> RemoteLoggerPrx? { + return try RemoteLoggerPrxI.checkedCast(prx: prx, facet: facet, context: context) as RemoteLoggerPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RemoteLoggerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RemoteLoggerPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: RemoteLoggerPrx.Protocol, facet: Swift.String? = nil) -> RemoteLoggerPrx { + return RemoteLoggerPrxI.uncheckedCast(prx: prx, facet: facet) as RemoteLoggerPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RemoteLoggerPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RemoteLoggerPrx.Protocol) -> Swift.String { + return RemoteLoggerTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RemoteLoggerPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RemoteLoggerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RemoteLoggerPrx?` - The extracted proxy + func read(_ type: RemoteLoggerPrx.Protocol) throws -> RemoteLoggerPrx? { + return try read() as RemoteLoggerPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RemoteLoggerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RemoteLoggerPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RemoteLoggerPrx.Protocol) throws -> RemoteLoggerPrx? { + return try read(tag: tag) as RemoteLoggerPrxI? + } +} + +/// The Ice remote logger interface. An application can implement a +/// RemoteLogger to receive the log messages sent to the local Logger +/// of another Ice application. +/// +/// RemoteLoggerPrx Methods: +/// +/// - `init`: init is called by attachRemoteLogger when a RemoteLogger proxy is attached. +/// +/// - initAsync: init is called by attachRemoteLogger when a RemoteLogger proxy is attached. +/// +/// - log: Log a LogMessage. +/// +/// - logAsync: Log a LogMessage. +public extension RemoteLoggerPrx { + /// init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + /// + /// - parameter prefix: `Swift.String` The prefix of the associated local Logger. + /// + /// - parameter logMessages: `LogMessageSeq` Old log messages generated before "now". + /// + /// - parameter context: `Ice.Context` - Optional request context. + func `init`(prefix iceP_prefix: Swift.String, logMessages iceP_logMessages: LogMessageSeq, context: Context? = nil) throws { + try _impl._invoke(operation: "init", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prefix) + LogMessageSeqHelper.write(to: ostr, value: iceP_logMessages) + }, + context: context) + } + + /// init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + /// + /// - parameter prefix: `Swift.String` The prefix of the associated local Logger. + /// + /// - parameter logMessages: `LogMessageSeq` Old log messages generated before "now". + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func initAsync(prefix iceP_prefix: Swift.String, logMessages iceP_logMessages: LogMessageSeq, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "init", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prefix) + LogMessageSeqHelper.write(to: ostr, value: iceP_logMessages) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Log a LogMessage. Note that log may be called by LoggerAdmin before init. + /// + /// - parameter _: `LogMessage` The message to log. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func log(_ iceP_message: LogMessage, context: Context? = nil) throws { + try _impl._invoke(operation: "log", + mode: .Normal, + write: { ostr in + ostr.write(iceP_message) + }, + context: context) + } + + /// Log a LogMessage. Note that log may be called by LoggerAdmin before init. + /// + /// - parameter _: `LogMessage` The message to log. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func logAsync(_ iceP_message: LogMessage, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "log", + mode: .Normal, + write: { ostr in + ostr.write(iceP_message) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The interface of the admin object that allows an Ice application the attach its +/// RemoteLogger to the Logger of this admin object's Ice communicator. +/// +/// LoggerAdminPrx Methods: +/// +/// - attachRemoteLogger: Attaches a RemoteLogger object to the local logger. +/// +/// - attachRemoteLoggerAsync: Attaches a RemoteLogger object to the local logger. +/// +/// - detachRemoteLogger: Detaches a RemoteLogger object from the local logger. +/// +/// - detachRemoteLoggerAsync: Detaches a RemoteLogger object from the local logger. +/// +/// - getLog: Retrieves log messages recently logged. +/// +/// - getLogAsync: Retrieves log messages recently logged. +public protocol LoggerAdminPrx: ObjectPrx {} + +internal final class LoggerAdminPrxI: ObjectPrxI, LoggerAdminPrx { + public override class func ice_staticId() -> Swift.String { + return LoggerAdminTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `LoggerAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `LoggerAdminPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: LoggerAdminPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> LoggerAdminPrx? { + return try LoggerAdminPrxI.checkedCast(prx: prx, facet: facet, context: context) as LoggerAdminPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `LoggerAdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `LoggerAdminPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: LoggerAdminPrx.Protocol, facet: Swift.String? = nil) -> LoggerAdminPrx { + return LoggerAdminPrxI.uncheckedCast(prx: prx, facet: facet) as LoggerAdminPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `LoggerAdminPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: LoggerAdminPrx.Protocol) -> Swift.String { + return LoggerAdminTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `LoggerAdminPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `LoggerAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LoggerAdminPrx?` - The extracted proxy + func read(_ type: LoggerAdminPrx.Protocol) throws -> LoggerAdminPrx? { + return try read() as LoggerAdminPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `LoggerAdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LoggerAdminPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: LoggerAdminPrx.Protocol) throws -> LoggerAdminPrx? { + return try read(tag: tag) as LoggerAdminPrxI? + } +} + +/// The interface of the admin object that allows an Ice application the attach its +/// RemoteLogger to the Logger of this admin object's Ice communicator. +/// +/// LoggerAdminPrx Methods: +/// +/// - attachRemoteLogger: Attaches a RemoteLogger object to the local logger. +/// +/// - attachRemoteLoggerAsync: Attaches a RemoteLogger object to the local logger. +/// +/// - detachRemoteLogger: Detaches a RemoteLogger object from the local logger. +/// +/// - detachRemoteLoggerAsync: Detaches a RemoteLogger object from the local logger. +/// +/// - getLog: Retrieves log messages recently logged. +/// +/// - getLogAsync: Retrieves log messages recently logged. +public extension LoggerAdminPrx { + /// Attaches a RemoteLogger object to the local logger. + /// attachRemoteLogger calls init on the provided RemoteLogger proxy. + /// + /// - parameter prx: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the remote logger wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that the remote logger wishes to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be provided + /// to init. A negative value requests all messages available. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - RemoteLoggerAlreadyAttachedException - Raised if this remote logger is already + /// attached to this admin object. + func attachRemoteLogger(prx iceP_prx: RemoteLoggerPrx?, messageTypes iceP_messageTypes: LogMessageTypeSeq, traceCategories iceP_traceCategories: StringSeq, messageMax iceP_messageMax: Swift.Int32, context: Context? = nil) throws { + try _impl._invoke(operation: "attachRemoteLogger", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prx) + LogMessageTypeSeqHelper.write(to: ostr, value: iceP_messageTypes) + ostr.write(iceP_traceCategories) + ostr.write(iceP_messageMax) + }, + userException:{ ex in + do { + throw ex + } catch let error as RemoteLoggerAlreadyAttachedException { + throw error + } catch is UserException {} + }, + context: context) + } + + /// Attaches a RemoteLogger object to the local logger. + /// attachRemoteLogger calls init on the provided RemoteLogger proxy. + /// + /// - parameter prx: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the remote logger wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that the remote logger wishes to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be provided + /// to init. A negative value requests all messages available. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func attachRemoteLoggerAsync(prx iceP_prx: RemoteLoggerPrx?, messageTypes iceP_messageTypes: LogMessageTypeSeq, traceCategories iceP_traceCategories: StringSeq, messageMax iceP_messageMax: Swift.Int32, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "attachRemoteLogger", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prx) + LogMessageTypeSeqHelper.write(to: ostr, value: iceP_messageTypes) + ostr.write(iceP_traceCategories) + ostr.write(iceP_messageMax) + }, + userException:{ ex in + do { + throw ex + } catch let error as RemoteLoggerAlreadyAttachedException { + throw error + } catch is UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Detaches a RemoteLogger object from the local logger. + /// + /// - parameter _: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Bool` - True if the provided remote logger proxy was detached, and false otherwise. + func detachRemoteLogger(_ iceP_prx: RemoteLoggerPrx?, context: Context? = nil) throws -> Swift.Bool { + return try _impl._invoke(operation: "detachRemoteLogger", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prx) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Detaches a RemoteLogger object from the local logger. + /// + /// - parameter _: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func detachRemoteLoggerAsync(_ iceP_prx: RemoteLoggerPrx?, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "detachRemoteLogger", + mode: .Normal, + write: { ostr in + ostr.write(iceP_prx) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Retrieves log messages recently logged. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the caller wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that caller wish to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be returned. + /// A negative value requests all messages available. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: LogMessageSeq, prefix: Swift.String)`: + /// + /// - returnValue: `LogMessageSeq` - The Log messages. + /// + /// - prefix: `Swift.String` - The prefix of the associated local logger. + func getLog(messageTypes iceP_messageTypes: LogMessageTypeSeq, traceCategories iceP_traceCategories: StringSeq, messageMax iceP_messageMax: Swift.Int32, context: Context? = nil) throws -> (returnValue: LogMessageSeq, prefix: Swift.String) { + return try _impl._invoke(operation: "getLog", + mode: .Normal, + write: { ostr in + LogMessageTypeSeqHelper.write(to: ostr, value: iceP_messageTypes) + ostr.write(iceP_traceCategories) + ostr.write(iceP_messageMax) + }, + read: { istr in + let iceP_prefix: Swift.String = try istr.read() + let iceP_returnValue: LogMessageSeq = try LogMessageSeqHelper.read(from: istr) + return (iceP_returnValue, iceP_prefix) + }, + context: context) + } + + /// Retrieves log messages recently logged. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the caller wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that caller wish to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be returned. + /// A negative value requests all messages available. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: LogMessageSeq, prefix: Swift.String)>` - The result of the operation + func getLogAsync(messageTypes iceP_messageTypes: LogMessageTypeSeq, traceCategories iceP_traceCategories: StringSeq, messageMax iceP_messageMax: Swift.Int32, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: LogMessageSeq, prefix: Swift.String)> { + return _impl._invokeAsync(operation: "getLog", + mode: .Normal, + write: { ostr in + LogMessageTypeSeqHelper.write(to: ostr, value: iceP_messageTypes) + ostr.write(iceP_traceCategories) + ostr.write(iceP_messageMax) + }, + read: { istr in + let iceP_prefix: Swift.String = try istr.read() + let iceP_returnValue: LogMessageSeq = try LogMessageSeqHelper.read(from: istr) + return (iceP_returnValue, iceP_prefix) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `RemoteLogger` servants. +public struct RemoteLoggerDisp: Disp { + public let servant: RemoteLogger + private static let defaultObject = ObjectI() + + public init(_ servant: RemoteLogger) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? RemoteLoggerDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RemoteLoggerDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RemoteLoggerDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RemoteLoggerDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "init": + return try servant._iceD_init(incoming: request, current: current) + case "log": + return try servant._iceD_log(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Ice remote logger interface. An application can implement a +/// RemoteLogger to receive the log messages sent to the local Logger +/// of another Ice application. +public protocol RemoteLogger { + /// init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + /// + /// - parameter prefix: `Swift.String` The prefix of the associated local Logger. + /// + /// - parameter logMessages: `LogMessageSeq` Old log messages generated before "now". + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func `init`(prefix: Swift.String, logMessages: LogMessageSeq, current: Current) throws + + /// Log a LogMessage. Note that log may be called by LoggerAdmin before init. + /// + /// - parameter message: `LogMessage` The message to log. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func log(message: LogMessage, current: Current) throws +} + + +/// Dispatcher for `LoggerAdmin` servants. +public struct LoggerAdminDisp: Disp { + public let servant: LoggerAdmin + private static let defaultObject = ObjectI() + + public init(_ servant: LoggerAdmin) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "attachRemoteLogger": + return try servant._iceD_attachRemoteLogger(incoming: request, current: current) + case "detachRemoteLogger": + return try servant._iceD_detachRemoteLogger(incoming: request, current: current) + case "getLog": + return try servant._iceD_getLog(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? LoggerAdminDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? LoggerAdminDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? LoggerAdminDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? LoggerAdminDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The interface of the admin object that allows an Ice application the attach its +/// RemoteLogger to the Logger of this admin object's Ice communicator. +public protocol LoggerAdmin { + /// Attaches a RemoteLogger object to the local logger. + /// attachRemoteLogger calls init on the provided RemoteLogger proxy. + /// + /// - parameter prx: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the remote logger wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that the remote logger wishes to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be provided + /// to init. A negative value requests all messages available. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - RemoteLoggerAlreadyAttachedException - Raised if this remote logger is already + /// attached to this admin object. + func attachRemoteLogger(prx: RemoteLoggerPrx?, messageTypes: LogMessageTypeSeq, traceCategories: StringSeq, messageMax: Swift.Int32, current: Current) throws + + /// Detaches a RemoteLogger object from the local logger. + /// + /// - parameter prx: `RemoteLoggerPrx?` A proxy to the remote logger. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Bool` - True if the provided remote logger proxy was detached, and false otherwise. + func detachRemoteLogger(prx: RemoteLoggerPrx?, current: Current) throws -> Swift.Bool + + /// Retrieves log messages recently logged. + /// + /// - parameter messageTypes: `LogMessageTypeSeq` The list of message types that the caller wishes to receive. + /// An empty list means no filtering (send all message types). + /// + /// - parameter traceCategories: `StringSeq` The categories of traces that caller wish to receive. + /// This parameter is ignored if messageTypes is not empty and does not include trace. + /// An empty list means no filtering (send all trace categories). + /// + /// - parameter messageMax: `Swift.Int32` The maximum number of log messages (of all types) to be returned. + /// A negative value requests all messages available. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: LogMessageSeq, prefix: Swift.String)`: + /// + /// - returnValue: `LogMessageSeq` - The Log messages. + /// + /// - prefix: `Swift.String` - The prefix of the associated local logger. + func getLog(messageTypes: LogMessageTypeSeq, traceCategories: StringSeq, messageMax: Swift.Int32, current: Current) throws -> (returnValue: LogMessageSeq, prefix: Swift.String) +} + +/// The Ice remote logger interface. An application can implement a +/// RemoteLogger to receive the log messages sent to the local Logger +/// of another Ice application. +/// +/// RemoteLogger Methods: +/// +/// - `init`: init is called by attachRemoteLogger when a RemoteLogger proxy is attached. +/// +/// - log: Log a LogMessage. +public extension RemoteLogger { + func _iceD_init(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_prefix, iceP_logMessages): (Swift.String, LogMessageSeq) = try inS.read { istr in + let iceP_prefix: Swift.String = try istr.read() + let iceP_logMessages: LogMessageSeq = try LogMessageSeqHelper.read(from: istr) + return (iceP_prefix, iceP_logMessages) + } + + try self.`init`(prefix: iceP_prefix, logMessages: iceP_logMessages, current: current) + + return inS.setResult() + } + + func _iceD_log(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_message: LogMessage = try inS.read { istr in + let iceP_message: LogMessage = try istr.read() + return iceP_message + } + + try self.log(message: iceP_message, current: current) + + return inS.setResult() + } +} + +/// The interface of the admin object that allows an Ice application the attach its +/// RemoteLogger to the Logger of this admin object's Ice communicator. +/// +/// LoggerAdmin Methods: +/// +/// - attachRemoteLogger: Attaches a RemoteLogger object to the local logger. +/// +/// - detachRemoteLogger: Detaches a RemoteLogger object from the local logger. +/// +/// - getLog: Retrieves log messages recently logged. +public extension LoggerAdmin { + func _iceD_attachRemoteLogger(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_prx, iceP_messageTypes, iceP_traceCategories, iceP_messageMax): (RemoteLoggerPrx?, LogMessageTypeSeq, StringSeq, Swift.Int32) = try inS.read { istr in + let iceP_prx: RemoteLoggerPrx? = try istr.read(RemoteLoggerPrx.self) + let iceP_messageTypes: LogMessageTypeSeq = try LogMessageTypeSeqHelper.read(from: istr) + let iceP_traceCategories: StringSeq = try istr.read() + let iceP_messageMax: Swift.Int32 = try istr.read() + return (iceP_prx, iceP_messageTypes, iceP_traceCategories, iceP_messageMax) + } + + try self.attachRemoteLogger(prx: iceP_prx, messageTypes: iceP_messageTypes, traceCategories: iceP_traceCategories, messageMax: iceP_messageMax, current: current) + + return inS.setResult() + } + + func _iceD_detachRemoteLogger(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_prx: RemoteLoggerPrx? = try inS.read { istr in + let iceP_prx: RemoteLoggerPrx? = try istr.read(RemoteLoggerPrx.self) + return iceP_prx + } + + let iceP_returnValue = try self.detachRemoteLogger(prx: iceP_prx, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getLog(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let (iceP_messageTypes, iceP_traceCategories, iceP_messageMax): (LogMessageTypeSeq, StringSeq, Swift.Int32) = try inS.read { istr in + let iceP_messageTypes: LogMessageTypeSeq = try LogMessageTypeSeqHelper.read(from: istr) + let iceP_traceCategories: StringSeq = try istr.read() + let iceP_messageMax: Swift.Int32 = try istr.read() + return (iceP_messageTypes, iceP_traceCategories, iceP_messageMax) + } + + let (iceP_returnValue, iceP_prefix) = try self.getLog(messageTypes: iceP_messageTypes, traceCategories: iceP_traceCategories, messageMax: iceP_messageMax, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_prefix) + LogMessageSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } +} diff --git a/Sources/Ice/Ice_Router.swift b/Sources/Ice/Ice_Router.swift new file mode 100644 index 0000000..68af180 --- /dev/null +++ b/Sources/Ice/Ice_Router.swift @@ -0,0 +1,621 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Router.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import PromiseKit + +/// Traits for Slice interface `Router`. +public struct RouterTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::Ice::Router"] + public static let staticId = "::Ice::Router" +} + +/// Traits for Slice interface `RouterFinder`. +public struct RouterFinderTraits: SliceTraits { + public static let staticIds = ["::Ice::Object", "::Ice::RouterFinder"] + public static let staticId = "::Ice::RouterFinder" +} + +/// The Ice router interface. Routers can be set either globally with +/// Communicator.setDefaultRouter, or with ice_router on specific +/// proxies. +/// +/// RouterPrx Methods: +/// +/// - getClientProxy: Get the router's client proxy, i.e., the proxy to use for forwarding requests from the client to the router. +/// +/// - getClientProxyAsync: Get the router's client proxy, i.e., the proxy to use for forwarding requests from the client to the router. +/// +/// - getServerProxy: Get the router's server proxy, i.e., the proxy to use for forwarding requests from the server to the router. +/// +/// - getServerProxyAsync: Get the router's server proxy, i.e., the proxy to use for forwarding requests from the server to the router. +/// +/// - addProxies: Add new proxy information to the router's routing table. +/// +/// - addProxiesAsync: Add new proxy information to the router's routing table. +public protocol RouterPrx: ObjectPrx {} + +internal final class RouterPrxI: ObjectPrxI, RouterPrx { + public override class func ice_staticId() -> Swift.String { + return RouterTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RouterPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RouterPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: RouterPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> RouterPrx? { + return try RouterPrxI.checkedCast(prx: prx, facet: facet, context: context) as RouterPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RouterPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RouterPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: RouterPrx.Protocol, facet: Swift.String? = nil) -> RouterPrx { + return RouterPrxI.uncheckedCast(prx: prx, facet: facet) as RouterPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RouterPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RouterPrx.Protocol) -> Swift.String { + return RouterTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RouterPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RouterPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterPrx?` - The extracted proxy + func read(_ type: RouterPrx.Protocol) throws -> RouterPrx? { + return try read() as RouterPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RouterPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RouterPrx.Protocol) throws -> RouterPrx? { + return try read(tag: tag) as RouterPrxI? + } +} + +/// The Ice router interface. Routers can be set either globally with +/// Communicator.setDefaultRouter, or with ice_router on specific +/// proxies. +/// +/// RouterPrx Methods: +/// +/// - getClientProxy: Get the router's client proxy, i.e., the proxy to use for forwarding requests from the client to the router. +/// +/// - getClientProxyAsync: Get the router's client proxy, i.e., the proxy to use for forwarding requests from the client to the router. +/// +/// - getServerProxy: Get the router's server proxy, i.e., the proxy to use for forwarding requests from the server to the router. +/// +/// - getServerProxyAsync: Get the router's server proxy, i.e., the proxy to use for forwarding requests from the server to the router. +/// +/// - addProxies: Add new proxy information to the router's routing table. +/// +/// - addProxiesAsync: Add new proxy information to the router's routing table. +public extension RouterPrx { + /// Get the router's client proxy, i.e., the proxy to use for + /// forwarding requests from the client to the router. + /// + /// If a null proxy is returned, the client will forward requests + /// to the router's endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?)`: + /// + /// - returnValue: `ObjectPrx?` - The router's client proxy. + /// + /// - hasRoutingTable: `Swift.Bool?` - Indicates whether or not the router supports a routing + /// table. If it is supported, the Ice runtime will call addProxies to populate the + /// routing table. This out parameter is only supported starting with Ice 3.7. + /// The Ice runtime assumes the router has a routing table if the optional is not + /// set. + func getClientProxy(context: Context? = nil) throws -> (returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?) { + return try _impl._invoke(operation: "getClientProxy", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + let iceP_hasRoutingTable: Swift.Bool? = try istr.read(tag: 1) + return (iceP_returnValue, iceP_hasRoutingTable) + }, + context: context) + } + + /// Get the router's client proxy, i.e., the proxy to use for + /// forwarding requests from the client to the router. + /// + /// If a null proxy is returned, the client will forward requests + /// to the router's endpoints. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?)>` - The result of the operation + func getClientProxyAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?)> { + return _impl._invokeAsync(operation: "getClientProxy", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + let iceP_hasRoutingTable: Swift.Bool? = try istr.read(tag: 1) + return (iceP_returnValue, iceP_hasRoutingTable) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the router's server proxy, i.e., the proxy to use for + /// forwarding requests from the server to the router. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectPrx?` - The router's server proxy. + func getServerProxy(context: Context? = nil) throws -> ObjectPrx? { + return try _impl._invoke(operation: "getServerProxy", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the router's server proxy, i.e., the proxy to use for + /// forwarding requests from the server to the router. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerProxyAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerProxy", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ObjectPrx? = try istr.read(ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Add new proxy information to the router's routing table. + /// + /// - parameter _: `ObjectProxySeq` The proxies to add. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectProxySeq` - Proxies discarded by the router. + func addProxies(_ iceP_proxies: ObjectProxySeq, context: Context? = nil) throws -> ObjectProxySeq { + return try _impl._invoke(operation: "addProxies", + mode: .Idempotent, + write: { ostr in + ObjectProxySeqHelper.write(to: ostr, value: iceP_proxies) + }, + read: { istr in + let iceP_returnValue: ObjectProxySeq = try ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Add new proxy information to the router's routing table. + /// + /// - parameter _: `ObjectProxySeq` The proxies to add. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func addProxiesAsync(_ iceP_proxies: ObjectProxySeq, context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "addProxies", + mode: .Idempotent, + write: { ostr in + ObjectProxySeqHelper.write(to: ostr, value: iceP_proxies) + }, + read: { istr in + let iceP_returnValue: ObjectProxySeq = try ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Router interface. It should be advertised through an Ice +/// object with the identity `Ice/RouterFinder'. This allows clients to +/// retrieve the router proxy with just the endpoint information of the +/// service. +/// +/// RouterFinderPrx Methods: +/// +/// - getRouter: Get the router proxy implemented by the process hosting this finder object. +/// +/// - getRouterAsync: Get the router proxy implemented by the process hosting this finder object. +public protocol RouterFinderPrx: ObjectPrx {} + +internal final class RouterFinderPrxI: ObjectPrxI, RouterFinderPrx { + public override class func ice_staticId() -> Swift.String { + return RouterFinderTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RouterFinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RouterFinderPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: ObjectPrx, type: RouterFinderPrx.Protocol, facet: Swift.String? = nil, context: Context? = nil) throws -> RouterFinderPrx? { + return try RouterFinderPrxI.checkedCast(prx: prx, facet: facet, context: context) as RouterFinderPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RouterFinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RouterFinderPrx` - A proxy with the requested type +public func uncheckedCast(prx: ObjectPrx, type: RouterFinderPrx.Protocol, facet: Swift.String? = nil) -> RouterFinderPrx { + return RouterFinderPrxI.uncheckedCast(prx: prx, facet: facet) as RouterFinderPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RouterFinderPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RouterFinderPrx.Protocol) -> Swift.String { + return RouterFinderTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RouterFinderPrx`. +public extension InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RouterFinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterFinderPrx?` - The extracted proxy + func read(_ type: RouterFinderPrx.Protocol) throws -> RouterFinderPrx? { + return try read() as RouterFinderPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RouterFinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RouterFinderPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RouterFinderPrx.Protocol) throws -> RouterFinderPrx? { + return try read(tag: tag) as RouterFinderPrxI? + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Router interface. It should be advertised through an Ice +/// object with the identity `Ice/RouterFinder'. This allows clients to +/// retrieve the router proxy with just the endpoint information of the +/// service. +/// +/// RouterFinderPrx Methods: +/// +/// - getRouter: Get the router proxy implemented by the process hosting this finder object. +/// +/// - getRouterAsync: Get the router proxy implemented by the process hosting this finder object. +public extension RouterFinderPrx { + /// Get the router proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `RouterPrx?` - The router proxy. + func getRouter(context: Context? = nil) throws -> RouterPrx? { + return try _impl._invoke(operation: "getRouter", + mode: .Normal, + read: { istr in + let iceP_returnValue: RouterPrx? = try istr.read(RouterPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the router proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getRouterAsync(context: Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getRouter", + mode: .Normal, + read: { istr in + let iceP_returnValue: RouterPrx? = try istr.read(RouterPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Router` servants. +public struct RouterDisp: Disp { + public let servant: Router + private static let defaultObject = ObjectI() + + public init(_ servant: Router) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "addProxies": + return try servant._iceD_addProxies(incoming: request, current: current) + case "getClientProxy": + return try servant._iceD_getClientProxy(incoming: request, current: current) + case "getServerProxy": + return try servant._iceD_getServerProxy(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RouterDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The Ice router interface. Routers can be set either globally with +/// Communicator.setDefaultRouter, or with ice_router on specific +/// proxies. +public protocol Router { + /// Get the router's client proxy, i.e., the proxy to use for + /// forwarding requests from the client to the router. + /// + /// If a null proxy is returned, the client will forward requests + /// to the router's endpoints. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?)`: + /// + /// - returnValue: `ObjectPrx?` - The router's client proxy. + /// + /// - hasRoutingTable: `Swift.Bool?` - Indicates whether or not the router supports a routing + /// table. If it is supported, the Ice runtime will call addProxies to populate the + /// routing table. This out parameter is only supported starting with Ice 3.7. + /// The Ice runtime assumes the router has a routing table if the optional is not + /// set. + func getClientProxy(current: Current) throws -> (returnValue: ObjectPrx?, hasRoutingTable: Swift.Bool?) + + /// Get the router's server proxy, i.e., the proxy to use for + /// forwarding requests from the server to the router. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ObjectPrx?` - The router's server proxy. + func getServerProxy(current: Current) throws -> ObjectPrx? + + /// Add new proxy information to the router's routing table. + /// + /// - parameter proxies: `ObjectProxySeq` The proxies to add. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ObjectProxySeq` - Proxies discarded by the router. + func addProxies(proxies: ObjectProxySeq, current: Current) throws -> ObjectProxySeq +} + + +/// Dispatcher for `RouterFinder` servants. +public struct RouterFinderDisp: Disp { + public let servant: RouterFinder + private static let defaultObject = ObjectI() + + public init(_ servant: RouterFinder) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "getRouter": + return try servant._iceD_getRouter(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? RouterFinderDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RouterFinderDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RouterFinderDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RouterFinderDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Router interface. It should be advertised through an Ice +/// object with the identity `Ice/RouterFinder'. This allows clients to +/// retrieve the router proxy with just the endpoint information of the +/// service. +public protocol RouterFinder { + /// Get the router proxy implemented by the process hosting this + /// finder object. The proxy might point to several replicas. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `RouterPrx?` - The router proxy. + func getRouter(current: Current) throws -> RouterPrx? +} + +/// The Ice router interface. Routers can be set either globally with +/// Communicator.setDefaultRouter, or with ice_router on specific +/// proxies. +/// +/// Router Methods: +/// +/// - getClientProxy: Get the router's client proxy, i.e., the proxy to use for forwarding requests from the client to the router. +/// +/// - getServerProxy: Get the router's server proxy, i.e., the proxy to use for forwarding requests from the server to the router. +/// +/// - addProxies: Add new proxy information to the router's routing table. +public extension Router { + func _iceD_getClientProxy(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let (iceP_returnValue, iceP_hasRoutingTable) = try self.getClientProxy(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + ostr.write(tag: 1, value: iceP_hasRoutingTable) + } + } + + func _iceD_getServerProxy(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getServerProxy(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_addProxies(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + let iceP_proxies: ObjectProxySeq = try inS.read { istr in + let iceP_proxies: ObjectProxySeq = try ObjectProxySeqHelper.read(from: istr) + return iceP_proxies + } + + let iceP_returnValue = try self.addProxies(proxies: iceP_proxies, current: current) + + return inS.setResult{ ostr in + ObjectProxySeqHelper.write(to: ostr, value: iceP_returnValue) + } + } +} + +/// This inferface should be implemented by services implementing the +/// Ice::Router interface. It should be advertised through an Ice +/// object with the identity `Ice/RouterFinder'. This allows clients to +/// retrieve the router proxy with just the endpoint information of the +/// service. +/// +/// RouterFinder Methods: +/// +/// - getRouter: Get the router proxy implemented by the process hosting this finder object. +public extension RouterFinder { + func _iceD_getRouter(incoming inS: Incoming, current: Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getRouter(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/Ice/Ice_RouterF.swift b/Sources/Ice/Ice_RouterF.swift new file mode 100644 index 0000000..c0a7003 --- /dev/null +++ b/Sources/Ice/Ice_RouterF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RouterF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_ServantLocator.swift b/Sources/Ice/Ice_ServantLocator.swift new file mode 100644 index 0000000..f39afa2 --- /dev/null +++ b/Sources/Ice/Ice_ServantLocator.swift @@ -0,0 +1,91 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocator.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A servant locator is called by an object adapter to +/// locate a servant that is not found in its active servant map. +public protocol ServantLocator: Swift.AnyObject { + /// Called before a request is dispatched if a + /// servant cannot be found in the object adapter's active servant + /// map. Note that the object adapter does not automatically insert + /// the returned servant into its active servant map. This must be + /// done by the servant locator implementation, if this is desired. + /// + /// locate can throw any user exception. If it does, that exception + /// is marshaled back to the client. If the Slice definition for the + /// corresponding operation includes that user exception, the client + /// receives that user exception; otherwise, the client receives + /// UnknownUserException. + /// + /// If locate throws any exception, the Ice run time does not + /// call finished. + /// + /// If you call locate from your own code, you + /// must also call finished when you have finished using the + /// servant, provided that locate returned a non-null servant; + /// otherwise, you will get undefined behavior if you use + /// servant locators such as the Freeze Evictor. + /// + /// - parameter _: `Current` Information about the current operation for which + /// a servant is required. + /// + /// - returns: `(returnValue: Disp?, cookie: Swift.AnyObject?)`: + /// + /// - returnValue: `Disp?` - The located servant, or null if no suitable servant has + /// been found. + /// + /// - cookie: `Swift.AnyObject?` - A "cookie" that will be passed to finished. + /// + /// - throws: + /// + /// - UserException - The implementation can raise a UserException + /// and the run time will marshal it as the result of the invocation. + func locate(_ curr: Current) throws -> (returnValue: Disp?, cookie: Swift.AnyObject?) + + /// Called by the object adapter after a request has been + /// made. This operation is only called if locate was called + /// prior to the request and returned a non-null servant. This + /// operation can be used for cleanup purposes after a request. + /// + /// finished can throw any user exception. If it does, that exception + /// is marshaled back to the client. If the Slice definition for the + /// corresponding operation includes that user exception, the client + /// receives that user exception; otherwise, the client receives + /// UnknownUserException. + /// + /// If both the operation and finished throw an exception, the + /// exception thrown by finished is marshaled back to the client. + /// + /// - parameter curr: `Current` Information about the current operation call for + /// which a servant was located by locate. + /// + /// - parameter servant: `Disp` The servant that was returned by locate. + /// + /// - parameter cookie: `Swift.AnyObject?` The cookie that was returned by locate. + /// + /// - throws: + /// + /// - UserException - The implementation can raise a UserException + /// and the run time will marshal it as the result of the invocation. + func finished(curr: Current, servant: Disp, cookie: Swift.AnyObject?) throws + + /// Called when the object adapter in which this servant locator is + /// installed is destroyed. + /// + /// - parameter _: `Swift.String` Indicates for which category the servant locator + /// is being deactivated. + func deactivate(_ category: Swift.String) +} diff --git a/Sources/Ice/Ice_ServantLocatorF.swift b/Sources/Ice/Ice_ServantLocatorF.swift new file mode 100644 index 0000000..3e06eb0 --- /dev/null +++ b/Sources/Ice/Ice_ServantLocatorF.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation diff --git a/Sources/Ice/Ice_SliceChecksumDict.swift b/Sources/Ice/Ice_SliceChecksumDict.swift new file mode 100644 index 0000000..93c0d75 --- /dev/null +++ b/Sources/Ice/Ice_SliceChecksumDict.swift @@ -0,0 +1,86 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `SliceChecksumDict.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A mapping from type IDs to Slice checksums. The dictionary +/// allows verification at run time that client and server +/// use matching Slice definitions. +public typealias SliceChecksumDict = [Swift.String: Swift.String] + +/// Helper class to read and write `SliceChecksumDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct SliceChecksumDictHelper { + /// Read a `SliceChecksumDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `SliceChecksumDict` - The dictionary read from the stream. + public static func read(from istr: InputStream) throws -> SliceChecksumDict { + let sz = try Swift.Int(istr.readSize()) + var v = SliceChecksumDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `SliceChecksumDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `SliceChecksumDict` - The dictionary read from the stream. + public static func read(from istr: InputStream, tag: Swift.Int32) throws -> SliceChecksumDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `SliceChecksumDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `SliceChecksumDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, value v: SliceChecksumDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `SliceChecksumDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `SliceChecksumDict` - The dictionary value to write to the stream. + public static func write(to ostr: OutputStream, tag: Swift.Int32, value v: SliceChecksumDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} diff --git a/Sources/Ice/Ice_ValueFactory.swift b/Sources/Ice/Ice_ValueFactory.swift new file mode 100644 index 0000000..d99b907 --- /dev/null +++ b/Sources/Ice/Ice_ValueFactory.swift @@ -0,0 +1,89 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ValueFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A factory for values. Value factories are used in several +/// places, such as when Ice receives a class instance and +/// when Freeze restores a persistent value. Value factories +/// must be implemented by the application writer and registered +/// with the communicator. +/// +/// Create a new value for a given value type. The type is the +/// absolute Slice type id, i.e., the id relative to the +/// unnamed top-level Slice module. For example, the absolute +/// Slice type id for an interface Bar in the module +/// Foo is "::Foo::Bar". +/// +/// Note that the leading "::" is required. +/// +/// - parameter _: `Swift.String` The value type. +/// +/// - returns: `Value?` - The value created for the given type, or nil if the +/// factory is unable to create the value. +public typealias ValueFactory = (Swift.String) -> Value? + +/// A value factory manager maintains a collection of value factories. +/// An application can supply a custom implementation during communicator +/// initialization, otherwise Ice provides a default implementation. +public protocol ValueFactoryManager: Swift.AnyObject { + /// Add a value factory. Attempting to add a factory with an id for + /// which a factory is already registered throws AlreadyRegisteredException. + /// + /// When unmarshaling an Ice value, the Ice run time reads the + /// most-derived type id off the wire and attempts to create an + /// instance of the type using a factory. If no instance is created, + /// either because no factory was found, or because all factories + /// returned nil, the behavior of the Ice run time depends on the + /// format with which the value was marshaled: + /// + /// If the value uses the "sliced" format, Ice ascends the class + /// hierarchy until it finds a type that is recognized by a factory, + /// or it reaches the least-derived type. If no factory is found that + /// can create an instance, the run time throws NoValueFactoryException. + /// + /// If the value uses the "compact" format, Ice immediately raises + /// NoValueFactoryException. + /// + /// The following order is used to locate a factory for a type: + /// + /// + /// + /// The Ice run-time looks for a factory registered + /// specifically for the type. + /// + /// If no instance has been created, the Ice run-time looks + /// for the default factory, which is registered with an empty type id. + /// + /// + /// If no instance has been created by any of the preceding + /// steps, the Ice run-time looks for a factory that may have been + /// statically generated by the language mapping for non-abstract classes. + /// + /// - parameter factory: `@escaping ValueFactory` The factory to add. + /// + /// - parameter id: `Swift.String` The type id for which the factory can create instances, or + /// an empty string for the default factory. + func add(factory: @escaping ValueFactory, id: Swift.String) throws + + /// Find an value factory registered with this communicator. + /// + /// - parameter _: `Swift.String` The type id for which the factory can create instances, + /// or an empty string for the default factory. + /// + /// - returns: `ValueFactory?` - The value factory, or null if no value factory was + /// found for the given id. + func find(_ id: Swift.String) -> ValueFactory? +} diff --git a/Sources/Ice/Ice_Version.swift b/Sources/Ice/Ice_Version.swift new file mode 100644 index 0000000..41430c5 --- /dev/null +++ b/Sources/Ice/Ice_Version.swift @@ -0,0 +1,144 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Version.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation + +/// A version structure for the protocol version. +public struct ProtocolVersion: Swift.Hashable { + public var major: Swift.UInt8 = 0 + public var minor: Swift.UInt8 = 0 + + public init() {} + + public init(major: Swift.UInt8, minor: Swift.UInt8) { + self.major = major + self.minor = minor + } +} + +/// An `Ice.InputStream` extension to read `ProtocolVersion` structured values from the stream. +public extension InputStream { + /// Read a `ProtocolVersion` structured value from the stream. + /// + /// - returns: `ProtocolVersion` - The structured value read from the stream. + func read() throws -> ProtocolVersion { + var v = ProtocolVersion() + v.major = try self.read() + v.minor = try self.read() + return v + } + + /// Read an optional `ProtocolVersion?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ProtocolVersion?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ProtocolVersion? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + try skipSize() + return try read() as ProtocolVersion + } +} + +/// An `Ice.OutputStream` extension to write `ProtocolVersion` structured values from the stream. +public extension OutputStream { + /// Write a `ProtocolVersion` structured value to the stream. + /// + /// - parameter _: `ProtocolVersion` - The value to write to the stream. + func write(_ v: ProtocolVersion) { + self.write(v.major) + self.write(v.minor) + } + + /// Write an optional `ProtocolVersion?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ProtocolVersion?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ProtocolVersion?) { + if let v = value { + if writeOptional(tag: tag, format: .VSize) { + write(size: 2) + write(v) + } + } + } +} + +/// A version structure for the encoding version. +public struct EncodingVersion: Swift.Hashable { + public var major: Swift.UInt8 = 0 + public var minor: Swift.UInt8 = 0 + + public init() {} + + public init(major: Swift.UInt8, minor: Swift.UInt8) { + self.major = major + self.minor = minor + } +} + +/// An `Ice.InputStream` extension to read `EncodingVersion` structured values from the stream. +public extension InputStream { + /// Read a `EncodingVersion` structured value from the stream. + /// + /// - returns: `EncodingVersion` - The structured value read from the stream. + func read() throws -> EncodingVersion { + var v = EncodingVersion() + v.major = try self.read() + v.minor = try self.read() + return v + } + + /// Read an optional `EncodingVersion?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `EncodingVersion?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> EncodingVersion? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + try skipSize() + return try read() as EncodingVersion + } +} + +/// An `Ice.OutputStream` extension to write `EncodingVersion` structured values from the stream. +public extension OutputStream { + /// Write a `EncodingVersion` structured value to the stream. + /// + /// - parameter _: `EncodingVersion` - The value to write to the stream. + func write(_ v: EncodingVersion) { + self.write(v.major) + self.write(v.minor) + } + + /// Write an optional `EncodingVersion?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `EncodingVersion?` - The value to write to the stream. + func write(tag: Swift.Int32, value: EncodingVersion?) { + if let v = value { + if writeOptional(tag: tag, format: .VSize) { + write(size: 2) + write(v) + } + } + } +} diff --git a/Sources/Ice/ImplicitContextI.swift b/Sources/Ice/ImplicitContextI.swift new file mode 100644 index 0000000..d366383 --- /dev/null +++ b/Sources/Ice/ImplicitContextI.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class ImplicitContextI: LocalObject, ImplicitContext { + func getContext() -> Context { + return handle.getContext() + } + + func setContext(_ newContext: Context) { + handle.setContext(newContext) + } + + func containsKey(_ key: String) -> Bool { + return handle.containsKey(key) + } + + func get(_ key: String) -> String { + return handle.get(key) + } + + func put(key: String, value: String) -> String { + return handle.put(key, value: value) + } + + func remove(_ key: String) -> String { + return handle.remove(key) + } +} diff --git a/Sources/Ice/Incoming.swift b/Sources/Ice/Incoming.swift new file mode 100644 index 0000000..f0243aa --- /dev/null +++ b/Sources/Ice/Incoming.swift @@ -0,0 +1,297 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import IceImpl +import PromiseKit + +public final class Incoming { + private let current: Current + private var format: FormatType + private let istr: InputStream + private let responseCallback: ICEBlobjectResponse + private let exceptionCallback: ICEBlobjectException + + private var servant: Disp? + private var locator: ServantLocator? + private var cookie: AnyObject? + + private var ostr: OutputStream! // must be set before calling responseCallback + private var ok: Bool // false if response contains a UserException + + init(istr: InputStream, response: @escaping ICEBlobjectResponse, exception: @escaping ICEBlobjectException, + current: Current) { + self.istr = istr + format = .DefaultFormat + ok = true + responseCallback = response + exceptionCallback = exception + self.current = current + } + + public func readEmptyParams() throws { + // + // Remember the encoding used by the input parameters, we'll + // encode the response parameters with the same encoding. + // + current.encoding = try istr.skipEmptyEncapsulation() + } + + public func readParamEncaps() throws -> Data { + let params = try istr.readEncapsulation() + current.encoding = params.encoding + return params.bytes + } + + public func read(_ cb: (InputStream) throws -> T) throws -> T { + // + // Remember the encoding used by the input parameters, we'll + // encode the response parameters with the same encoding. + // + current.encoding = try istr.startEncapsulation() + let l = try cb(istr) + try istr.endEncapsulation() + return l + } + + public func startOver() { + istr.startOver() + ostr = nil + } + + public func writeParamEncaps(ok: Bool, outParams: Data) -> OutputStream { + let ostr = OutputStream(communicator: istr.communicator, encoding: current.encoding) + if outParams.isEmpty { + ostr.writeEmptyEncapsulation(current.encoding) + } else { + ostr.writeEncapsulation(outParams) + } + self.ok = ok + + return ostr + } + + public func response() { + guard locator == nil || servantLocatorFinished() else { + return + } + precondition(ostr != nil, "OutputStream was not set before calling response()") + ostr.finished().withUnsafeBytes { + responseCallback(ok, $0.baseAddress!, $0.count) + } + } + + public func exception(_ ex: Error) { + guard locator == nil || servantLocatorFinished() else { + return + } + handleException(ex) + } + + public func setFormat(_ format: FormatType) { + self.format = format + } + + @discardableResult + public func setResult(_ os: OutputStream) -> Promise? { + ostr = os + return nil // Response is cached in the Incoming to not have to create unnecessary promise + } + + public func setResult() -> Promise? { + let ostr = OutputStream(communicator: istr.communicator) + ostr.writeEmptyEncapsulation(current.encoding) + self.ostr = ostr + return nil // Response is cached in the Incoming to not have to create unnecessary future + } + + public func setResult(_ cb: (OutputStream) -> Void) -> Promise? { + let ostr = OutputStream(communicator: istr.communicator) + ostr.startEncapsulation(encoding: current.encoding, format: format) + cb(ostr) + ostr.endEncapsulation() + self.ostr = ostr + return nil // Response is cached in the Incoming to not have to create unnecessary future + } + + public func setResultPromise(_ p: Promise) -> Promise { + // Use the thread which fulfilled the promise (on: nil) + return p.map(on: nil) { + let ostr = OutputStream(communicator: self.istr.communicator) + ostr.writeEmptyEncapsulation(self.current.encoding) + return ostr + } + } + + public func setResultPromise(_ p: Promise, + _ cb: @escaping (OutputStream, T) -> Void) -> Promise { + // Use the thread which fulfilled the promise (on: nil) + return p.map(on: nil) { t in + let ostr = OutputStream(communicator: self.istr.communicator) + ostr.startEncapsulation(encoding: self.current.encoding, format: self.format) + cb(ostr, t) + ostr.endEncapsulation() + return ostr + } + } + + func servantLocatorFinished() -> Bool { + guard let locator = locator, let servant = servant else { + preconditionFailure() + } + + do { + try locator.finished(curr: current, servant: servant, cookie: cookie) + return true + } catch { + handleException(error) + } + + return false + } + + func invoke(_ servantManager: ServantManager) { + servant = servantManager.findServant(id: current.id, facet: current.facet) + + if servant == nil { + locator = servantManager.findServantLocator(category: current.id.category) + + if locator == nil, !current.id.category.isEmpty { + locator = servantManager.findServantLocator(category: "") + } + + if let locator = locator { + do { + let locatorReturn = try locator.locate(current) + (servant, cookie) = (locatorReturn.returnValue, locatorReturn.cookie) + } catch { + handleException(error) + return + } + } + } + + guard let s = servant else { + do { + if servantManager.hasServant(id: current.id) || servantManager.isAdminId(current.id) { + throw FacetNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } else { + throw ObjectNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } catch { + exceptionCallback(convertException(error)) + return + } + } + + // + // Dispatch in the incoming call + // + do { + // Request was dispatched asynchronously if promise is non-nil + if let promise = try s.dispatch(request: self, current: current) { + // Use the thread which fulfilled the promise (on: nil) + promise.done(on: nil) { ostr in + self.ostr = ostr + self.response() + }.catch(on: nil) { error in + self.exception(error) + } + } else { + response() + } + } catch { + exception(error) + } + } + + func handleException(_ exception: Error) { + guard let e = exception as? UserException else { + exceptionCallback(convertException(exception)) + return + } + ok = false // response will contain a UserException + let ostr = OutputStream(communicator: istr.communicator) + ostr.startEncapsulation(encoding: current.encoding, format: format) + ostr.write(e) + ostr.endEncapsulation() + ostr.finished().withUnsafeBytes { + responseCallback(ok, $0.baseAddress!, $0.count) + } + } + + func convertException(_ exception: Error) -> ICERuntimeException { + // + // 1. run-time exceptions that travel over the wire + // 2. other LocalExceptions and UserExceptions + // 3. all other exceptions are LocalException + // + switch exception { + // 1. Known run-time exceptions + case let exception as ObjectNotExistException: + let e = ICEObjectNotExistException() + e.file = exception.file + e.line = Int32(exception.line) + e.name = exception.id.name + e.category = exception.id.category + e.facet = exception.facet + e.operation = exception.operation + return e + case let exception as FacetNotExistException: + let e = ICEFacetNotExistException() + e.file = exception.file + e.line = Int32(exception.line) + e.name = exception.id.name + e.category = exception.id.category + e.facet = exception.facet + e.operation = exception.operation + return e + case let exception as OperationNotExistException: + let e = ICEOperationNotExistException() + e.file = exception.file + e.line = Int32(exception.line) + e.name = exception.id.name + e.category = exception.id.category + e.facet = exception.facet + e.operation = exception.operation + return e + case let exception as UnknownUserException: + let e = ICEUnknownUserException() + e.file = exception.file + e.line = Int32(exception.line) + e.unknown = exception.unknown + return e + case let exception as UnknownLocalException: + let e = ICEUnknownLocalException() + e.file = exception.file + e.line = Int32(exception.line) + e.unknown = exception.unknown + return e + case let exception as UnknownException: + let e = ICEUnknownException() + e.file = exception.file + e.line = Int32(exception.line) + e.unknown = exception.unknown + return e + // 2. Other LocalExceptions and UserExceptions + case let exception as LocalException: + let e = ICEUnknownLocalException() + e.file = exception.file + e.line = Int32(exception.line) + e.unknown = "\(exception)" + return e + case let exception as UserException: + let e = ICEUnknownUserException() + e.unknown = "\(exception.ice_id())" + return e + // 3. Unknown exceptions + default: + let e = ICEUnknownException() + e.file = #file + e.line = Int32(#line) + e.unknown = "\(exception)" + return e + } + } +} diff --git a/Sources/Ice/InitializationData.swift b/Sources/Ice/InitializationData.swift new file mode 100644 index 0000000..76ecabc --- /dev/null +++ b/Sources/Ice/InitializationData.swift @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// Settings optionally supplied during communicator initialization. +public struct InitializationData { + /// The properties for the communicator. + public var properties: Properties? + + /// The logger for the communicator. + public var logger: Logger? + + public var classResolverPrefix: [String]? + + public init() {} +} diff --git a/Sources/Ice/Initialize.swift b/Sources/Ice/Initialize.swift new file mode 100644 index 0000000..a422aa3 --- /dev/null +++ b/Sources/Ice/Initialize.swift @@ -0,0 +1,282 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +// +// Factories are registered once when `factoriesRegistered' is lazzy initialized, +// all Swift global variables are lazzy initialized. +// +// All code paths that require the use of the factories before `initialize' is call +// should check `factoriesRegistered' to ensure lazzy initinialization occurrs before +// the factories are used. +// +let factoriesRegistered: Bool = { + ICEUtil.registerFactories(exception: ExceptionFactory.self, + connectionInfo: ConnectionInfoFactory.self, + endpointInfo: EndpointInfoFactory.self, + adminFacet: AdminFacetFactory.self) + return true +}() + +/// Creates a communicator. +/// +/// - parameter _: `[String]` - A command-line argument vector. Any Ice-related options +/// in this vector are used to initialize the communicator. +/// +/// - parameter initData: `Ice.InitializationData` - Additional intialization data. Property +/// settings in args override property settings in initData. +/// +/// - returns: The initialized communicator. +public func initialize(_ args: [String], initData: InitializationData? = nil) throws -> Communicator { + return try initializeImpl(args: args, initData: initData ?? InitializationData(), withConfigFile: true).0 +} + +/// Creates a communicator. +/// +/// - parameter _: `[String]` - A command-line argument vector. Any Ice-related options +/// in this vector are used to initialize the communicator. This method modifies the +/// argument vector by removing any Ice-related options. +/// +/// - parameter initData: `Ice.InitializationData` - Additional intialization data. Property +/// settings in args override property settings in initData. +/// +/// - returns: `Ice.Communicator` - The initialized communicator. +public func initialize(_ args: inout [String], initData: InitializationData? = nil) throws -> Communicator { + let result = try initializeImpl(args: args, initData: initData ?? InitializationData(), withConfigFile: true) + args = result.1 + return result.0 +} + +/// Creates a communicator. +/// +/// - parameter args: `[String]` - A command-line argument array. Any Ice-related options +/// in this array are used to initialize the communicator. +/// +/// - parameter configFile: `String` - Path to a config file that sets the new communicator's +/// default properties. +/// +/// - returns: `Ice.Communicator` - The initialized communicator. +public func initialize(args: [String], configFile: String) throws -> Communicator { + var initData = InitializationData() + let properties = createProperties() + try properties.load(configFile) + initData.properties = properties + return try initialize(args, initData: initData) +} + +/// Creates a communicator. +/// +/// - parameter args: `[String]` - A command-line argument array. Any Ice-related options +/// in this array are used to initialize the communicator. This method modifies the +/// argument array by removing any Ice-related options. +/// +/// - parameter configFile: `String` - Path to a config file that sets the new communicator's +/// default properties. +/// +/// - returns: `Ice.Communicator` - The initialized communicator. +public func initialize(args: inout [String], configFile: String) throws -> Communicator { + var initData = InitializationData() + let properties = createProperties() + try properties.load(configFile) + initData.properties = properties + return try initialize(&args, initData: initData) +} + +/// Creates a communicator. +/// +/// - parameter _: `Ice.InitializationData` - Additional intialization data. +/// +/// - returns: `Ice.Communicator` - The initialized communicator. +public func initialize(_ initData: InitializationData? = nil) throws -> Communicator { + // This is the no-configFile flavor: we never load config from ICE_CONFIG + return try initializeImpl(args: [], initData: initData ?? InitializationData(), withConfigFile: false).0 +} + +/// Creates a communicator. +/// +/// - parameter _: `String` - Path to a config file that sets the new communicator's default +/// properties. +/// +/// - returns: `Ice.Communicator` - The initialized communicator. +public func initialize(_ configFile: String) throws -> Communicator { + return try initialize(args: [], configFile: configFile) +} + +private func initializeImpl(args: [String], + initData userInitData: InitializationData, + withConfigFile: Bool) throws -> (Communicator, [String]) { + // Ensure factories are initialized + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + + var initData = userInitData + if initData.properties == nil { + initData.properties = createProperties() + } + + var loggerP: ICELoggerProtocol? + if let l = initData.logger { + loggerP = LoggerWrapper(handle: l) + } + + let propsHandle = (initData.properties as! PropertiesI).handle + + return try autoreleasepool { + var remArgs: NSArray? + let handle = try ICEUtil.initialize(args, + properties: propsHandle, + withConfigFile: withConfigFile, + logger: loggerP, + remArgs: &remArgs) + + // + // Update initData.properties reference to point to the properties object + // created by Ice::initialize, in case it changed + // + let newPropsHandle = handle.getProperties() + initData.properties = newPropsHandle.getSwiftObject(PropertiesI.self) { + PropertiesI(handle: newPropsHandle) + } + + // + // Update initData.logger referecnce in case we are using a C++ logger (defined though a property) or + // a C++ logger plug-in installed a new logger + // + if let objcLogger = handle.getLogger() as? ICELogger { + initData.logger = objcLogger.getSwiftObject(ObjcLoggerWrapper.self) { + ObjcLoggerWrapper(handle: objcLogger) + } + } + + precondition(initData.logger != nil && initData.properties != nil) + + let communicator = CommunicatorI(handle: handle, initData: initData) + if remArgs == nil { + return (communicator, []) + } else { + // swiftlint:disable force_cast + return (communicator, remArgs as! [String]) + // swiftlint:enable force_cast + } + } +} + +/// Creates a new empty property set. +/// +/// - returns: `Properties` - A new empty property set. +public func createProperties() -> Properties { + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + return PropertiesI(handle: ICEUtil.createProperties()) +} + +/// Creates a property set initialized from an argument array. +/// +/// - parameter _: `[String]` - A command-line argument array, possibly containing options to +/// set properties. If the command-line options include a `--Ice.Config` option, the +/// corresponding configuration files are parsed. If the same property is set in a configuration +/// file and in the argument array, the argument array takes precedence. +/// +/// - parameter defaults: `Ice.Properties` - Optional default values for the property set. Settings in +/// configuration files and argument array override these defaults. +/// +/// - returns: `Ice.Properties` - A new property set initialized with the property settings from the arguments +/// array and defaults. +public func createProperties(_ args: [String], defaults: Properties? = nil) throws -> Properties { + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + return try autoreleasepool { + let propertiesHandle = try ICEUtil.createProperties(args, + defaults: (defaults as? PropertiesI)?.handle, + remArgs: nil) + return PropertiesI(handle: propertiesHandle) + } +} + +/// Creates a property set initialized from an argument array. +/// +/// - parameter _: `[String]` - A command-line argument array, possibly containing options to +/// set properties. If the command-line options include a `--Ice.Config` option, the +/// corresponding configuration files are parsed. If the same property is set in a configuration +/// file and in the argument array, the argument array takes precedence. This method modifies the +/// argument array by removing any Ice-related options. +/// +/// - parameter defaults: `Ice.Properties` - Optional default values for the property set. Settings in +/// configuration files and argument array override these defaults. +/// +/// - returns: `Ice.Properties` - A new property set initialized with the property settings from args +/// and defaults. +public func createProperties(_ args: inout [String], defaults: Properties? = nil) throws -> Properties { + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + return try autoreleasepool { + var remArgs: NSArray? + let propertiesHandle = try ICEUtil.createProperties(args, + defaults: (defaults as? PropertiesI)?.handle, + remArgs: &remArgs) + + // swiftlint:disable force_cast + args = remArgs as! [String] + // swiftlint:enable force_cast + return PropertiesI(handle: propertiesHandle) + } +} + +/// Returns the Ice version as an integer in the form A.BB.CC, where A +/// indicates the major version, BB indicates the minor version, and CC +/// indicates the patch level. For example, for Ice 3.3.1, the returned +/// value is 30301. +public let intVersion: Int = 30710 + +/// The Ice version in the form A.B.C, where A indicates the major version, +/// B indicates the minor version, and C indicates the patch level. +public let stringVersion: String = "3.7.10" + +public let Encoding_1_0 = EncodingVersion(major: 1, minor: 0) +public let Encoding_1_1 = EncodingVersion(major: 1, minor: 1) + +public let currentEncoding = Encoding_1_1 + +/// Converts a string to an object identity. +/// +/// - parameter _: `String` - The string to convert. +/// +/// - returns: `Ice.Identity` - The converted object identity. +public func stringToIdentity(_ string: String) throws -> Identity { + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + return try autoreleasepool { + var name = NSString() + var category = NSString() + try ICEUtil.stringToIdentity(str: string, name: &name, category: &category) + return Identity(name: name as String, category: category as String) + } +} + +/// Converts an object identity to a string. +/// +/// - parameter id: `Ice.Identity` - The object identity to convert. +/// +/// - parameter mode: `ToStringMode` - Specifies if and how non-printable ASCII characters are escaped +/// in the result. +/// +/// - returns: `String` - The string representation of the object identity. +public func identityToString(id: Identity, mode: ToStringMode = ToStringMode.Unicode) -> String { + return ICEUtil.identityToString(name: id.name, category: id.category, mode: mode.rawValue) +} + +/// Converts an encoding version to a string. +/// +/// - parameter _: `Ice.EncodingVersion` - The encoding version to convert. +/// +/// - returns: `String` - The converted string. +public func encodingVersionToString(_ encoding: EncodingVersion) -> String { + return ICEUtil.encodingVersionToString(major: encoding.major, minor: encoding.minor) +} diff --git a/Sources/Ice/InputStream.swift b/Sources/Ice/InputStream.swift new file mode 100644 index 0000000..57d3548 --- /dev/null +++ b/Sources/Ice/InputStream.swift @@ -0,0 +1,1860 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import IceImpl + +/// Stream class to read (unmarshal) Slice types from a sequence of bytes. +public class InputStream { + let data: Data + let classResolverPrefix: [String]? + + private(set) var pos: Int = 0 + private(set) var communicator: Communicator + private let encoding: EncodingVersion + private let traceSlicing: Bool + fileprivate let acceptClassCycles: Bool + + private var encaps: Encaps! + + private var startSeq: Int32 = -1 + private var minSeqSize: Int32 = 0 + private let classGraphDepthMax: Int32 + + private var remaining: Int { + return data.count - pos + } + + var currentEncoding: EncodingVersion { + return encaps != nil ? encaps.encoding : encoding + } + + public convenience init(communicator: Communicator, bytes: Data) { + let encoding = (communicator as! CommunicatorI).defaultsAndOverrides.defaultEncoding + self.init(communicator: communicator, encoding: encoding, bytes: bytes) + } + + public required init(communicator: Communicator, + encoding: EncodingVersion, + bytes: Data) { + data = bytes + classResolverPrefix = (communicator as! CommunicatorI).initData.classResolverPrefix + self.communicator = communicator + self.encoding = encoding + classGraphDepthMax = (communicator as! CommunicatorI).classGraphDepthMax + traceSlicing = (communicator as! CommunicatorI).traceSlicing + acceptClassCycles = (communicator as! CommunicatorI).acceptClassCycles + } + + /// Reads an encapsulation from the stream. + /// + /// - returns: `(bytes: Data, encoding: EncodingVersion)` The encapsulation. + public func readEncapsulation() throws -> (bytes: Data, encoding: EncodingVersion) { + let sz: Int32 = try read() + if sz < 6 { + throw UnmarshalOutOfBoundsException(reason: "Invalid size") + } + + if sz - 4 > remaining { + throw UnmarshalOutOfBoundsException(reason: "Invalid size") + } + + let encoding: EncodingVersion = try read() + try changePos(offset: -6) + + let bytes = data[pos ..< pos + Int(sz)] + return (bytes, encoding) + } + + /// Reads the start of an encapsulation. + /// + /// - returns: `Ice.EncodingVersion` - The encapsulation encoding version. + @discardableResult + public func startEncapsulation() throws -> EncodingVersion { + precondition(encaps == nil, "Nested or sequential encapsulations are not supported") + + let start = pos + // + // I don't use readSize() and writeSize() for encapsulations, + // because when creating an encapsulation, I must know in advance + // how many bytes the size information will require in the data + // stream. If I use an Int, it is always 4 bytes. For + // readSize()/writeSize(), it could be 1 or 5 bytes. + // + let sz: Int32 = try read() + + if sz < 6 { + throw UnmarshalOutOfBoundsException(reason: "invalid size") + } + if sz - 4 > remaining { + throw UnmarshalOutOfBoundsException(reason: "invalid size") + } + + let encoding: EncodingVersion = try read() + + try checkSupportedEncoding(encoding) + + encaps = Encaps(start: start, size: Int(sz), encoding: encoding) + + return encoding + } + + /// Ends the previous encapsulation. + public func endEncapsulation() throws { + if !encaps.encoding_1_0 { + try skipOptionals() + if pos != encaps.start + encaps.sz { + throw EncapsulationException(reason: "buffer size does not match decoded encapsulation size") + } + } else if pos != encaps.start + encaps.sz { + if pos + 1 != encaps.start + encaps.sz { + throw EncapsulationException(reason: "buffer size does not match decoded encapsulation size") + } + + // + // Ice version < 3.3 had a bug where user exceptions with + // class members could be encoded with a trailing byte + // when dispatched with AMD. So we tolerate an extra byte + // in the encapsulation. + // + try skip(1) + } + } + + /// Skips an empty encapsulation. + /// + /// - returns: `Ice.EncodingVersion` - The encapsulation's encoding version. + @discardableResult + func skipEmptyEncapsulation() throws -> EncodingVersion { + let sz: Int32 = try read() + + if sz < 6 { + throw EncapsulationException(reason: "invalid size") + } + + if sz - 4 > remaining { + throw UnmarshalOutOfBoundsException(reason: "") + } + + let encoding: EncodingVersion = try read() + try checkSupportedEncoding(encoding) // Make sure the encoding is supported. + + if encoding == Encoding_1_0 { + if sz != 6 { + throw EncapsulationException(reason: "") + } + } else { + // + // Skip the optional content of the encapsulation if we are expecting an + // empty encapsulation. + // + try skip(sz - 6) + } + + return encoding + } + + /// Skips over an encapsulation. + /// + /// - returns: `Ice.EncodingVersion` - The encoding version of the skipped encapsulation. + func skipEncapsulation() throws -> EncodingVersion { + let sz: Int32 = try read() + + if sz < 6 { + throw EncapsulationException(reason: "invalid size") + } + + let encodingVersion: EncodingVersion = try read() + try changePos(offset: Int(sz) - 6) + return encodingVersion + } + + /// Reads the start of a class instance or exception slice. + /// + /// - returns: The Slice type ID for this slice. + @discardableResult + public func startSlice() throws -> String { + precondition(encaps.decoder != nil) + return try encaps.decoder.startSlice() + } + + /// Indicates that the end of a class instance or exception slice has been reached. + public func endSlice() throws { + precondition(encaps.decoder != nil) + try encaps.decoder.endSlice() + } + + /// Skips over a class instance or exception slice. + public func skipSlice() throws { + precondition(encaps.decoder != nil) + try encaps.decoder.skipSlice() + } + + /// Indicates that unmarshaling is complete, except for any class instances. The application must call this method + /// only if the stream actually contains class instances. Calling `readPendingValues` triggers the + /// calls to consumers provided with {@link #readValue} to inform the application that unmarshaling of an instance + /// is complete. + public func readPendingValues() throws { + if encaps.decoder != nil { + try encaps.decoder.readPendingValues() + } else if encaps.encoding_1_0 { + // + // If using the 1.0 encoding and no instances were read, we + // still read an empty sequence of pending instances if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no instances + // are written we do marshal an empty sequence if marshaled + // data types use classes. + // + try skipSize() + } + } + + /// Extracts a user exception from the stream and throws it. + public func throwException() throws { + initEncaps() + try encaps.decoder.throwException() + } + + func skipOptional(format: OptionalFormat) throws { + switch format { + case .F1: + try skip(1) + case .F2: + try skip(2) + case .F4: + try skip(4) + case .F8: + try skip(8) + case .Size: + try skipSize() + case .VSize: + try skip(readSize()) + case .FSize: + try skip(read()) + case .Class: + try read(UnknownSlicedValue.self, cb: nil) + } + } + + func skipOptionals() throws { + // + // Skip remaining un-read optional members. + // + while true { + if pos >= encaps.start + encaps.sz { + return // End of encapsulation also indicates end of optionals. + } + + let v: UInt8 = try read() + if v == SliceFlags.OPTIONAL_END_MARKER.rawValue { + return + } + + // Read first 3 bits. + guard let format = OptionalFormat(rawValue: v & 0x07) else { + preconditionFailure("invalid optional format") + } + + if v >> 3 == 30 { + try skipSize() + } + + try skipOptional(format: format) + } + } + + // Reset the InputStream to prepare for retry + internal func startOver() { + pos = 0 + encaps = nil + } + + private func changePos(offset: Int) throws { + precondition(pos + offset >= 0, "Negative position") + + guard offset <= remaining else { + throw UnmarshalOutOfBoundsException(reason: "Attempt to move past end of buffer") + } + pos += offset + } + + /// Skips the given number of bytes. + /// + /// - parameter _: `Int` - The number of bytes to skip. + public func skip(_ count: Int) throws { + precondition(count >= 0, "skip count is negative") + try changePos(offset: count) + } + + /// Skips the given number of bytes. + /// + /// - parameter _: `Int32` - The number of bytes to skip. + public func skip(_ count: Int32) throws { + try changePos(offset: Int(count)) + } + + /// Skip over a size value. + public func skipSize() throws { + let b: UInt8 = try read() + if b == 255 { + try skip(4) + } + } + + /// Marks the start of a class instance. + public func startValue() { + precondition(encaps.decoder != nil) + encaps.decoder.startInstance(type: .ValueSlice) + } + + /// Marks the end of a class instance. + /// + /// - parameter preserve: `Bool` - True if unknown slices should be preserved, false otherwise. + /// + /// - returns: `Ice.SlicedData` - A SlicedData object containing the preserved slices for unknown types. + @discardableResult + public func endValue(preserve: Bool) throws -> SlicedData? { + precondition(encaps.decoder != nil) + return try encaps.decoder.endInstance(preserve: preserve) + } + + /// Marks the start of a user exception. + public func startException() { + precondition(encaps.decoder != nil) + encaps.decoder.startInstance(type: .ExceptionSlice) + } + + /// Marks the end of a user exception. + /// + /// - parameter preserve: `Bool` - True if unknown slices should be preserved, false otherwise. + /// + /// - returns: `Ice.SlicedData?` - A `SlicedData` object containing the preserved slices for unknown + /// types. + @discardableResult + public func endException(preserve: Bool) throws -> SlicedData? { + precondition(encaps.decoder != nil) + return try encaps.decoder.endInstance(preserve: preserve) + } + + func initEncaps() { + if encaps == nil { + encaps = Encaps(start: 0, size: data.count, encoding: encoding) + } + if encaps.decoder == nil { // Lazy initialization + let valueFactoryManager = communicator.getValueFactoryManager() + if encaps.encoding_1_0 { + encaps.decoder = EncapsDecoder10(stream: self, + valueFactoryManager: valueFactoryManager, + classGraphDepthMax: classGraphDepthMax) + } else { + encaps.decoder = EncapsDecoder11(stream: self, + valueFactoryManager: valueFactoryManager, + classGraphDepthMax: classGraphDepthMax) + } + } + } + + fileprivate func traceSkipSlice(typeId: String, sliceType: SliceType) { + guard traceSlicing else { + return + } + + ICETraceUtil.traceSlicing(kind: sliceType == SliceType.ExceptionSlice ? "exception" : "object", + typeId: typeId, + slicingCat: "Slicing", + logger: LoggerWrapper(handle: communicator.getLogger())) + } + + static func throwUOE(expectedType: Value.Type, v: Value) throws { + // + // If the object is an unknown sliced object, we didn't find an + // value factory, in this case raise a NoValueFactoryException + // instead. + // + if let usv = v as? UnknownSlicedValue { + throw NoValueFactoryException(reason: "", type: usv.ice_id()) + } + + throw UnexpectedObjectException(reason: "expected element of type `\(expectedType)' but received `\(v)'", + type: v.ice_id(), + expectedType: expectedType.ice_staticId()) + } +} + +public extension InputStream { + /// Reads a numeric value from the stream. + /// + /// - returns: `Element` - The numeric value read from the stream. + func read() throws -> Element where Element: StreamableNumeric { + let size = MemoryLayout.size + guard size <= remaining else { + throw UnmarshalOutOfBoundsException(reason: "attempting to read past buffer capacity") + } + + var value: Element = 0 + // We assume a little-endian platform + withUnsafeMutablePointer(to: &value) { ptr in + let buf = UnsafeMutableBufferPointer(start: ptr, count: 1) + self.data.copyBytes(to: buf, from: self.pos ..< self.pos + size) + } + pos += size + return value + } + + /// Reads an optional numeric value from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `Element?` - The optional numeric value read from the stream. + func read(tag: Int32) throws -> Element? where Element: StreamableNumeric { + let expectedFormat = OptionalFormat(fixedSize: MemoryLayout.size) + guard try readOptional(tag: tag, expectedFormat: expectedFormat!) else { + return nil + } + return try read() + } + + /// Reads a sequence of numeric values from the stream. + /// + /// - returns: `[Element]` - The sequence of numeric values read from the stream. + func read() throws -> [Element] where Element: StreamableNumeric { + let sz = try readAndCheckSeqSize(minSize: MemoryLayout.size) + + if sz == 0 { + return [Element]() + } else { + let eltSize = MemoryLayout.size + if sz == 1 || eltSize == MemoryLayout.stride { + // Can copy directly from bytes to array + var a = [Element](repeating: 0, count: sz) + pos += a.withUnsafeMutableBufferPointer { buf in + self.data.copyBytes(to: buf, from: self.pos ..< self.pos + sz * eltSize) + } + return a + } else { + var a = [Element]() + a.reserveCapacity(sz) + for _ in 0 ..< sz { + try a.append(read()) + } + return a + } + } + } + + /// Reads an optional sequence of numeric values from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `[Element]?` - The optional sequence read from the stream. + func read(tag: Int32) throws -> [Element]? where Element: StreamableNumeric { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + if MemoryLayout.size > 1 { + try skipSize() + } + return try read() + } + + /// Reads a byte from the stream. + /// + /// - returns: `UInt8` - The byte read from the stream. + func read() throws -> UInt8 { + guard remaining > 0 else { + throw UnmarshalOutOfBoundsException(reason: "attempting to read past buffer capacity") + } + let value = data[pos] + pos += 1 + return value + } + + /// Reads a sequence of bytes from the stream. + /// + /// - returns: `[UInt8]` - The sequence of bytes read from the stream. + func read() throws -> [UInt8] { + let sz = try readAndCheckSeqSize(minSize: 1) + let start = pos + pos += sz + return [UInt8](data[start ..< pos]) + } + + /// Reads a sequence of bytes from the stream. + /// + /// - returns: `Data` - The sequence of bytes read from the stream. + func read() throws -> Data { + let sz = try readAndCheckSeqSize(minSize: 1) + let start = pos + pos += sz + return data.subdata(in: start ..< pos) // copy + } + + /// Reads an optional sequence of bytes from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `Data?` - The optional sequence of bytes read from the stream. + func read(tag: Int32) throws -> Data? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + // No skipSize here + return try read() + } + + /// Reads a boolean value from the stream. + /// + /// - returns: `Bool` - The boolean value read from the stream. + func read() throws -> Bool { + let value: UInt8 = try read() + return value == 1 + } + + /// Reads an optional boolean value from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `Bool?` - The optional boolean value read from the stream. + func read(tag: Int32) throws -> Bool? { + guard try readOptional(tag: tag, expectedFormat: .F1) else { + return nil + } + return try read() as Bool + } + + /// Reads a sequence of boolean value from the stream. + /// + /// - returns: `[Bool]` - The sequence of boolean values read from the stream. + func read() throws -> [Bool] { + let sz = try readAndCheckSeqSize(minSize: 1) + + if sz == 0 { + return [Bool]() + } else if MemoryLayout.size == 1, MemoryLayout.stride == 1 { + // Copy directly from bytes to array + var a = [Bool](repeating: false, count: sz) + pos += a.withUnsafeMutableBufferPointer { buf in + self.data.copyBytes(to: buf, from: self.pos ..< self.pos + sz) + } + return a + } else { + fatalError("Unsupported Bool memory layout") + } + } + + /// Reads an optional sequence of boolean value from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `[Bool]?` - The optional sequence of boolean values read from the stream. + func read(tag: Int32) throws -> [Bool]? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + return try read() + } + + /// Reads a size from the stream. + /// + /// - returns: `Int32` - The size read from the stream. + func readSize() throws -> Int32 { + let byteVal: UInt8 = try read() + if byteVal == 255 { + return try read() + } else { + return Int32(byteVal) + } + } + + /// Reads a sequence size from the stream and ensures the stream has enough + /// bytes for `size` elements, where each element's size is at least minSize. + /// + /// - parameter minSize: `Int` - The mininum element size to use for the check. + /// + /// - returns: `Int` - The size read from the stream. + func readAndCheckSeqSize(minSize: Int) throws -> Int { + let sz = try Int(readSize()) + + guard sz != 0 else { + return sz + } + + // + // The startSeq variable points to the start of the sequence for which + // we expect to read at least minSeqSize bytes from the stream. + // + // If not initialized or if we already read more data than minSeqSize, + // we reset startSeq and minSeqSize for this sequence (possibly a + // top-level sequence or enclosed sequence it doesn't really matter). + // + // Otherwise, we are reading an enclosed sequence and we have to bump + // minSeqSize by the minimum size that this sequence will require on + // the stream. + // + // The goal of this check is to ensure that when we start un-marshalling + // a new sequence, we check the minimal size of this new sequence against + // the estimated remaining buffer size. This estimatation is based on + // the minimum size of the enclosing sequences, it's minSeqSize. + // + if startSeq == -1 || pos > (startSeq + minSeqSize) { + startSeq = Int32(pos) + minSeqSize = Int32(sz * minSize) + } else { + minSeqSize += Int32(sz * minSize) + } + + // + // If there isn't enough data to read on the stream for the sequence (and + // possibly enclosed sequences), something is wrong with the marshalled + // data: it's claiming having more data that what is possible to read. + // + if startSeq + minSeqSize > data.count { + throw UnmarshalOutOfBoundsException(reason: "bad sequence size") + } + + return sz + } + + // + // Optional + // + func readOptional(tag: Int32, expectedFormat: OptionalFormat) throws -> Bool { + if encaps.decoder != nil { + return try encaps.decoder.readOptional(tag: tag, format: expectedFormat) + } + + return try readOptionalImpl(readTag: tag, expectedFormat: expectedFormat) + } + + internal func readOptionalImpl(readTag: Int32, expectedFormat: OptionalFormat) throws -> Bool { + if encaps.encoding_1_0 { + return false // Optional members aren't supported with the 1.0 encoding. + } + + while true { + if pos >= encaps.start + encaps.sz { + return false // End of encapsulation also indicates end of optionals. + } + + let v: UInt8 = try read() + if v == SliceFlags.OPTIONAL_END_MARKER.rawValue { + try changePos(offset: -1) // Rewind + return false + } + + // First 3 bits. + guard let format = OptionalFormat(rawValue: v & 0x07) else { + throw MarshalException(reason: "invalid optional format") + } + var tag = Int32(v >> 3) + if tag == 30 { + tag = try readSize() + } + + if tag > readTag { + let offset = tag < 30 ? -1 : (tag < 255 ? -2 : -6) // Rewind + try changePos(offset: offset) + return false // No optional data members with the requested tag + } else if tag < readTag { + try skipOptional(format: format) // Skip optional data members + } else { + if format != expectedFormat { + throw MarshalException(reason: "invalid optional data member `\(tag)': unexpected format") + } + return true + } + } + } + + /// Reads an enumerator from the stream, as a byte. + /// + /// - parameter enumMaxValue: `Int32` - The maximum value for the enumerators (used only for the 1.0 encoding). + /// + /// - returns: `UInt8` - The enumerator's byte value. + func read(enumMaxValue: Int32) throws -> UInt8 { + if currentEncoding == Encoding_1_0 { + if enumMaxValue < 127 { + return try read() + } else if enumMaxValue < 32767 { + let v: Int16 = try read() + guard v <= UInt8.max else { + throw UnmarshalOutOfBoundsException(reason: "1.0 encoded enum value is larger than UInt8") + } + return UInt8(v) + } else { + let v: Int32 = try read() + guard v <= UInt8.max else { + throw UnmarshalOutOfBoundsException(reason: "1.0 encoded enum value is larger than UInt8") + } + return UInt8(v) + } + } else { + let v = try readSize() + guard v <= UInt8.max else { + throw UnmarshalOutOfBoundsException(reason: "1.1 encoded enum value is larger than UInt8") + } + return UInt8(v) + } + } + + /// Reads an enumerator from the stream, as a Int32. + /// + /// - parameter enumMaxValue: `Int32` - The maximum value for the enumerators (used only for the 1.0 encoding). + /// + /// - returns: `Int32` - The enumerator's Int32 value. + func read(enumMaxValue: Int32) throws -> Int32 { + if currentEncoding == Encoding_1_0 { + if enumMaxValue < 127 { + return Int32(try read() as UInt8) + } else if enumMaxValue < 32767 { + return Int32(try read() as Int16) + } else { + return try read() + } + } else { + return try readSize() + } + } + + /// Reads a string from the stream. + /// + /// - returns: `String` - The string read from the stream. + func read() throws -> String { + let size = try readSize() + if size == 0 { + return "" + } else { + let start = pos + try skip(size) + let end = pos + guard let str = String(data: data[start ..< end], encoding: .utf8) else { + throw MarshalException(reason: "unable to read string") + } + return str + } + } + + /// Reads an optional string from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `String?` - The optional string read from the stream. + func read(tag: Int32) throws -> String? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + return try read() as String + } + + /// Reads a sequence of strings from the stream. + /// + /// - returns: `[String]` - The sequence of strings read from the stream. + func read() throws -> [String] { + let sz = try readAndCheckSeqSize(minSize: 1) + var r: [String] = [String]() + r.reserveCapacity(sz) + for _ in 0 ..< sz { + r.append(try read()) + } + return r + } + + /// Reads an optional sequence of strings from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `[String]?` - The optional sequence of strings read from the stream. + func read(tag: Int32) throws -> [String]? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as [String] + } + + /// Reads a proxy from the stream (internal helper). + /// + /// - returns: `ProxyImpl?` - The proxy read from the stream. + func read() throws -> ProxyImpl? where ProxyImpl: ObjectPrxI { + return try ProxyImpl.ice_read(from: self) + } + + /// Reads an optional proxy from the stream (internal helper). + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - returns: `ProxyImpl?` - The proxy read from the stream. + func read(tag: Int32) throws -> ProxyImpl? where ProxyImpl: ObjectPrxI { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ProxyImpl? + } + + /// Reads a base proxy from the stream. + /// + /// - returns: `ObjectPrx?` - The proxy read from the stream. + func read(_: ObjectPrx.Protocol) throws -> ObjectPrx? { + return try read() as ObjectPrxI? + } + + /// Reads an optional base proxy from the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + ///  + /// - returns: `ObjectPrx?` - The proxy read from the stream. + func read(tag: Int32, type _: ObjectPrx.Protocol) throws -> ObjectPrx? { + return try read(tag: tag) as ObjectPrxI? + } + + /// Reads a value from the stream. + func read(cb: ((Value?) throws -> Void)?) throws { + initEncaps() + try encaps.decoder.readValue(cb: cb) + } + + /// Reads an optional value from the stream. + func read(tag: Int32, cb: ((Value?) throws -> Void)?) throws { + if try readOptional(tag: tag, expectedFormat: .Class) { + try read(cb: cb) + } + } + + /// Reads a value from the stream. + func read(_ value: ValueType.Type, cb: ((ValueType?) -> Void)?) throws where ValueType: Value { + initEncaps() + if let cb = cb { + try encaps.decoder.readValue { v in + if v == nil || v is ValueType { + cb(v as? ValueType) + } else { + try InputStream.throwUOE(expectedType: value, v: v!) + } + } + } else { + try encaps.decoder.readValue(cb: nil) + } + } + + /// Reads an optional value from the stream. + func read(tag: Int32, value: ValueType.Type, cb: ((ValueType?) -> Void)?) throws where ValueType: Value { + if try readOptional(tag: tag, expectedFormat: .Class) { + try read(value, cb: cb) + } + } +} + +private class Encaps { + let start: Int + let sz: Int + let encoding: EncodingVersion + let encoding_1_0: Bool + var decoder: EncapsDecoder! + + init(start: Int, size: Int, encoding: EncodingVersion) { + self.start = start + sz = size + self.encoding = encoding + encoding_1_0 = encoding == Ice.Encoding_1_0 + } +} + +private enum SliceType { + case NoSlice + case ValueSlice + case ExceptionSlice +} + +private typealias Callback = (Value?) throws -> Void + +private struct PatchEntry { + let cb: Callback + let classGraphDepth: Int32 + + fileprivate init(cb: @escaping Callback, classGraphDepth: Int32) { + self.cb = cb + self.classGraphDepth = classGraphDepth + } +} + +private protocol EncapsDecoder: AnyObject { + var stream: InputStream { get } + var valueFactoryManager: ValueFactoryManager { get } + + // + // Encapsulation attributes for value unmarshaling. + // + var patchMap: [Int32: [PatchEntry]] { get set } + var unmarshaledMap: [Int32: Value?] { get set } + var typeIdMap: [Int32: String] { get set } + var typeIdIndex: Int32 { get set } + var valueList: [Value] { get set } + + var typeIdCache: [String: Value.Type?] { get set } + + var classGraphDepthMax: Int32 { get } + var classGraphDepth: Int32 { get set } + + func readValue(cb: Callback?) throws + func throwException() throws + + func startInstance(type: SliceType) + func endInstance(preserve: Bool) throws -> SlicedData? + func startSlice() throws -> String + func endSlice() throws + func skipSlice() throws + + func readOptional(tag: Int32, format: OptionalFormat) throws -> Bool + func readPendingValues() throws +} + +extension EncapsDecoder { + func readOptional(tag _: Int32, format _: OptionalFormat) throws -> Bool { + return false + } + + func readPendingValues() throws {} + + func readTypeId(isIndex: Bool) throws -> String { + if isIndex { + let index = try stream.readSize() + guard let typeId = typeIdMap[index] else { + throw UnmarshalOutOfBoundsException(reason: "invalid typeId") + } + return typeId + } else { + let typeId: String = try stream.read() + typeIdIndex += 1 + typeIdMap[typeIdIndex] = typeId + return typeId + } + } + + func resolveClass(typeId: String) throws -> Value.Type? { + if let cls = typeIdCache[typeId] { + return cls + } else { + var cls: Value.Type? + for prefix in stream.classResolverPrefix ?? [] { + cls = ClassResolver.resolve(typeId: typeId, prefix: prefix) + if cls != nil { + break + } + } + if cls == nil { + cls = ClassResolver.resolve(typeId: typeId) + } + typeIdCache[typeId] = cls + return cls + } + } + + func newInstance(typeId: String) throws -> Value? { + // + // Try to find a factory registered for the specific type. + // + if let factory = valueFactoryManager.find(typeId) { + if let v = factory(typeId) { + return v + } + } + + // + // If that fails, invoke the default factory if one has been + // registered. + // + if let factory = valueFactoryManager.find("") { + if let v = factory(typeId) { + return v + } + } + + // + // Last chance: try to instantiate the class dynamically. + // + if let cls = try resolveClass(typeId: typeId) { + return cls.init() + } + + return nil + } + + func addPatchEntry(index: Int32, cb: @escaping Callback) throws { + precondition(index > 0, "invalid index") + + // + // Check if we already unmarshaled the object. If that's the case, just patch the object smart pointer + // and we're done. A null value indicates we've encountered a cycle and Ice.AllowClassCycles is false. + // + if let optObj = unmarshaledMap[index] { + guard let obj = optObj else { + assert(!stream.acceptClassCycles) + throw MarshalException(reason: "cycle detected during Value unmarshaling") + } + try cb(obj) + return + } + + // + // Add patch entry if the instance isn't unmarshaled yet, + // the callback will be called when the instance is + // unmarshaled. + // + var entries = patchMap[index] ?? [] + entries.append(PatchEntry(cb: cb, classGraphDepth: classGraphDepth)) + patchMap[index] = entries + } + + func unmarshal(index: Int32, v: Value) throws { + // + // Add the instance to the map of unmarshaled instances, this must + // be done before reading the instances (for circular references). + // + // If circular references are not allowed we insert null (for cycle detection) and add + // the object to the map once it has been fully unmarshaled. + // + unmarshaledMap[index] = stream.acceptClassCycles ? v : (nil as Value?) + assert(unmarshaledMap[index] != nil) + + // + // Read the instance. + // + try v._iceRead(from: stream) + + // + // Patch all instances now that the instance is unmarshaled. + // + if let l = patchMap[index] { + precondition(!l.isEmpty) + + // + // Patch all pointers that refer to the instance. + // + for entry in l { + try entry.cb(v) + } + + // + // Clear out the patch map for that index -- there is nothing left + // to patch for that index for the time being. + // + patchMap.removeValue(forKey: index) + } + + if patchMap.isEmpty, valueList.isEmpty { + v.ice_postUnmarshal() + } else { + valueList.append(v) + + if patchMap.isEmpty { + // + // Iterate over the instance list and invoke ice_postUnmarshal on + // each instance. We must do this after all instances have been + // unmarshaled in order to ensure that any instance data members + // have been properly patched. + // + for p in valueList { + p.ice_postUnmarshal() + } + valueList.removeAll() + } + } + + if !stream.acceptClassCycles { + // This class has been fully unmarshaled without creating any cycles + // It can be added to the map now. + unmarshaledMap[index] = v + } + } +} + +private class EncapsDecoder10: EncapsDecoder { + // EncapsDecoder members + unowned let stream: InputStream + let valueFactoryManager: ValueFactoryManager + lazy var patchMap = [Int32: [PatchEntry]]() + lazy var unmarshaledMap = [Int32: Value?]() + lazy var typeIdMap = [Int32: String]() + var typeIdIndex: Int32 = 0 + lazy var valueList = [Value]() + lazy var typeIdCache = [String: Value.Type?]() + + // Value/exception attributes + var sliceType: SliceType + var skipFirstSlice: Bool! + + // Slice attributes + var sliceSize: Int32! + var typeId: String! + + let classGraphDepthMax: Int32 + var classGraphDepth: Int32 + + init(stream: InputStream, valueFactoryManager: ValueFactoryManager, classGraphDepthMax: Int32) { + self.stream = stream + self.valueFactoryManager = valueFactoryManager + sliceType = SliceType.NoSlice + self.classGraphDepthMax = classGraphDepthMax + classGraphDepth = 0 + } + + func readValue(cb: Callback?) throws { + guard let cb = cb else { + preconditionFailure("patch fuction can not be nil") + } + + // + // Object references are encoded as a negative integer in 1.0. + // + var index: Int32 = try stream.read() + if index > 0 { + throw MarshalException(reason: "invalid object id") + } + index = -index + + if index == 0 { + try cb(nil) + } else { + try addPatchEntry(index: index, cb: cb) + } + } + + func throwException() throws { + precondition(sliceType == .NoSlice) + + // + // User exception with the 1.0 encoding start with a boolean flag + // that indicates whether or not the exception has classes. + // + // This allows reading the pending instances even if some part of + // the exception was sliced. + // + + let usesClasses: Bool = try stream.read() + + sliceType = .ExceptionSlice + skipFirstSlice = false + + // + // Read the first slice header. + // + try startSlice() + let mostDerivedId = typeId! + + while true { + // + // Look for user exception + // + var userExceptionType: UserException.Type? + for prefix in stream.classResolverPrefix ?? [] { + userExceptionType = ClassResolver.resolve(typeId: typeId, prefix: prefix) + if userExceptionType != nil { + break + } + } + if userExceptionType == nil { + userExceptionType = ClassResolver.resolve(typeId: typeId) + } + + // + // We found the exception. + // + if let type = userExceptionType { + let ex = type.init() + try ex._iceRead(from: stream) + if usesClasses { + try readPendingValues() + } + throw ex + } + + // + // Slice off what we don't understand. + // + try skipSlice() + do { + try startSlice() + } catch let ex as UnmarshalOutOfBoundsException { + // + // An oversight in the 1.0 encoding means there is no marker to indicate + // the last slice of an exception. As a result, we just try to read the + // next type ID, which raises UnmarshalOutOfBoundsException when the + // input buffer underflows. + // + // Set the reason member to a more helpful message. + // + + ex.reason = "unknown exception type `\(mostDerivedId)'" + throw ex + } + } + } + + func startInstance(type: SliceType) { + precondition(sliceType == type) + skipFirstSlice = true + } + + func endInstance(preserve _: Bool) throws -> SlicedData? { + // + // Read the Ice::Value slice. + // + if sliceType == .ValueSlice { + try startSlice() + let sz = try stream.readSize() // For compatibility with the old AFM. + if sz != 0 { + throw MarshalException(reason: "invalid Object slice") + } + try endSlice() + } + + sliceType = .NoSlice + return nil + } + + @discardableResult + func startSlice() throws -> String { + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if skipFirstSlice { + skipFirstSlice = false + return typeId + } + + // + // For class instances, first read the type ID boolean which indicates + // whether or not the type ID is encoded as a string or as an + // index. For exceptions, the type ID is always encoded as a + // string. + // + if sliceType == .ValueSlice { + let isIndex: Bool = try stream.read() + typeId = try readTypeId(isIndex: isIndex) + } else { + typeId = try stream.read() + } + + sliceSize = try stream.read() + if sliceSize < 4 { + throw UnmarshalOutOfBoundsException(reason: "invalid slice size") + } + return typeId + } + + func endSlice() throws {} + + func skipSlice() throws { + stream.traceSkipSlice(typeId: typeId, sliceType: sliceType) + try stream.skip(sliceSize - 4) + } + + func readPendingValues() throws { + var num: Int32 + repeat { + num = try stream.readSize() + for _ in 0 ..< num { + try readInstance() + } + } while num > 0 + + if !patchMap.isEmpty { + // + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. + // + throw MarshalException(reason: "index for class received, but no instance") + } + } + + func readInstance() throws { + let index: Int32 = try stream.read() + + if index <= 0 { + throw MarshalException(reason: "invalid object id") + } + + sliceType = SliceType.ValueSlice + skipFirstSlice = false + + // + // Read the first slice header. + // + try startSlice() + let mostDerivedId = typeId! + var v: Value! + + while true { + // + // For the 1.0 encoding, the type ID for the base Object class + // marks the last slice. + // + if typeId == "::Ice::Object" { + throw NoValueFactoryException(reason: "invalid typeId", type: mostDerivedId) + } + + v = try newInstance(typeId: typeId) + + // + // We found a factory, we get out of this loop. + // + if v != nil { + break + } + + // + // Slice off what we don't understand. + // + try skipSlice() + try startSlice() // Read next Slice header for next iteration. + } + + // + // Compute the biggest class graph depth of this object. To compute this, + // we get the class graph depth of each ancestor from the patch map and + // keep the biggest one. + // + classGraphDepth = 0 + if let l = patchMap[index] { + precondition(l.count > 0) + classGraphDepth = l.reduce(0) { max($0, $1.classGraphDepth) } + } + classGraphDepth += 1 + if classGraphDepth > classGraphDepthMax { + throw MarshalException(reason: "maximum class graph depth reached") + } + + // + // Unmarshal the instance and add it to the map of unmarshaled instances. + // + try unmarshal(index: index, v: v) + } +} + +private class EncapsDecoder11: EncapsDecoder { + // EncapsDecoder members + unowned let stream: InputStream + let valueFactoryManager: ValueFactoryManager + lazy var patchMap = [Int32: [PatchEntry]]() + lazy var unmarshaledMap = [Int32: Value?]() + lazy var typeIdMap = [Int32: String]() + var typeIdIndex: Int32 = 0 + lazy var valueList = [Value]() + lazy var typeIdCache = [String: Value.Type?]() + + let classGraphDepthMax: Int32 + var classGraphDepth: Int32 + + private var current: InstanceData! + var valueIdIndex: Int32 = 1 // The ID of the next instance to unmarshal. + lazy var compactIdCache = [Int32: Value.Type]() // Cache of compact type IDs. + + private struct IndirectPatchEntry { + var index: Int32 + var cb: Callback + + init(index: Int32, cb: @escaping Callback) { + self.index = index + self.cb = cb + } + } + + private class InstanceData { + // Instance attributes + var sliceType: SliceType! + var skipFirstSlice: Bool! + lazy var slices = [SliceInfo]() // Preserved slices. + lazy var indirectionTables = [[Int32]]() + + // Slice attributes + var sliceFlags: SliceFlags! + var sliceSize: Int32! + var typeId: String! + var compactId: Int32! + lazy var indirectPatchList = [IndirectPatchEntry]() + + let previous: InstanceData? + weak var next: InstanceData? + + init(previous: InstanceData?) { + self.previous = previous + next = nil + + previous?.next = self + } + } + + init(stream: InputStream, valueFactoryManager: ValueFactoryManager, classGraphDepthMax: Int32) { + self.stream = stream + self.valueFactoryManager = valueFactoryManager + self.classGraphDepthMax = classGraphDepthMax + classGraphDepth = 0 + } + + func readValue(cb: Callback?) throws { + let index = try stream.readSize() + if index < 0 { + throw MarshalException(reason: "invalid object id") + } else if index == 0 { + try cb?(nil) + } else if current != nil, current.sliceFlags.contains(.FLAG_HAS_INDIRECTION_TABLE) { + // + // When reading a class instance within a slice and there's an + // indirect instance table, always read an indirect reference + // that points to an instance from the indirect instance table + // marshaled at the end of the Slice. + // + // Maintain a list of indirect references. Note that the + // indirect index starts at 1, so we decrement it by one to + // derive an index into the indirection table that we'll read + // at the end of the slice. + // + if let cb = cb { + current.indirectPatchList.append(IndirectPatchEntry(index: index - 1, cb: cb)) + } + } else { + _ = try readInstance(index: index, cb: cb) + } + } + + func throwException() throws { + precondition(current == nil) + + push(sliceType: .ExceptionSlice) + // + // Read the first slice header. + // + try startSlice() + let mostDerivedId = current.typeId! + while true { + // + // Look for user exception + // + var userExceptionType: UserException.Type? + for prefix in stream.classResolverPrefix ?? [] { + userExceptionType = ClassResolver.resolve(typeId: current.typeId, prefix: prefix) + if userExceptionType != nil { + break + } + } + if userExceptionType == nil { + userExceptionType = ClassResolver.resolve(typeId: current.typeId) + } + + // + // We found the exception. + // + if let userEx = userExceptionType { + let ex = userEx.init() + try ex._iceRead(from: stream) + throw ex + } + + // + // Slice off what we don't understand. + // + try skipSlice() + + if current.sliceFlags.contains(.FLAG_IS_LAST_SLICE) { + if let range = mostDerivedId.range(of: "::") { + throw UnknownUserException(unknown: String(mostDerivedId[range.upperBound...])) + } else { + throw UnknownUserException(unknown: mostDerivedId) + } + } + + try startSlice() + } + } + + func startInstance(type: SliceType) { + precondition(current.sliceType == type) + current.skipFirstSlice = true + } + + func endInstance(preserve: Bool) throws -> SlicedData? { + var slicedData: SlicedData? + if preserve { + slicedData = try readSlicedData() + } + + current.slices.removeAll() + current.indirectionTables.removeAll() + + current = current.previous + return slicedData + } + + @discardableResult + func startSlice() throws -> String { + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if current.skipFirstSlice { + current.skipFirstSlice = false + return current.typeId + } + + current.sliceFlags = try SliceFlags(rawValue: stream.read()) + + // + // Read the type ID, for value slices the type ID is encoded as a + // string or as an index, for exceptions it's always encoded as a + // string. + // + if current.sliceType == .ValueSlice { + // Must be checked 1st! + if current.sliceFlags.contains(.FLAG_HAS_TYPE_ID_COMPACT) { + current.typeId = "" + current.compactId = try stream.readSize() + } else if current.sliceFlags.contains(.FLAG_HAS_TYPE_ID_INDEX) || + current.sliceFlags.contains(.FLAG_HAS_TYPE_ID_STRING) { + current.typeId = try readTypeId(isIndex: current.sliceFlags.contains(.FLAG_HAS_TYPE_ID_INDEX)) + current.compactId = -1 + } else { + // + // Only the most derived slice encodes the type ID for the compact format. + // + current.typeId = "" + + current.compactId = -1 + } + } else { + current.typeId = try stream.read() + current.compactId = -1 + } + + // + // Read the slice size if necessary. + // + if current.sliceFlags.contains(SliceFlags.FLAG_HAS_SLICE_SIZE) { + current.sliceSize = try stream.read() + if current.sliceSize < 4 { + throw UnmarshalOutOfBoundsException(reason: "invalid slice size") + } + } else { + current.sliceSize = 0 + } + + return current.typeId + } + + func endSlice() throws { + if current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) { + try stream.skipOptionals() + } + + // + // Read the indirection table if one is present and transform the + // indirect patch list into patch entries with direct references. + // + if current.sliceFlags.contains(.FLAG_HAS_INDIRECTION_TABLE) { + var indirectionTable = [Int32](repeating: 0, count: Int(try stream.readAndCheckSeqSize(minSize: 1))) + + for i in 0 ..< indirectionTable.count { + indirectionTable[i] = try readInstance(index: stream.readSize(), cb: nil) + } + + // + // Sanity checks. If there are optional members, it's possible + // that not all instance references were read if they are from + // unknown optional data members. + // + if indirectionTable.isEmpty { + throw MarshalException(reason: "empty indirection table") + } + if current.indirectPatchList.isEmpty, + !current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) { + throw MarshalException(reason: "no references to indirection table") + } + + // + // Convert indirect references into direct references. + // + for e in current.indirectPatchList { + precondition(e.index >= 0) + if e.index >= indirectionTable.count { + throw MarshalException(reason: "indirection out of range") + } + try addPatchEntry(index: indirectionTable[Int(e.index)], cb: e.cb) + } + current.indirectPatchList.removeAll() + } + } + + func skipSlice() throws { + stream.traceSkipSlice(typeId: current.typeId, sliceType: current.sliceType) + + let start = stream.pos + + if current.sliceFlags.contains(.FLAG_HAS_SLICE_SIZE) { + precondition(current.sliceSize >= 4) + try stream.skip(current.sliceSize - 4) + } else { + if current.sliceType == .ValueSlice { + throw NoValueFactoryException(reason: "no value factory found and compact format prevents " + + "slicing (the sender should use the sliced format instead)", + type: current.typeId) + } else { + if let r = current.typeId.range(of: "::") { + throw UnknownUserException(unknown: String(current.typeId[r.upperBound...])) + } else { + throw UnknownUserException(unknown: current.typeId) + } + } + } + + // + // Preserve this slice. + // + let hasOptionalMembers = current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) + let isLastSlice = current.sliceFlags.contains(.FLAG_IS_LAST_SLICE) + var dataEnd = stream.pos + + if hasOptionalMembers { + // + // Don't include the optional member end marker. It will be re-written by + // endSlice when the sliced data is re-written. + // + dataEnd -= 1 + } + + let bytes = stream.data.subdata(in: start ..< dataEnd) // copy + + let info = SliceInfo(typeId: current.typeId, + compactId: current.compactId, + bytes: bytes, + instances: [], + hasOptionalMembers: hasOptionalMembers, + isLastSlice: isLastSlice) + + // + // Read the indirect instance table. We read the instances or their + // IDs if the instance is a reference to an already unmarhsaled + // instance. + // + // The SliceInfo object sequence is initialized only if + // readSlicedData is called. + // + if current.sliceFlags.contains(.FLAG_HAS_INDIRECTION_TABLE) { + var indirectionTable = [Int32](repeating: 0, count: Int(try stream.readAndCheckSeqSize(minSize: 1))) + + for i in 0 ..< indirectionTable.count { + indirectionTable[i] = try readInstance(index: stream.readSize(), cb: nil) + } + current.indirectionTables.append(indirectionTable) + } else { + current.indirectionTables.append([]) + } + + current.slices.append(info) + } + + func readOptional(tag: Int32, format: OptionalFormat) throws -> Bool { + if current == nil { + return try stream.readOptionalImpl(readTag: tag, expectedFormat: format) + } else if current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) { + return try stream.readOptionalImpl(readTag: tag, expectedFormat: format) + } + return false + } + + func readInstance(index: Int32, cb: Callback?) throws -> Int32 { + precondition(index > 0) + + if index > 1 { + if let cb = cb { + try addPatchEntry(index: index, cb: cb) + } + return index + } + + push(sliceType: .ValueSlice) + + // + // Get the instance ID before we start reading slices. If some + // slices are skipped, the indirect instance table is still read and + // might read other instances. + // + valueIdIndex += 1 + let index = valueIdIndex + + // + // Read the first slice header. + // + try startSlice() + let mostDerivedId = current.typeId! + + var v: Value? + while true { + var updateCache = false + + if current.compactId >= 0 { + updateCache = true + + // + // Translate a compact (numeric) type ID into a class. + // + if !compactIdCache.isEmpty { + // + // Check the cache to see if we've already translated the compact type ID into a class. + // + if let cls: Value.Type = compactIdCache[current.compactId] { + v = cls.init() + updateCache = false + } + } + + // + // If we haven't already cached a class for the compact ID, then try to translate the + // compact ID into a type ID. + // + if v == nil { + current.typeId = TypeIdResolver.resolve(compactId: current.compactId) ?? "" + } + } + + if v == nil, !current.typeId.isEmpty { + v = try newInstance(typeId: current.typeId) + } + + if let v = v { + if updateCache { + precondition(current.compactId >= 0) + compactIdCache[current.compactId] = type(of: v) + } + + // + // We have an instance, get out of this loop. + // + break + } + + // + // Slice off what we don't understand. + // + try skipSlice() + + // + // If this is the last slice, keep the instance as an opaque + // UnknownSlicedValue object. + // + if current.sliceFlags.contains(.FLAG_IS_LAST_SLICE) { + // + // Provide a factory with an opportunity to supply the instance. + // We pass the "::Ice::Object" ID to indicate that this is the + // last chance to preserve the instance. + // + v = try newInstance(typeId: "::Ice::Object") + if v == nil { + v = UnknownSlicedValue(unknownTypeId: mostDerivedId) + } + + break + } + + try startSlice() // Read next Slice header for next iteration. + } + + classGraphDepth += 1 + if classGraphDepth > classGraphDepthMax { + throw MarshalException(reason: "maximum class graph depth reached") + } + + // + // Unmarshal the instance. + // + try unmarshal(index: index, v: v!) + + classGraphDepth -= 1 + + if current == nil, !patchMap.isEmpty { + // + // If any entries remain in the patch map, the sender has sent an index for an instance, but failed + // to supply the instance. + // + throw MarshalException(reason: "index for class received, but no instance") + } + + try cb?(v) + + return index + } + + func readSlicedData() throws -> SlicedData? { + // No preserved slices. + if current.slices.isEmpty { + return nil + } + + // + // The _indirectionTables member holds the indirection table for each slice + // in _slices. + // + precondition(current.slices.count == current.indirectionTables.count) + + for n in 0 ..< current.slices.count { + // + // We use the "instances" list in SliceInfo to hold references + // to the target instances. Note that the instances might not have + // been read yet in the case of a circular reference to an + // enclosing instance. + + let sz = current.indirectionTables[n].count + current.slices[n].instances = [Ice.Value]() + current.slices[n].instances.reserveCapacity(sz) + for j in 0 ..< sz { + try addPatchEntry(index: current.indirectionTables[n][j]) { v in + self.current.slices[n].instances.append(v!) + } + } + } + + return SlicedData(slices: current.slices) + } + + func push(sliceType: SliceType) { + if current == nil { + current = InstanceData(previous: nil) + } else { + current = current.next ?? InstanceData(previous: current) + } + current.sliceType = sliceType + current.skipFirstSlice = false + } +} + +public struct DictEntry { + public var key: K! + public var value: UnsafeMutablePointer! + + public init(key: K? = nil, value: UnsafeMutablePointer? = nil) { + self.key = key + self.value = value + } +} + +public class DictEntryArray { + public var values: [DictEntry] + + public init(size: Int) { + values = [DictEntry](repeating: DictEntry(), count: size) + } +} + +/// A Numeric type that can be marshaled (written) using an OutputStream and +/// unmarshaled (read) using an InputStream +public protocol StreamableNumeric: Numeric {} + +extension UInt8: StreamableNumeric {} +extension Int16: StreamableNumeric {} +extension Int32: StreamableNumeric {} +extension Int64: StreamableNumeric {} +extension Float: StreamableNumeric {} +extension Double: StreamableNumeric {} diff --git a/Sources/Ice/LocalExceptionDescription.swift b/Sources/Ice/LocalExceptionDescription.swift new file mode 100644 index 0000000..ce0f63a --- /dev/null +++ b/Sources/Ice/LocalExceptionDescription.swift @@ -0,0 +1,762 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +private extension String { + mutating func sep(_ str: String) { + guard !str.isEmpty else { + return + } + append(":\n\(str)") + } + + mutating func nl(_ str: String) { + guard !str.isEmpty else { + return + } + append("\n\(str)") + } + + mutating func failedRequest(_ ex: RequestFailedException) { + let id: String = identityToString(id: ex.id, mode: .Unicode) + sep("identity: `\(id)'") + nl("facet: \(ex.facet)") + nl("operation: \(ex.operation)") + } + + mutating func hex(_ value: UInt8) { + append("0x") + append(String(format: "%02X", value)) + } +} + +private func socketError(_ error: Int32) -> String { + if error == 0 { + return "unknown error" + } + return ICEUtil.errorToString(error) +} + +extension InitializationException { + var _InitializationExceptionDescription: String { + var s = String() + + s.sep("initialization exception") + s.sep(reason) + + return s + } +} + +extension PluginInitializationException { + var _PluginInitializationExceptionDescription: String { + var s = String() + + s.sep("plug-in initialization failed") + s.sep(reason) + + return s + } +} + +extension CollocationOptimizationException { + var _CollocationOptimizationExceptionDescription: String { + var s = String() + + s.sep("requested feature not available with collocation optimization") + + return s + } +} + +extension AlreadyRegisteredException { + var _AlreadyRegisteredExceptionDescription: String { + var s = String() + + s.sep("\(kindOfObject) with ice `\(id)' is already registered") + + return s + } +} + +extension NotRegisteredException { + var _NotRegisteredExceptionDescription: String { + var s = String() + + s.sep("no \(kindOfObject) with id `\(id)' is registered") + + return s + } +} + +extension TwowayOnlyException { + var _TwowayOnlyExceptionDescription: String { + var s = String() + + s.sep("operation `\(operation)' can only be invoked as a twoway request") + + return s + } +} + +extension CloneNotImplementedException { + var _CloneNotImplementedExceptionDescription: String { + var s = String() + + s.sep("ice_clone() must be implemented in classes derived from abstract base classes") + + return s + } +} + +extension UnknownException { + var _UnknownExceptionDescription: String { + var s = String() + + s.sep("unknown exception") + s.sep(unknown) + + return s + } +} + +extension UnknownLocalException { + var _UnknownLocalExceptionDescription: String { + var s = String() + + s.sep("unknown local exception") + s.sep(unknown) + + return s + } +} + +extension UnknownUserException { + var _UnknownUserExceptionDescription: String { + var s = String() + + s.sep("unknown user exception") + s.sep(unknown) + + return s + } +} + +extension VersionMismatchException { + var _VersionMismatchExceptionDescription: String { + var s = String() + + s.sep("Ice library version mismatch") + + return s + } +} + +extension CommunicatorDestroyedException { + var _CommunicatorDestroyedExceptionDescription: String { + var s = String() + + s.sep("communicator object destroyed") + + return s + } +} + +extension ObjectAdapterDeactivatedException { + var _ObjectAdapterDeactivatedExceptionDescription: String { + var s = String() + + s.sep("object adapter `\(name)' deactivated") + + return s + } +} + +extension ObjectAdapterIdInUseException { + var _ObjectAdapterIdInUseExceptionDescription: String { + var s = String() + + s.sep("object adapter with id `\(id)' is already in use") + + return s + } +} + +extension NoEndpointException { + var _NoEndpointExceptionDescription: String { + var s = String() + + s.sep("no suitable endpoint available for proxy `\(proxy)'") + + return s + } +} + +extension EndpointParseException { + var _EndpointParseExceptionDescription: String { + var s = String() + + s.sep("error while parsing endpoint `\(str)'") + + return s + } +} + +extension EndpointSelectionTypeParseException { + var _EndpointSelectionTypeParseExceptionDescription: String { + var s = String() + + s.sep("error while parsing endpoint selection type `\(str)'") + + return s + } +} + +extension VersionParseException { + var _VersionParseExceptionDescription: String { + var s = String() + + s.sep("error while parsing version `\(str)'") + + return s + } +} + +extension IdentityParseException { + var _IdentityParseExceptionDescription: String { + var s = String() + + s.sep("error while parsing identity `\(str)'") + + return s + } +} + +extension ProxyParseException { + var _ProxyParseExceptionDescription: String { + var s = String() + + s.sep("error while parsing proxy `\(str)'") + + return s + } +} + +extension IllegalIdentityException { + var _IllegalIdentityExceptionDescription: String { + var s = String() + let identity: String = identityToString(id: id, mode: .Unicode) + s.sep("llegal identity: `\(identity)'") + + return s + } +} + +extension IllegalServantException { + var _IllegalServantExceptionDescription: String { + var s = String() + + s.sep("illegal servant: `\(reason)'") + + return s + } +} + +extension RequestFailedException { + var _RequestFailedExceptionDescription: String { + var s = String() + + s.sep("request failed") + s.failedRequest(self) + + return s + } +} + +extension ObjectNotExistException { + var _ObjectNotExistExceptionDescription: String { + var s = String() + + s.sep("object does not exist") + s.failedRequest(self) + + return s + } +} + +extension FacetNotExistException { + var _FacetNotExistExceptionDescription: String { + var s = String() + + s.sep("facet does not exist") + s.failedRequest(self) + + return s + } +} + +extension OperationNotExistException { + var _OperationNotExistExceptionDescription: String { + var s = String() + + s.sep("operation does not exist") + s.failedRequest(self) + + return s + } +} + +extension SyscallException { + var _SyscallExceptionDescription: String { + var s = String() + + if error != 0 { + s.sep("syscall exception: \(ICEUtil.errorToString(error))") + } + + return s + } +} + +extension SocketException { + var _SocketExceptionDescription: String { + var s = String() + + s.sep("socket exception: \(socketError(error))") + + return s + } +} + +extension CFNetworkException { + var _CFNetworkExceptionDescription: String { + var s = String() + + s.sep("network exception: domain: `\(domain)' error: `\(error)'") + + return s + } +} + +extension FileException { + var _FileExceptionDescription: String { + var s = String() + + s.sep("file exception: ") + if error == 0 { + s.append("couldn't open file") + } else { + s.append(ICEUtil.errorToString(error)) + } + if !path.isEmpty { + s.nl("path: \(path)") + } + + return s + } +} + +extension ConnectFailedException { + var _ConnectFailedExceptionDescription: String { + var s = String() + + s.sep("connect failed: \(socketError(error))") + + return s + } +} + +extension ConnectionRefusedException { + var _ConnectionRefusedExceptionDescription: String { + var s = String() + + s.sep("connection refused: \(socketError(error))") + + return s + } +} + +extension ConnectionLostException { + var _ConnectionLostExceptionDescription: String { + var s = String() + + s.sep("connection lost: ") + if error == 0 { + s.append("recv() returned zero") + } else { + s.append(socketError(error)) + } + + return s + } +} + +extension DNSException { + var _DNSExceptionDescription: String { + var s = String() + + s.sep("DNS error: \(ICEUtil.errorToStringDNS(error))") + s.nl("host: \(host)") + + return s + } +} + +extension OperationInterruptedException { + var _OperationInterruptedExceptionDescription: String { + var s = String() + + s.sep("operation interrupted") + + return s + } +} + +extension TimeoutException { + var _TimeoutExceptionDescription: String { + var s = String() + + s.sep("timeout while sending or receiving data") + + return s + } +} + +extension ConnectTimeoutException { + var _ConnectTimeoutExceptionDescription: String { + var s = String() + + s.sep("timeout while establishing a connection") + + return s + } +} + +extension CloseTimeoutException { + var _CloseTimeoutExceptionDescription: String { + var s = String() + + s.sep("timeout while closing a connection") + + return s + } +} + +extension ConnectionTimeoutException { + var _ConnectionTimeoutExceptionDescription: String { + var s = String() + + s.sep("connection has timed out") + + return s + } +} + +extension InvocationTimeoutException { + var _InvocationTimeoutExceptionDescription: String { + var s = String() + + s.sep("invocation has timed out") + + return s + } +} + +extension InvocationCanceledException { + var _InvocationCanceledExceptionDescription: String { + var s = String() + + s.sep("invocation canceled") + + return s + } +} + +extension ProtocolException { + var _ProtocolExceptionDescription: String { + var s = String() + + s.sep("protocol exception") + s.sep(reason) + + return s + } +} + +extension BadMagicException { + var _BadMagicExceptionDescription: String { + var s = String() + + s.sep("unknown magic number: ") + + s.hex(badMagic[0]) + s.append(", ") + s.hex(badMagic[1]) + s.append(", ") + s.hex(badMagic[2]) + s.append(", ") + s.hex(badMagic[3]) + + if !reason.isEmpty { + s.nl(reason) + } + + return s + } +} + +extension UnsupportedProtocolException { + var _UnsupportedProtocolExceptionDescription: String { + var s = String() + + s.sep("protocol error: unsupported protocol version: \(bad)") + s.nl("(can only support protocols compatible with version \(supported))") + + return s + } +} + +extension UnsupportedEncodingException { + var _UnsupportedEncodingExceptionDescription: String { + var s = String() + + s.sep("encoding error: unsupported encoding version: \(bad)") + s.nl("(can only support encodings compatible with version \(supported))") + + if !reason.isEmpty { + s.nl(reason) + } + + return s + } +} + +extension UnknownMessageException { + var _UnknownMessageExceptionDescription: String { + var s = String() + + s.sep("protocol error: unknown message type") + s.sep(reason) + + return s + } +} + +extension ConnectionNotValidatedException { + var _ConnectionNotValidatedExceptionDescription: String { + var s = String() + + s.sep("protocol error: received message over unvalidated connection") + s.sep(reason) + + return s + } +} + +extension UnknownRequestIdException { + var _UnknownRequestIdExceptionDescription: String { + var s = String() + + s.sep("protocol error: unknown request id") + s.sep(reason) + + return s + } +} + +extension UnknownReplyStatusException { + var _UnknownReplyStatusExceptionDescription: String { + var s = String() + + s.sep("protocol error: unknown unknown reply status") + s.sep(reason) + + return s + } +} + +extension CloseConnectionException { + var _CloseConnectionExceptionDescription: String { + var s = String() + + s.sep("protocol error: connection closed") + s.sep(reason) + + return s + } +} + +extension ConnectionManuallyClosedException { + var _ConnectionManuallyClosedExceptionDescription: String { + var s = String() + + let type = graceful ? "gracefully" : "forcefully" + s.sep("protocol error: connection manually closed (\(type))") + + return s + } +} + +extension IllegalMessageSizeException { + var _IllegalMessageSizeExceptionDescription: String { + var s = String() + + s.sep("protocol error: illegal message size") + s.sep(reason) + + return s + } +} + +extension CompressionException { + var _CompressionExceptionDescription: String { + var s = String() + + s.sep("protocol error: failed to compress or uncompress data") + s.sep(reason) + + return s + } +} + +extension DatagramLimitException { + var _DatagramLimitExceptionDescription: String { + var s = String() + + s.sep("protocol error: maximum datagram payload size exceeded") + s.sep(reason) + + return s + } +} + +extension MarshalException { + var _MarshalExceptionDescription: String { + var s = String() + + s.sep("protocol error: error during marshaling or unmarshaling") + s.sep(reason) + + return s + } +} + +extension ProxyUnmarshalException { + var _ProxyUnmarshalExceptionDescription: String { + var s = String() + + s.sep("protocol error: inconsistent proxy data during unmarshaling") + s.sep(reason) + + return s + } +} + +extension UnmarshalOutOfBoundsException { + var _UnmarshalOutOfBoundsExceptionDescription: String { + var s = String() + + s.sep("protocol error: out of bounds during unmarshaling") + s.sep(reason) + + return s + } +} + +extension NoValueFactoryException { + var _NoValueFactoryExceptionDescription: String { + var s = String() + + s.sep("protocol error: no suitable value factory found for `\(type)'") + s.sep(reason) + + return s + } +} + +extension UnexpectedObjectException { + var _UnexpectedObjectExceptionDescription: String { + var s = String() + + s.sep("unexpected class instance of type `\(type)'; expected instance of type `\(expectedType)'") + s.sep(reason) + + return s + } +} + +extension MemoryLimitException { + var _MemoryLimitExceptionDescription: String { + var s = String() + + s.sep("protocol error: memory limit exceeded") + s.sep(reason) + + return s + } +} + +extension StringConversionException { + var _StringConversionExceptionDescription: String { + var s = String() + + s.sep("protocol error: string conversion failed") + s.sep(reason) + + return s + } +} + +extension EncapsulationException { + var _EncapsulationExceptionDescription: String { + var s = String() + + s.sep("protocol error: illegal encapsulation") + s.sep(reason) + + return s + } +} + +extension FeatureNotSupportedException { + var _FeatureNotSupportedExceptionDescription: String { + var s = String() + + s.sep("feature: `\(unsupportedFeature)' is not supported") + + return s + } +} + +extension SecurityException { + var _SecurityExceptionDescription: String { + var s = String() + + s.sep("security exception") + s.sep(reason) + + return s + } +} + +extension FixedProxyException { + var _FixedProxyExceptionDescription: String { + var s = String() + + s.sep("fixed proxy exception") + + return s + } +} + +extension ResponseSentException { + var _ResponseSentExceptionDescription: String { + var s = String() + + s.sep("response sent exception") + + return s + } +} diff --git a/Sources/Ice/LocalExceptionFactory.swift b/Sources/Ice/LocalExceptionFactory.swift new file mode 100644 index 0000000..9c3ae6d --- /dev/null +++ b/Sources/Ice/LocalExceptionFactory.swift @@ -0,0 +1,303 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class ExceptionFactory: ICEExceptionFactory { + static func initializationException(_ reason: String, file: String, line: Int) -> Error { + return InitializationException(reason: reason, file: file, line: line) + } + + static func pluginInitializationException(_ reason: String, file: String, line: Int) -> Error { + return PluginInitializationException(reason: reason, file: file, line: line) + } + + static func collocationOptimizationException(_ file: String, line: Int) -> Error { + return CollocationOptimizationException(file: file, line: line) + } + + static func alreadyRegisteredException(_ kindOfObject: String, id: String, file: String, line: Int) -> Error { + return AlreadyRegisteredException(kindOfObject: kindOfObject, id: id, file: file, line: line) + } + + static func notRegisteredException(_ kindOfObject: String, id: String, file: String, line: Int) -> Error { + return NotRegisteredException(kindOfObject: kindOfObject, id: id, file: file, line: line) + } + + static func twowayOnlyException(_ operation: String, file: String, line: Int) -> Error { + return TwowayOnlyException(operation: operation, file: file, line: line) + } + + static func cloneNotImplementedException(_ file: String, line: Int) -> Error { + return CloneNotImplementedException(file: file, line: line) + } + + static func versionMismatchException(_ file: String, line: Int) -> Error { + return VersionMismatchException(file: file, line: line) + } + + static func communicatorDestroyedException(_ file: String, line: Int) -> Error { + return CommunicatorDestroyedException(file: file, line: line) + } + + static func objectAdapterDeactivatedException(_ name: String, file: String, line: Int) -> Error { + return ObjectAdapterDeactivatedException(name: name, file: file, line: line) + } + + static func objectAdapterIdInUseException(_ id: String, file: String, line: Int) -> Error { + return ObjectAdapterIdInUseException(id: id, file: file, line: line) + } + + static func noEndpointException(_ proxy: String, file: String, line: Int) -> Error { + return NoEndpointException(proxy: proxy, file: file, line: line) + } + + static func endpointParseException(_ str: String, file: String, line: Int) -> Error { + return EndpointParseException(str: str, file: file, line: line) + } + + static func endpointSelectionTypeParseException(_ str: String, file: String, line: Int) -> Error { + return EndpointSelectionTypeParseException(str: str, file: file, line: line) + } + + static func versionParseException(_ str: String, file: String, line: Int) -> Error { + return VersionParseException(str: str, file: file, line: line) + } + + static func identityParseException(_ str: String, file: String, line: Int) -> Error { + return IdentityParseException(str: str, file: file, line: line) + } + + static func proxyParseException(_ str: String, file: String, line: Int) -> Error { + return ProxyParseException(str: str, file: file, line: line) + } + + static func illegalIdentityException(_ name: String, category: String, file: String, line: Int) -> Error { + return IllegalIdentityException(id: Identity(name: name, category: category), file: file, line: line) + } + + static func illegalServantException(_ reason: String, file: String, line: Int) -> Error { + return IllegalServantException(reason: reason, file: file, line: line) + } + + static func dNSException(_ error: Int32, host: String, file: String, line: Int) -> Error { + return DNSException(error: error, host: host, file: file, line: line) + } + + static func operationInterruptedException(_ file: String, line: Int) -> Error { + return OperationInterruptedException(file: file, line: line) + } + + static func invocationCanceledException(_ file: String, line: Int) -> Error { + return InvocationCanceledException(file: file, line: line) + } + + static func featureNotSupportedException(_ unsupportedFeature: String, file: String, line: Int) -> Error { + return FeatureNotSupportedException(unsupportedFeature: unsupportedFeature, file: file, line: line) + } + + static func fixedProxyException(_ file: String, line: Int) -> Error { + return FixedProxyException(file: file, line: line) + } + + static func responseSentException(_ file: String, line: Int) -> Error { + return ResponseSentException(file: file, line: line) + } + + static func securityException(_ reason: String, file: String, line: Int) -> Error { + return SecurityException(reason: reason, file: file, line: line) + } + + static func localException(_ file: String, line: Int) -> Error { + return LocalException(file: file, line: line) + } + + static func unknownLocalException(_ unknown: String, file: String, line: Int) -> Error { + return UnknownLocalException(unknown: unknown, file: file, line: line) + } + + static func unknownUserException(_ unknown: String, file: String, line: Int) -> Error { + return UnknownUserException(unknown: unknown, file: file, line: line) + } + + static func unknownException(_ unknown: String, file: String, line: Int) -> Error { + return UnknownException(unknown: unknown, file: file, line: line) + } + + static func objectNotExistException(_ name: String, category: String, facet: String, operation: String, + file: String, line: Int) -> Error { + return ObjectNotExistException(id: Identity(name: name, category: category), facet: facet, operation: operation, + file: file, line: line) + } + + static func facetNotExistException(_ name: String, category: String, facet: String, operation: String, + file: String, line: Int) -> Error { + return FacetNotExistException(id: Identity(name: name, category: category), facet: facet, operation: operation, + file: file, line: line) + } + + static func operationNotExistException(_ name: String, + category: String, + facet: String, + operation: String, file: String, line: Int) -> Error { + return OperationNotExistException(id: Identity(name: name, + category: category), + facet: facet, + operation: operation, file: file, line: line) + } + + static func requestFailedException(_ name: String, category: String, facet: String, operation: String, + file: String, line: Int) -> Error { + return RequestFailedException(id: Identity(name: name, category: category), facet: facet, operation: operation, + file: file, line: line) + } + + static func connectionRefusedException(_ error: Int32, file: String, line: Int) -> Error { + return ConnectionRefusedException(error: error, file: file, line: line) + } + + static func fileException(_ error: Int32, path: String, file: String, line: Int) -> Error { + return FileException(error: error, path: path, file: file, line: line) + } + + static func connectFailedException(_ error: Int32, file: String, line: Int) -> Error { + return ConnectionRefusedException(error: error, file: file, line: line) + } + + static func connectionLostException(_ error: Int32, file: String, line: Int) -> Error { + return ConnectionLostException(error: error, file: file, line: line) + } + + static func socketException(_ error: Int32, file: String, line: Int) -> Error { + return SocketException(error: error, file: file, line: line) + } + + static func syscallException(_ error: Int32, file: String, line: Int) -> Error { + return SyscallException(error: error, file: file, line: line) + } + + static func connectTimeoutException(_ file: String, line: Int) -> Error { + return ConnectTimeoutException(file: file, line: line) + } + + static func closeTimeoutException(_ file: String, line: Int) -> Error { + return CloseTimeoutException(file: file, line: line) + } + + static func connectionTimeoutException(_ file: String, line: Int) -> Error { + return ConnectionTimeoutException(file: file, line: line) + } + + static func invocationTimeoutException(_ file: String, line: Int) -> Error { + return InvocationTimeoutException(file: file, line: line) + } + + static func timeoutException(_ file: String, line: Int) -> Error { + return TimeoutException(file: file, line: line) + } + + static func badMagicException(_ reason: String, badMagic: Data, file: String, line: Int) -> Error { + return BadMagicException(reason: reason, badMagic: badMagic, file: file, line: line) + } + + static func unsupportedProtocolException(_ reason: String, + badMajor: UInt8, + badMinor: UInt8, + supportedMajor: UInt8, + supportedMinor: UInt8, file: String, line: Int) -> Error { + return UnsupportedProtocolException(reason: reason, + bad: ProtocolVersion(major: badMajor, minor: badMinor), + supported: ProtocolVersion(major: supportedMajor, minor: supportedMinor), + file: file, line: line) + } + + static func unsupportedEncodingException(_ reason: String, + badMajor: UInt8, + badMinor: UInt8, + supportedMajor: UInt8, + supportedMinor: UInt8, file: String, line: Int) -> Error { + return UnsupportedEncodingException(reason: reason, + bad: EncodingVersion(major: badMajor, minor: badMinor), + supported: EncodingVersion(major: supportedMajor, minor: supportedMinor), + file: file, line: line) + } + + static func unknownMessageException(_ reason: String, file: String, line: Int) -> Error { + return UnknownMessageException(reason: reason, file: file, line: line) + } + + static func connectionNotValidatedException(_ reason: String, file: String, line: Int) -> Error { + return ConnectionNotValidatedException(reason: reason, file: file, line: line) + } + + static func unknownRequestIdException(_ reason: String, file: String, line: Int) -> Error { + return UnknownRequestIdException(reason: reason, file: file, line: line) + } + + static func unknownReplyStatusException(_ reason: String, file: String, line: Int) -> Error { + return UnknownReplyStatusException(reason: reason, file: file, line: line) + } + + static func closeConnectionException(_ reason: String, file: String, line: Int) -> Error { + return CloseConnectionException(reason: reason, file: file, line: line) + } + + static func connectionManuallyClosedException(_ graceful: Bool, file: String, line: Int) -> Error { + return ConnectionManuallyClosedException(graceful: graceful, file: file, line: line) + } + + static func illegalMessageSizeException(_ reason: String, file: String, line: Int) -> Error { + return IllegalMessageSizeException(reason: reason, file: file, line: line) + } + + static func compressionException(_ reason: String, file: String, line: Int) -> Error { + return CompressionException(reason: reason, file: file, line: line) + } + + static func datagramLimitException(_ reason: String, file: String, line: Int) -> Error { + return DatagramLimitException(reason: reason, file: file, line: line) + } + + static func proxyUnmarshalException(_ reason: String, file: String, line: Int) -> Error { + return ProxyUnmarshalException(reason: reason, file: file, line: line) + } + + static func unmarshalOutofBoundsException(_ reason: String, file: String, line: Int) -> Error { + return UnmarshalOutOfBoundsException(reason: reason, file: file, line: line) + } + + static func noValueFactoryException(_ reason: String, type: String, file: String, line: Int) -> Error { + return NoValueFactoryException(reason: reason, type: type, file: file, line: line) + } + + static func unexpectedObjectException(_ reason: String, type: String, expectedType: String, + file: String, line: Int) -> Error { + return UnexpectedObjectException(reason: reason, type: type, expectedType: expectedType, + file: file, line: line) + } + + static func memoryLimitException(_ reason: String, file: String, line: Int) -> Error { + return MemoryLimitException(reason: reason, file: file, line: line) + } + + static func stringConversionException(_ reason: String, file: String, line: Int) -> Error { + return StringConversionException(reason: reason, file: file, line: line) + } + + static func encapsulationException(_ reason: String, file: String, line: Int) -> Error { + return EncapsulationException(reason: reason, file: file, line: line) + } + + static func marshalException(_ reason: String, file: String, line: Int) -> Error { + return MarshalException(reason: reason, file: file, line: line) + } + + static func protocolException(_ reason: String, file: String, line: Int) -> Error { + return ProtocolException(reason: reason, file: file, line: line) + } + + static func runtimeError(_ message: String) -> Error { + return RuntimeError(message) + } +} diff --git a/Sources/Ice/LocalObject.swift b/Sources/Ice/LocalObject.swift new file mode 100644 index 0000000..672eda7 --- /dev/null +++ b/Sources/Ice/LocalObject.swift @@ -0,0 +1,50 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class LocalObject { + let handle: Handle + + init(handle: Handle) { + precondition(handle.swiftRef == nil) + self.handle = handle + self.handle.swiftRef = self + } +} + +extension ICELocalObject { + // + // getSwiftObject returns the Swift object holding a handle to this ICELocalObject or initializes a new one + // + func getSwiftObject(_: LocalObjectClass.Type, + initializer: () -> LocalObjectClass) -> LocalObjectClass + where Handle: ICELocalObject, LocalObjectClass: LocalObject { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + + if let swiftClass = swiftRef { + precondition(swiftClass is LocalObjectClass) + // swiftlint:disable force_cast + return swiftClass as! LocalObjectClass + // swiftlint:enable force_cast + } + + return initializer() + } + + // + // getCachedSwiftObject returns the Swift object holding a handle to this ICELocalObject + // + func getCachedSwiftObject(_: LocalObjectClass.Type) -> LocalObjectClass + where Handle: ICELocalObject, LocalObjectClass: LocalObject { + guard let swiftClass = swiftRef else { + preconditionFailure("swiftRef is nil") + } + guard let c = swiftClass as? LocalObjectClass else { + preconditionFailure("Invalid swift type for ICELocalObject") + } + return c + } +} diff --git a/Sources/Ice/LoggerWrapper.swift b/Sources/Ice/LoggerWrapper.swift new file mode 100644 index 0000000..f15ab0b --- /dev/null +++ b/Sources/Ice/LoggerWrapper.swift @@ -0,0 +1,67 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +// Wraps Swift Loggers so they can be called by ObjC/C++ +class LoggerWrapper: ICELoggerProtocol { + let handle: Logger + + init(handle: Logger) { + self.handle = handle + } + + func print(_ message: String) { + handle.print(message) + } + + func trace(category: String, message: String) { + handle.trace(category: category, message: message) + } + + func warning(_ message: String) { + handle.warning(message) + } + + func error(_ message: String) { + handle.error(message) + } + + func getPrefix() -> String { + return handle.getPrefix() + } + + func cloneWithPrefix(_ prefix: String) -> Any { + return handle.cloneWithPrefix(prefix) + } +} + +// Wraps Ice C++ logger +class ObjcLoggerWrapper: LocalObject, Logger { + func print(_ message: String) { + handle.print(message) + } + + func trace(category: String, message: String) { + handle.trace(category: category, message: message) + } + + func warning(_ message: String) { + handle.warning(message) + } + + func error(_ message: String) { + handle.error(message) + } + + func getPrefix() -> String { + return handle.getPrefix() + } + + func cloneWithPrefix(_ prefix: String) -> Logger { + // swiftlint:disable force_cast + return ObjcLoggerWrapper(handle: handle.cloneWithPrefix(prefix) as! ICELogger) + // swiftlint:enable force_cast + } +} diff --git a/Sources/Ice/Mutex.swift b/Sources/Ice/Mutex.swift new file mode 100644 index 0000000..633f590 --- /dev/null +++ b/Sources/Ice/Mutex.swift @@ -0,0 +1,27 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation + +struct Mutex { + private var unfairLock = os_unfair_lock() + + mutating func lock() { + os_unfair_lock_lock(&unfairLock) + } + + mutating func locked() -> Bool { + return os_unfair_lock_trylock(&unfairLock) + } + + mutating func unlock() { + os_unfair_lock_unlock(&unfairLock) + } + + mutating func sync(_ closure: () throws -> R) rethrows -> R { + lock() + defer { unlock() } + return try closure() + } +} diff --git a/Sources/Ice/NativePropertiesAdmin.swift b/Sources/Ice/NativePropertiesAdmin.swift new file mode 100644 index 0000000..66f9fb3 --- /dev/null +++ b/Sources/Ice/NativePropertiesAdmin.swift @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// Closure called when the communicator's properties have been updated. +/// +/// - parameter: `PropertyDict` A dictionary containing the properties that were added, +/// changed or removed, with a removed property denoted by an entry whose value is an +/// empty string. +public typealias PropertiesAdminUpdateCallback = (PropertyDict) -> Void + +/// Closure used to remove the properties update callback. +public typealias PropertiesAdminRemoveCallback = () -> Void + +/// Base protocol for the Properties admin facet. +public protocol NativePropertiesAdmin { + /// Register an update callback that will be invoked when property updates occur. + /// + /// - parameter cb: `PropertiesAdminUpdateCallback` - The callback. + /// + /// - returns: A closure that can be invoked to remove the callback. + func addUpdateCallback(_ cb: @escaping PropertiesAdminUpdateCallback) -> PropertiesAdminRemoveCallback +} diff --git a/Sources/Ice/Object.swift b/Sources/Ice/Object.swift new file mode 100644 index 0000000..8cea29e --- /dev/null +++ b/Sources/Ice/Object.swift @@ -0,0 +1,154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl +import PromiseKit + +/// Request is an opaque type that represents an incoming request. +public typealias Request = Incoming + +/// A request dispatcher (Disp) is a helper struct used by object adapters to dispatch +/// requests to servants. +public protocol Disp { + /// Dispatch request to servant. + /// + /// - parameter request: `Ice.Request` - The incoming request. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func dispatch(request: Request, current: Current) throws -> Promise? +} + +/// A SliceTraits struct describes a Slice interface, class or exception. +public protocol SliceTraits { + /// List of all type-ids. + static var staticIds: [String] { get } + + /// Most derived type-id. + static var staticId: String { get } +} + +/// The base class for servants. +public protocol Object { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface. + func ice_id(current: Current) throws -> String + + /// Returns the Slice type IDs of the interfaces supported by this object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `[String]` The Slice type IDs of the interfaces supported by this object, in base-to-derived + /// order. The first element of the returned array is always `::Ice::Object`. + func ice_ids(current: Current) throws -> [String] + + /// Tests whether this object supports a specific Slice interface. + /// + /// - parameter s: `String` - The type ID of the Slice interface to test against. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Bool` - True if this object has the interface specified by s or + /// derives from the interface specified by s. + func ice_isA(id: String, current: Current) throws -> Bool + + /// Tests whether this object can be reached. + /// + /// - parameter current: The Current object for the dispatch. + func ice_ping(current: Current) throws +} + +public extension Object { + func _iceD_ice_id(incoming inS: Incoming, current: Current) throws -> Promise? { + try inS.readEmptyParams() + + let returnValue = try ice_id(current: current) + + return inS.setResult { ostr in + ostr.write(returnValue) + } + } + + func _iceD_ice_ids(incoming inS: Incoming, current: Current) throws -> Promise? { + try inS.readEmptyParams() + + let returnValue = try ice_ids(current: current) + + return inS.setResult { ostr in + ostr.write(returnValue) + } + } + + func _iceD_ice_isA(incoming inS: Incoming, current: Current) throws -> Promise? { + let ident: String = try inS.read { istr in + try istr.read() + } + + let returnValue = try ice_isA(id: ident, current: current) + + return inS.setResult { ostr in + ostr.write(returnValue) + } + } + + func _iceD_ice_ping(incoming inS: Incoming, current: Current) throws -> Promise? { + try inS.readEmptyParams() + try ice_ping(current: current) + return inS.setResult() + } +} + +/// Traits for Object. +public struct ObjectTraits: SliceTraits { + public static let staticIds = ["::Ice::Object"] + public static let staticId = "::Ice::Object" +} + +/// class ObjectI provides the default implementation of Object operations (ice_id, +/// ice_ping etc.) for a given Slice interface. +open class ObjectI: Object { + public init() {} + + open func ice_id(current _: Current) throws -> String { + return T.staticId + } + + open func ice_ids(current _: Current) throws -> [String] { + return T.staticIds + } + + open func ice_isA(id: String, current _: Current) throws -> Bool { + return T.staticIds.contains(id) + } + + open func ice_ping(current _: Current) throws { + // Do nothing + } +} + +/// Request dispatcher for plain Object servants. +public struct ObjectDisp: Disp { + public let servant: Object + + public init(_ servant: Object) { + self.servant = servant + } + + public func dispatch(request: Request, current: Current) throws -> Promise? { + switch current.operation { + case "ice_id": + return try servant._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try servant._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try servant._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try servant._iceD_ice_ping(incoming: request, current: current) + default: + throw OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} diff --git a/Sources/Ice/ObjectAdapterI.swift b/Sources/Ice/ObjectAdapterI.swift new file mode 100644 index 0000000..ac1f8ee --- /dev/null +++ b/Sources/Ice/ObjectAdapterI.swift @@ -0,0 +1,243 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class ObjectAdapterI: LocalObject, ObjectAdapter, ICEBlobjectFacade, Hashable { + private let communicator: Communicator + let servantManager: ServantManager + + init(handle: ICEObjectAdapter, communicator: Communicator) { + self.communicator = communicator + servantManager = ServantManager(adapterName: handle.getName(), communicator: communicator) + super.init(handle: handle) + + handle.registerDefaultServant(self) + } + + func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(self).hashValue) + } + + static func == (lhs: ObjectAdapterI, rhs: ObjectAdapterI) -> Bool { + return lhs === rhs + } + + func getName() -> String { + return handle.getName() + } + + func getCommunicator() -> Communicator { + return communicator + } + + func activate() throws { + try autoreleasepool { + try handle.activate() + } + } + + func hold() { + handle.hold() + } + + func waitForHold() { + handle.waitForHold() + } + + func deactivate() { + handle.deactivate() + } + + func waitForDeactivate() { + handle.waitForDeactivate() + } + + func isDeactivated() -> Bool { + return handle.isDeactivated() + } + + func destroy() { + return handle.destroy() + } + + func add(servant: Disp, id: Identity) throws -> ObjectPrx { + return try addFacet(servant: servant, id: id, facet: "") + } + + func addFacet(servant: Disp, id: Identity, facet: String) throws -> ObjectPrx { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + try servantManager.addServant(servant: servant, id: id, facet: facet) + return try createProxy(id).ice_facet(facet) + } + + func addWithUUID(_ servant: Disp) throws -> ObjectPrx { + return try addFacetWithUUID(servant: servant, facet: "") + } + + func addFacetWithUUID(servant: Disp, facet: String) throws -> ObjectPrx { + return try addFacet(servant: servant, id: Identity(name: UUID().uuidString, category: ""), facet: facet) + } + + func addDefaultServant(servant: Disp, category: String) throws { + try servantManager.addDefaultServant(servant: servant, category: category) + } + + func remove(_ id: Identity) throws -> Disp { + return try removeFacet(id: id, facet: "") + } + + func removeFacet(id: Identity, facet: String) throws -> Disp { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try servantManager.removeServant(id: id, facet: facet) + } + + func removeAllFacets(_ id: Identity) throws -> FacetMap { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try servantManager.removeAllFacets(id: id) + } + + func removeDefaultServant(_ category: String) throws -> Disp { + return try servantManager.removeDefaultServant(category: category) + } + + func find(_ id: Identity) -> Disp? { + return findFacet(id: id, facet: "") + } + + func findFacet(id: Identity, facet: String) -> Disp? { + return servantManager.findServant(id: id, facet: facet) + } + + func findAllFacets(_ id: Identity) -> FacetMap { + return servantManager.findAllFacets(id: id) + } + + func findByProxy(_ proxy: ObjectPrx) -> Disp? { + return findFacet(id: proxy.ice_getIdentity(), facet: proxy.ice_getFacet()) + } + + func addServantLocator(locator: ServantLocator, category: String) throws { + try servantManager.addServantLocator(locator: locator, category: category) + } + + func removeServantLocator(_ category: String) throws -> ServantLocator { + return try servantManager.removeServantLocator(category: category) + } + + func findServantLocator(_ category: String) -> ServantLocator? { + return servantManager.findServantLocator(category: category) + } + + func findDefaultServant(_ category: String) -> Disp? { + return servantManager.findDefaultServant(category: category) + } + + func createProxy(_ id: Identity) throws -> ObjectPrx { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try autoreleasepool { + try ObjectPrxI(handle: handle.createProxy(name: id.name, category: id.category), + communicator: communicator) + } + } + + func createDirectProxy(_ id: Identity) throws -> ObjectPrx { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try autoreleasepool { + try ObjectPrxI(handle: handle.createDirectProxy(name: id.name, category: id.category), + communicator: communicator) + } + } + + func createIndirectProxy(_ id: Identity) throws -> ObjectPrx { + precondition(!id.name.isEmpty, "Identity cannot have an empty name") + return try autoreleasepool { + try ObjectPrxI(handle: handle.createIndirectProxy(name: id.name, category: id.category), + communicator: communicator) + } + } + + func setLocator(_ locator: LocatorPrx?) { + let l = locator as? LocatorPrxI + handle.setLocator(l?.handle ?? nil) + } + + func getLocator() -> LocatorPrx? { + guard let locatorHandle = handle.getLocator() else { + return nil + } + return LocatorPrxI.fromICEObjectPrx(handle: locatorHandle) + } + + func getEndpoints() -> EndpointSeq { + return handle.getEndpoints().fromObjc() + } + + func refreshPublishedEndpoints() throws { + try autoreleasepool { + try handle.refreshPublishedEndpoints() + } + } + + func getPublishedEndpoints() -> EndpointSeq { + return handle.getPublishedEndpoints().fromObjc() + } + + func setPublishedEndpoints(_ newEndpoints: EndpointSeq) throws { + try autoreleasepool { + try handle.setPublishedEndpoints(newEndpoints.toObjc()) + } + } + + func getDispatchQueue() throws -> DispatchQueue { + return try autoreleasepool { + try handle.getDispatchQueue() + } + } + + func facadeInvoke(_ adapter: ICEObjectAdapter, + inEncapsBytes: UnsafeMutableRawPointer, + inEncapsCount: Int, + con: ICEConnection?, + name: String, + category: String, + facet: String, + operation: String, + mode: UInt8, + context: [String: String], + requestId: Int32, + encodingMajor: UInt8, + encodingMinor: UInt8, + response: @escaping ICEBlobjectResponse, + exception: @escaping ICEBlobjectException) { + precondition(handle == adapter) + + let connection = con?.getSwiftObject(ConnectionI.self) { ConnectionI(handle: con!) } ?? nil + + let current = Current(adapter: self, + con: connection, + id: Identity(name: name, category: category), + facet: facet, + operation: operation, + mode: OperationMode(rawValue: mode)!, + ctx: context, + requestId: requestId, + encoding: EncodingVersion(major: encodingMajor, minor: encodingMinor)) + + let incoming = Incoming(istr: InputStream(communicator: communicator, + encoding: EncodingVersion(major: encodingMajor, + minor: encodingMinor), + bytes: Data(bytesNoCopy: inEncapsBytes, count: inEncapsCount, + deallocator: .none)), + response: response, + exception: exception, + current: current) + + incoming.invoke(servantManager) + } + + func facadeRemoved() { + servantManager.destroy() + } +} diff --git a/Sources/Ice/OptionalFormat.swift b/Sources/Ice/OptionalFormat.swift new file mode 100644 index 0000000..8e39912 --- /dev/null +++ b/Sources/Ice/OptionalFormat.swift @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// Helper for encoding of optional member or parameter. +public enum OptionalFormat: UInt8 { + case F1 = 0 + case F2 = 1 + case F4 = 2 + case F8 = 3 + case Size = 4 + case VSize = 5 + case FSize = 6 + case Class = 7 + + init?(fixedSize: Int) { + switch fixedSize { + case 1: + self.init(rawValue: 0) + case 2: + self.init(rawValue: 1) + case 4: + self.init(rawValue: 2) + case 8: + self.init(rawValue: 3) + default: + return nil + } + } +} diff --git a/Sources/Ice/OutputStream.swift b/Sources/Ice/OutputStream.swift new file mode 100644 index 0000000..45e3d25 --- /dev/null +++ b/Sources/Ice/OutputStream.swift @@ -0,0 +1,1076 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import IceImpl + +/// Stream class to write (marshal) Slice types into a sequence of bytes. +public class OutputStream { + private var data: Data = Data(capacity: 240) + private let communicator: Communicator + private let encoding: EncodingVersion + private let encoding_1_0: Bool + private let format: FormatType + + private var encaps: Encaps! + + /// Determines the current encoding version. + var currentEncoding: EncodingVersion { + return encaps != nil ? encaps.encoding : encoding + } + + public convenience init(communicator: Communicator) { + let encoding = (communicator as! CommunicatorI).defaultsAndOverrides.defaultEncoding + self.init(communicator: communicator, encoding: encoding) + } + + public init(communicator: Communicator, encoding: EncodingVersion) { + self.communicator = communicator + self.encoding = encoding + encoding_1_0 = encoding == Encoding_1_0 + format = (communicator as! CommunicatorI).defaultsAndOverrides.defaultFormat + } + + /// Writes the start of an encapsulation to the stream. + public func startEncapsulation() { + startEncapsulation(encoding: encoding, format: FormatType.DefaultFormat) + } + + /// Writes the start of an encapsulation to the stream. + /// + /// - parameter encoding: `Ice.EncodingVersion` - The encoding version of the encapsulation. + /// + /// - parameter format: `Ice.FormatType` - Specify the compact or sliced format. + public func startEncapsulation(encoding: EncodingVersion, format: FormatType) { + precondition(encaps == nil, "Nested or sequential encapsulations are not supported") + encaps = Encaps(encoding: encoding, format: format, start: data.count) + write(Int32(0)) // Placeholder for the encapsulation length. + write(encaps.encoding) + } + + /// Ends the previous encapsulation. + public func endEncapsulation() { + // Size includes size and version. + let start = encaps.start + let sz = Int32(data.count - start) + write(bytesOf: sz, at: start) + } + + /// Writes an empty encapsulation using the given encoding version. + /// + /// - parameter encoding: `Ice.EncodingVersion` - The encoding version of the encapsulation. + func writeEmptyEncapsulation(_ encoding: EncodingVersion) { + write(Int32(6)) // Size + write(encoding) + } + + /// Writes a pre-encoded encapsulation. + /// + /// - parameter _: `Data` - The encapsulation data. + func writeEncapsulation(_ v: Data) { + precondition(v.count >= 6, "Encapsulation is invalid. Size is too small.") + data.append(v) + } + + func getCount() -> Int { + return data.count + } + + /// Overwrite an existing Numeric at the specified position + /// + func write(bytesOf value: Element, at: Int) where Element: StreamableNumeric { + withUnsafePointer(to: value) { ptr in + self.data.replaceSubrange(at ..< at + MemoryLayout.size, + with: UnsafeRawPointer(ptr), count: MemoryLayout.size) + } + } + + /// Marks the start of a class instance. + /// + /// - parameter data: `Ice.SlicedData?` - Preserved slices for this instance, or nil. + public func startValue(data: SlicedData?) { + precondition(encaps.encoder != nil) + encaps.encoder.startInstance(type: .ValueSlice, data: data) + } + + /// Marks the end of a class instance. + public func endValue() { + precondition(encaps.encoder != nil) + encaps.encoder.endInstance() + } + + /// Marks the start of a user exception. + /// + /// - parameter data: `Ice.SlicedData` Preserved slices for this exception, or nil. + public func startException(data: SlicedData?) { + precondition(encaps.encoder != nil) + encaps.encoder.startInstance(type: .ExceptionSlice, data: data) + } + + /// Marks the end of a user exception. + public func endException() { + precondition(encaps.encoder != nil) + encaps.encoder.endInstance() + } + + private func initEncaps() { + if encaps == nil { + encaps = Encaps(encoding: encoding, format: format, start: 0) + } else if encaps.format == .DefaultFormat { + encaps.format = format + } + + // Lazy initialization. + if encaps.encoder == nil { + if encaps.encoding_1_0 { + encaps.encoder = EncapsEncoder10(os: self, encaps: encaps) + } else { + encaps.encoder = EncapsEncoder11(os: self, encaps: encaps) + } + } + } + + /// Writes the state of Slice classes whose index was previously written with writeValue() to the stream. + public func writePendingValues() { + if encaps != nil, encaps.encoder != nil { + encaps.encoder.writePendingValues() + } else if encoding_1_0 { + // If using the 1.0 encoding and no instances were written, we + // still write an empty sequence for pending instances if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no instances + // are written we do marshal an empty sequence if marshaled + // data types use classes. + write(size: Int32(0)) + } + } + + /// Returns the underlying data + public func finished() -> Data { + return data + } + + /// Marks the start of a new slice for a class instance or user exception. + /// + /// - parameter typeId: `String` - The Slice type ID corresponding to this slice. + /// + /// - parameter compactId: `Int32` - The Slice compact type ID corresponding to this + /// slice or -1 if no compact ID is defined for the type ID. + /// + /// - parameter last: `Bool` - True if this is the last slice, false otherwise. + public func startSlice(typeId: String, compactId: Int32, last: Bool) { + precondition(encaps != nil && encaps.encoder != nil) + encaps.encoder.startSlice(typeId: typeId, compactId: compactId, last: last) + } + + /// Marks the end of a slice for a class instance or user exception. + public func endSlice() { + precondition(encaps != nil && encaps.encoder != nil) + encaps.encoder.endSlice() + } +} + +public extension OutputStream { + /// Writes a numeric value to the stream. + /// + /// - parameter _: `Element` - The numeric value to write. + func write(_ v: Element) where Element: StreamableNumeric { + // We assume a little-endian platform + withUnsafePointer(to: v) { ptr in + self.data.append(UnsafeBufferPointer(start: ptr, count: 1)) + } + } + + /// Writes an optional numeric value to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `Element?` - The numeric value to write. + func write(tag: Int32, value: Element?) where Element: StreamableNumeric { + let format = OptionalFormat(fixedSize: MemoryLayout.size) + if let val = value { + if writeOptional(tag: tag, format: format!) { + write(val) + } + } + } + + /// Writes a sequence of numeric values to the stream. + /// + /// - parameter _: `[Element]` - The sequence of numeric values. + func write(_ v: [Element]) where Element: StreamableNumeric { + write(size: v.count) + + if v.count <= 1 || MemoryLayout.size == MemoryLayout.stride { + v.withUnsafeBufferPointer { buf in + self.data.append(buf) + } + } else { + for e in v { + write(e) + } + } + } + + /// Writes an optional sequence of numeric values to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `[Element]?` - The sequence of numeric numeric values to write. + func write(tag: Int32, value: [Element]?) where Element: StreamableNumeric { + if let val = value { + if writeOptionalVSize(tag: tag, len: val.count, elemSize: MemoryLayout.size) { + write(val) + } + } + } + + // + // UInt8 optimization + // + + /// Writes a byte to the stream. + /// + /// - parameter _: `UInt8` - The byte to write. + func write(_ v: UInt8) { + data.append(v) + } + + /// Writes a sequence of bytes to the stream. + /// + /// - parameter _: `[UInt8]` - The sequence of bytes to write. + func write(_ v: [UInt8]) { + write(size: v.count) + if v.count > 0 { + data.append(contentsOf: v) + } + } + + /// Writes a sequence of bytes to the stream. + /// + /// - parameter _: `Data` - The sequence of bytes to write. + func write(_ v: Data) { + write(size: v.count) + if v.count > 0 { + data.append(v) + } + } + + /// Writes an optional sequence of bytes to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `Data` - The sequence of bytes to write. + func write(tag: Int32, value: Data?) { + if let val = value { + // Note: not the same as larger Numeric + if writeOptional(tag: tag, format: .VSize) { + write(val) + } + } + } + + /// Writes a boolean value to the stream. + /// + /// - parameter _: `Bool` - The boolean value to write. + func write(_ v: Bool) { + write(UInt8(v == true ? 1 : 0)) + } + + /// Writes an optional boolean value to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `Bool?` - The boolean value to write. + func write(tag: Int32, value: Bool?) { + if let val = value { + if writeOptional(tag: tag, format: .F1) { + write(val) + } + } + } + + /// Writes a sequence of boolean values to the stream. + /// + /// - parameter _: `[Bool]` - The sequence of boolean values to write. + func write(_ v: [Bool]) { + write(size: v.count) + if MemoryLayout.size == 1, MemoryLayout.stride == 1 { + v.withUnsafeBufferPointer { buf in + self.data.append(buf) + } + } else { + fatalError("Unsupported Bool layout") + } + } + + /// Writes an optional sequence of boolean values to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `[Bool]?` - The sequence of boolean values to write. + func write(tag: Int32, value: [Bool]?) { + if let val = value { + if writeOptional(tag: tag, format: .VSize) { + write(val) + } + } + } + + /// Writes a size to the stream. + /// + /// - parameter size: `Int32` - The size to write. + func write(size: Int32) { + if size > 254 { + write(UInt8(255)) + write(size) + } else { + write(UInt8(size)) + } + } + + /// Writes a size to the stream. + /// + /// - parameter size: `Int` - The size to write. + func write(size: Int) { + precondition(size <= Int32.max, "Size is too large") + write(size: Int32(size)) + } + + func startSize() -> Int32 { + let pos = Int32(data.count) + write(Int32(0)) // Placeholder for 32-bit size + return pos + } + + func endSize(position: Int32) { + precondition(position > 0) + write(bytesOf: Int32(data.count) - position - 4, at: Int(position)) + } + + /// Writes an enumerator to the stream. + /// + /// - parameter val: `UInt8` - The value of the enumerator to write. + /// + /// - parameter maxValue: `Int32` - The maximum value for the enumeration's enumerators + /// (used only for the 1.0 encoding). + func write(enum val: UInt8, maxValue: Int32) { + if currentEncoding == Encoding_1_0 { + if maxValue < 127 { + write(UInt8(val)) + } else if maxValue < 32767 { + write(Int16(val)) + } else { + write(Int32(val)) + } + } else { + write(size: Int32(val)) + } + } + + /// Writes an optional enumerator to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter val: `UInt8` - The value of the enumerator to write. + /// + /// - parameter maxValue: `Int32` - The maximum value for the enumeration's enumerators + /// (used only for the 1.0 encoding). + func write(tag: Int32, val: UInt8, maxValue: Int32) { + if writeOptional(tag: tag, format: .Size) { + write(enum: val, maxValue: maxValue) + } + } + + /// Writes an enumerator to the stream. + /// + /// - parameter val: `Int32` - The value of the enumerator to write. + /// + /// - parameter maxValue: `Int32` - The maximum value for the enumeration's enumerators + /// (used only for the 1.0 encoding). + func write(enum val: Int32, maxValue: Int32) { + if currentEncoding == Encoding_1_0 { + if maxValue < 127 { + write(UInt8(val)) + } else if maxValue < 32767 { + write(Int16(val)) + } else { + write(Int32(val)) + } + } else { + write(size: val) + } + } + + /// Writes an optional enumerator to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter val: `Int32` - The value of the enumerator to write. + /// + /// - parameter maxValue: `Int32` - The maximum value for the enumeration's enumerators + /// (used only for the 1.0 encoding). + func write(tag: Int32, val: Int32, maxValue: Int32) { + if writeOptional(tag: tag, format: .Size) { + write(enum: val, maxValue: maxValue) + } + } + + /// Writes a string to the stream. + /// + /// - parameter _: `String` - The string to write. + func write(_ v: String) { + let bytes = v.data(using: .utf8)! + write(size: bytes.count) + data.append(bytes) + } + + /// Writes a string to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `String?` - The string to write. + func write(tag: Int32, value v: String?) { + if let val = v { + if writeOptional(tag: tag, format: .VSize) { + write(val) + } + } + } + + /// Writes a sequence of strings to the stream. + /// + /// - parameter _: `String` - The sequence of strings to write. + func write(_ v: [String]) { + write(size: v.count) + for s in v { + write(s) + } + } + + /// Writes an optional sequence of strings to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `[String]?` - The sequence of strings to write. + func write(tag: Int32, value v: [String]?) { + if let val = v { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(val) + endSize(position: pos) + } + } + } + + /// Writes a proxy to the stream. + /// + /// - parameter _: `ObjectPrx?` - The proxy to write. + func write(_ v: ObjectPrx?) { + if let prxImpl = v as? ObjectPrxI { + prxImpl.ice_write(to: self) + } else { + // + // A nil proxy is represented by an Identity with empty name and category fields. + // + write(Identity()) + } + } + + /// Writes an optional proxy to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `ObjectPrx?` - The proxy to write. + func write(tag: Int32, value v: ObjectPrx?) { + if let val = v { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(val) + endSize(position: pos) + } + } + } + + /// Writes a value to the stream. + /// + /// - parameter _: `Value?` - The value to write. + func write(_ v: Value?) { + initEncaps() + encaps.encoder.writeValue(v: v) + } + + /// Writes an optional value to the stream. + /// + /// - parameter tag: `Int32` - The tag of the optional data member or parameter. + /// + /// - parameter value: `Value?` - The value to write. + func write(tag: Int32, value v: Value?) { + if let val = v { + if writeOptional(tag: tag, format: .Class) { + write(val) + } + } + } + + /// Writes a user exception to the stream. + /// + /// - parameter _: `UserException` - The user exception to write. + func write(_ v: UserException) { + initEncaps() + encaps.encoder.writeException(v: v) + } + + func writeOptional(tag: Int32, format: OptionalFormat) -> Bool { + precondition(encaps != nil) + if let encoder = encaps.encoder { + return encoder.writeOptional(tag: tag, format: format) + } + return writeOptionalImpl(tag: tag, format: format) + } + + internal func writeOptionalImpl(tag: Int32, format: OptionalFormat) -> Bool { + guard currentEncoding != Encoding_1_0 else { + return false + } + + var v = format.rawValue + if tag < 30 { + v |= UInt8(tag) << 3 + write(v) + + } else { + v |= 0x0F0 // tag = 30 + write(v) + write(size: tag) + } + return true + } + + func writeOptionalVSize(tag: Int32, len: Int, elemSize: Int) -> Bool { + if writeOptional(tag: tag, format: .VSize) { + if elemSize > 1 { + // We optimize-out the size when elemSize == 1 + write(size: len == 0 ? 1 : (len * elemSize) + (len > 254 ? 5 : 1)) + } + return true + } + return false + } + + /// Writes bytes to the stream. + /// + /// - parameter raw: `Data` - The bytes to write as-is. + func write(raw: Data) { + data.append(raw) + } +} + +extension OutputStream: ICEOutputStreamHelper { + public func copy(_ bytes: UnsafeRawPointer, count: Int) { + data.append(bytes.assumingMemoryBound(to: UInt8.self), count: count) + } +} + +private class Encaps { + let start: Int + var format: FormatType + let encoding: EncodingVersion + let encoding_1_0: Bool + + var encoder: EncapsEncoder! + + init(encoding: EncodingVersion, format: FormatType, start: Int) { + self.start = start + self.format = format + self.encoding = encoding + encoding_1_0 = encoding == Encoding_1_0 + } +} + +private enum SliceType { + case NoSlice + case ValueSlice + case ExceptionSlice +} + +private struct ValueHolder: Hashable { + init(_ value: Value) { + self.value = value + } + + func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(value).hashValue) + } + + static func == (lhs: ValueHolder, rhs: ValueHolder) -> Bool { + return lhs.value === rhs.value + } + + fileprivate let value: Value +} + +private protocol EncapsEncoder: AnyObject { + var os: OutputStream { get } + var encaps: Encaps { get } + + // Encapsulation attributes for instance marshaling. + var marshaledMap: [ValueHolder: Int32] { get } + var typeIdMap: [String: Int32] { get set } + var typeIdIndex: Int32 { get set } + + init(os: OutputStream, encaps: Encaps) + + func writeValue(v: Value?) + func writeException(v: UserException) + + func startInstance(type: SliceType, data: SlicedData?) + func endInstance() + + func startSlice(typeId: String, compactId: Int32, last: Bool) + func endSlice() + + // Implemented for the 1.0 encoding, not necessary for subsequent encodings. + func writePendingValues() + func writeOptional(tag: Int32, format: OptionalFormat) -> Bool +} + +extension EncapsEncoder { + func writeOptional(tag _: Int32, format _: OptionalFormat) -> Bool { + return false + } + + func writePendingValues() {} + + func registerTypeId(_ typeId: String) -> Int32 { + guard let p = typeIdMap[typeId] else { + typeIdIndex += 1 + typeIdMap[typeId] = typeIdIndex + return -1 + } + return p + } +} + +private final class EncapsEncoder10: EncapsEncoder { + unowned let os: OutputStream + unowned let encaps: Encaps + var marshaledMap: [ValueHolder: Int32] + lazy var typeIdMap: [String: Int32] = [String: Int32]() + var typeIdIndex: Int32 + + // Instance attributes + private var sliceType: SliceType = SliceType.NoSlice + // Slice attributes + private var writeSlice: Int32 = 0 // Position of the slice data members + // Encapsulation attributes for instance marshaling. + private var valueIdIndex: Int32 = 0 + private var toBeMarshaledMap = [ValueHolder: Int32]() + + init(os: OutputStream, encaps: Encaps) { + self.os = os + self.encaps = encaps + marshaledMap = [ValueHolder: Int32]() + typeIdIndex = 0 + } + + func writeValue(v: Value?) { + // + // Value references are encoded as a negative integer in 1.0. + // + if let val = v { + os.write(-registerValue(val)) + } else { + os.write(Int32(0)) + } + } + + func writeException(v: UserException) { + // + // User exception with the 1.0 encoding start with a boolean + // flag that indicates whether or not the exception uses + // classes. + // + // This allows reading the pending instances even if some part of + // the exception was sliced. + // + let usesClasses = v._usesClasses() + os.write(usesClasses) + v._iceWrite(to: os) + if usesClasses { + writePendingValues() + } + } + + func startInstance(type: SliceType, data _: SlicedData?) { + sliceType = type + } + + func endInstance() { + if sliceType == SliceType.ValueSlice { + // + // Write the Object slice. + // + startSlice(typeId: "::Ice::Object", compactId: -1, last: true) + os.write(size: 0) // For compatibility with the old AFM. + endSlice() + } + sliceType = SliceType.NoSlice + } + + func startSlice(typeId: String, compactId _: Int32, last _: Bool) { + // + // For instance slices, encode a boolean to indicate how the type ID + // is encoded and the type ID either as a string or index. For + // exception slices, always encode the type ID as a string. + // + if sliceType == SliceType.ValueSlice { + let index = registerTypeId(typeId) + if index < 0 { + os.write(false) + os.write(typeId) + } else { + os.write(true) + os.write(size: index) + } + } else { + os.write(typeId) + } + + os.write(Int32(0)) // Placeholder for the slice length. + writeSlice = Int32(os.getCount()) + } + + func endSlice() { + // + // Write the slice length. + // + let sz = Int32(os.getCount()) - writeSlice + 4 + os.write(bytesOf: sz, at: Int(writeSlice - 4)) + } + + func writePendingValues() { + while !toBeMarshaledMap.isEmpty { + // + // Consider the to be marshalled instances as marshaled now, + // this is necessary to avoid adding again the "to be + // marshaled instances" into _toBeMarshaledMap while writing + // instances. + // + for (key, value) in toBeMarshaledMap { + marshaledMap[key] = value + } + + let savedMap = toBeMarshaledMap + toBeMarshaledMap = [ValueHolder: Int32]() + os.write(size: savedMap.count) + + for (key, value) in savedMap { + // + // Consider the to be marshalled instances as marshaled now, + // this is necessary to avoid adding again the "to be + // marshaled instances" into _toBeMarshaledMap while writing + // instances. + // + os.write(Int32(value)) + + key.value.ice_preMarshal() + + key.value._iceWrite(to: os) + } + } + os.write(size: 0) // Zero marker indicates end of sequence of sequences of instances. + } + + func registerValue(_ v: Value) -> Int32 { + // + // Look for this instance in the to-be-marshaled map. + // + let val = ValueHolder(v) + if let p = toBeMarshaledMap[val] { + return p + } + + // + // Didn't find it, try the marshaled map next. + // + if let p = marshaledMap[val] { + return p + } + + // + // We haven't seen this instance previously, create a new + // index, and insert it into the to-be-marshaled map. + // + valueIdIndex += 1 + toBeMarshaledMap[val] = valueIdIndex + return valueIdIndex + } +} + +private final class EncapsEncoder11: EncapsEncoder { + unowned let os: OutputStream + unowned let encaps: Encaps + + var marshaledMap: [ValueHolder: Int32] + lazy var typeIdMap: [String: Int32] = [String: Int32]() + var typeIdIndex: Int32 + + var current: InstanceData! + var valueIdIndex: Int32 = 1 // The ID of the next instance to marhsal + + init(os: OutputStream, encaps: Encaps) { + self.os = os + self.encaps = encaps + marshaledMap = [ValueHolder: Int32]() + typeIdIndex = 0 + } + + func writeValue(v: Value?) { + guard let v = v else { + os.write(size: 0) + return + } + + if let current = current, encaps.format == FormatType.SlicedFormat { + // + // If writing an instance within a slice and using the sliced + // format, write an index from the instance indirection + // table. The indirect instance table is encoded at the end of + // each slice and is always read (even if the Slice is + // unknown). + // + let vh = ValueHolder(v) + if let index = current.indirectionMap[vh] { + os.write(size: index) + } else { + current.indirectionTable.append(vh) + let idx = current.indirectionTable.count // Position + 1 (0 is reserved for nil) + current.indirectionMap[vh] = Int32(idx) + os.write(size: idx) + } + } else { + writeInstance(v) // Write the instance or a reference if already marshaled. + } + } + + func writeException(v: UserException) { + v._iceWrite(to: os) + } + + func startInstance(type: SliceType, data: SlicedData?) { + if let curr = current { + current = curr.next ?? InstanceData(previous: curr) + } else { + current = InstanceData(previous: nil) + } + + current!.sliceType = type + current!.firstSlice = true + + if let d = data { + writeSlicedData(d) + } + } + + func endInstance() { + current = current!.previous + } + + func startSlice(typeId: String, compactId: Int32, last: Bool) { + guard let current = current else { + preconditionFailure("current is nil") + } + + precondition(current.indirectionTable.isEmpty && current.indirectionMap.isEmpty) + + current.sliceFlagsPos = Int32(os.getCount()) + current.sliceFlags = [] + + if encaps.format == FormatType.SlicedFormat { + // Encode the slice size if using the sliced format. + current.sliceFlags.insert(.FLAG_HAS_SLICE_SIZE) + } + if last { + current.sliceFlags.insert(.FLAG_IS_LAST_SLICE) // This is the last slice. + } + + os.write(UInt8(0)) // Placeholder for the slice flags + + // + // For instance slices, encode the flag and the type ID either as a + // string or index. For exception slices, always encode the type + // ID a string. + // + if current.sliceType == SliceType.ValueSlice { + // + // Encode the type ID (only in the first slice for the compact + // encoding). + // + if encaps.format == FormatType.SlicedFormat || current.firstSlice { + if compactId >= 0 { + current.sliceFlags.insert(.FLAG_HAS_TYPE_ID_COMPACT) + os.write(size: compactId) + } else { + let index = registerTypeId(typeId) + if index < 0 { + current.sliceFlags.insert(.FLAG_HAS_TYPE_ID_STRING) + os.write(typeId) + } else { + current.sliceFlags.insert(.FLAG_HAS_TYPE_ID_INDEX) + os.write(size: index) + } + } + } + } else { + os.write(typeId) + } + + if current.sliceFlags.contains(.FLAG_HAS_SLICE_SIZE) { + os.write(Int32(0)) // Placeholder for the slice length. + } + + current.writeSlice = Int32(os.getCount()) + current.firstSlice = false + } + + func endSlice() { + guard let current = current else { + preconditionFailure("current is nil") + } + // + // Write the optional member end marker if some optional members + // were encoded. Note that the optional members are encoded before + // the indirection table and are included in the slice size. + // + if current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) { + os.write(SliceFlags.OPTIONAL_END_MARKER.rawValue) + } + + // + // Write the slice length if necessary. + // + if current.sliceFlags.contains(.FLAG_HAS_SLICE_SIZE) { + let sz: Int32 = Int32(os.getCount()) - current.writeSlice + 4 + os.write(bytesOf: sz, at: Int(current.writeSlice - 4)) + } + + // + // Only write the indirection table if it contains entries. + // + if !current.indirectionTable.isEmpty { + precondition(encaps.format == FormatType.SlicedFormat) + current.sliceFlags.insert(.FLAG_HAS_INDIRECTION_TABLE) + + // + // Write the indirection instance table. + // + os.write(size: current.indirectionTable.count) + for v in current.indirectionTable { + writeInstance(v.value) + } + + current.indirectionTable.removeAll() + current.indirectionMap.removeAll() + } + + // + // Finally, update the slice flags. + // + os.write(bytesOf: current.sliceFlags.rawValue, at: Int(current.sliceFlagsPos)) + } + + func writeOptional(tag: Int32, format: OptionalFormat) -> Bool { + guard let current = current else { + return os.writeOptionalImpl(tag: tag, format: format) + } + + if os.writeOptionalImpl(tag: tag, format: format) { + current.sliceFlags.insert(.FLAG_HAS_OPTIONAL_MEMBERS) + return true + } else { + return false + } + } + + func writeSlicedData(_ slicedData: SlicedData) { + // + // We only remarshal preserved slices if we are using the sliced + // format. Otherwise, we ignore the preserved slices, which + // essentially "slices" the instance into the most-derived type + // known by the sender. + // + guard encaps.format == .SlicedFormat else { + return + } + + for info in slicedData.slices { + startSlice(typeId: info.typeId, compactId: info.compactId, last: info.isLastSlice) + + // + // Write the bytes associated with this slice. + // + os.write(raw: info.bytes) + + if info.hasOptionalMembers { + current.sliceFlags.insert(.FLAG_HAS_OPTIONAL_MEMBERS) + } + + // + // Make sure to also re-write the instance indirection table. + // + for o in info.instances { + current.indirectionTable.append(ValueHolder(o)) + } + + endSlice() + } + } + + func writeInstance(_ v: Value) { + // + // If the instance was already marshaled, just write it's ID. + // + if let p = marshaledMap[ValueHolder(v)] { + os.write(size: p) + return + } + + // + // We haven't seen this instance previously, create a new ID, + // insert it into the marshaled map, and write the instance. + // + valueIdIndex += 1 + marshaledMap[ValueHolder(v)] = valueIdIndex + + v.ice_preMarshal() + os.write(size: 1) // Class instance marker. + v._iceWrite(to: os) + } +} + +private class InstanceData { + // Instance attributes + var sliceType: SliceType = SliceType.NoSlice + var firstSlice: Bool = true + + // Slice attributes + var sliceFlags: SliceFlags = [] + var writeSlice: Int32 = 0 // Position of the slice data members + var sliceFlagsPos: Int32 = 0 // Position of the slice flags + lazy var indirectionTable = [ValueHolder]() + lazy var indirectionMap = [ValueHolder: Int32]() + + let previous: InstanceData? + weak var next: InstanceData? + + init(previous: InstanceData?) { + self.previous = previous + next = nil + if let p = previous { + p.next = self + } + } +} diff --git a/Sources/Ice/ProcessI.swift b/Sources/Ice/ProcessI.swift new file mode 100644 index 0000000..7c8cbd3 --- /dev/null +++ b/Sources/Ice/ProcessI.swift @@ -0,0 +1,15 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class ProcessI: LocalObject, Process { + func shutdown(current _: Current) { + handle.shutdown() + } + + func writeMessage(message: Swift.String, fd: Swift.Int32, current _: Current) { + handle.writeMessage(message, fd: fd) + } +} diff --git a/Sources/Ice/PropertiesAdminI.swift b/Sources/Ice/PropertiesAdminI.swift new file mode 100644 index 0000000..eb3304f --- /dev/null +++ b/Sources/Ice/PropertiesAdminI.swift @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class PropertiesAdminI: LocalObject, PropertiesAdmin, NativePropertiesAdmin { + private let communicator: Communicator + + init(communicator: Communicator, handle: ICEPropertiesAdmin) { + self.communicator = communicator + super.init(handle: handle) + } + + func getProperty(key: Swift.String, current _: Current) throws -> Swift.String { + return try autoreleasepool { + try handle.getProperty(key) + } + } + + func getPropertiesForPrefix(prefix: Swift.String, current _: Current) throws -> PropertyDict { + return try autoreleasepool { + try handle.getPropertiesForPrefix(prefix) + } + } + + func setProperties(newProperties: PropertyDict, current _: Current) throws { + try autoreleasepool { + try handle.setProperties(newProperties) + } + } + + func addUpdateCallback(_ cb: @escaping PropertiesAdminUpdateCallback) -> PropertiesAdminRemoveCallback { + return handle.addUpdateCallback { (props: PropertyDict) in + cb(props) + } + } +} diff --git a/Sources/Ice/PropertiesI.swift b/Sources/Ice/PropertiesI.swift new file mode 100644 index 0000000..424c6ee --- /dev/null +++ b/Sources/Ice/PropertiesI.swift @@ -0,0 +1,72 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import IceImpl + +class PropertiesI: LocalObject, Properties { + public func getProperty(_ key: String) -> String { + return handle.getProperty(key) + } + + public func getPropertyWithDefault(key: String, value: String) -> String { + return handle.getPropertyWithDefault(key, value: value) + } + + public func getPropertyAsInt(_ key: String) -> Int32 { + return handle.getPropertyAsInt(key) + } + + public func getPropertyAsIntWithDefault(key: String, value: Int32) -> Int32 { + return handle.getPropertyAsIntWithDefault(key: key, value: value) + } + + public func getPropertyAsList(_ key: String) -> StringSeq { + return handle.getPropertyAsList(key) + } + + public func getPropertyAsListWithDefault(key: String, value: StringSeq) -> StringSeq { + return handle.getPropertyAsListWithDefault(key: key, value: value) + } + + public func getPropertiesForPrefix(_ prefix: String) -> PropertyDict { + return handle.getPropertiesForPrefix(prefix) + } + + public func setProperty(key: String, value: String) { + precondition(!key.isEmpty, "Key cannot be empty") + do { + try autoreleasepool { + try handle.setProperty(key, value: value) + } + } catch { + fatalError("\(error)") + } + } + + public func getCommandLineOptions() -> StringSeq { + return handle.getCommandLineOptions() + } + + public func parseCommandLineOptions(prefix: String, options: StringSeq) throws -> StringSeq { + return try autoreleasepool { + try handle.parseCommandLineOptions(prefix, options: options) + } + } + + public func parseIceCommandLineOptions(_ options: StringSeq) throws -> StringSeq { + return try autoreleasepool { + try handle.parseIceCommandLineOptions(options) + } + } + + public func load(_ file: String) throws { + return try autoreleasepool { + try handle.load(file) + } + } + + public func clone() -> Properties { + return PropertiesI(handle: handle.clone()) + } +} diff --git a/Sources/Ice/Proxy.swift b/Sources/Ice/Proxy.swift new file mode 100644 index 0000000..ae64663 --- /dev/null +++ b/Sources/Ice/Proxy.swift @@ -0,0 +1,1423 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation +import IceImpl +import PromiseKit + +/// The base protocol for all Ice proxies. +public protocol ObjectPrx: CustomStringConvertible, AnyObject { + /// Returns the communicator that created this proxy. + /// + /// - returns: `Ice.Communicator` - The communicator that created this proxy. + func ice_getCommunicator() -> Communicator + + /// Returns the identity embedded in this proxy. + /// + /// - returns: `Ice.Identity` - The identity of the target object. + func ice_getIdentity() -> Identity + + /// Creates a new proxy that is identical to this proxy, except for the identity. + /// + /// - parameter _: `Ice.Identity` - The identity for the new proxy. + /// + /// - returns: A proxy with the new identity. + func ice_identity(_ id: Identity) -> Self + + /// Returns the per-proxy context for this proxy. + /// + /// - returns: `Ice.Context` - The per-proxy context. + func ice_getContext() -> Context + + /// Creates a new proxy that is identical to this proxy, except for the per-proxy context. + /// + /// - parameter newContext: `Ice.Context` - The context for the new proxy. + /// + /// - returns: The proxy with the new per-proxy context. + func ice_context(_ context: Context) -> Self + + /// Returns the facet for this proxy. + /// + /// - returns: `String` - The facet for this proxy. If the proxy uses the default facet, + /// the return value is the empty string. + func ice_getFacet() -> String + + /// Creates a new proxy that is identical to this proxy, except for the facet. + /// + /// - parameter _: `String` - The facet for the new proxy. + /// + /// - returns: `Ice.ObjectPrx` - The proxy with the new facet. + func ice_facet(_ facet: String) -> ObjectPrx + + /// Returns the adapter ID for this proxy. + /// + /// - returns: `String` - The adapter ID. If the proxy does not have an adapter ID, the return value is the + /// empty string. + func ice_getAdapterId() -> String + + /// Creates a new proxy that is identical to this proxy, except for the adapter ID. + /// + /// - parameter _: `String` - The adapter ID for the new proxy. + /// + /// - returns: The proxy with the new adapter ID. + func ice_adapterId(_ id: String) -> Self + + /// Returns the endpoints used by this proxy. + /// + /// - returns: `EndpointSeq` - The endpoints used by this proxy. + func ice_getEndpoints() -> EndpointSeq + + /// Creates a new proxy that is identical to this proxy, except for the endpoints. + /// + /// - parameter _: `EndpointSeq` - The endpoints for the new proxy. + /// + /// - returns: The proxy with the new endpoints. + func ice_endpoints(_ endpoints: EndpointSeq) -> Self + + /// Returns the locator cache timeout of this proxy. + /// + /// - returns: `Int32` - The locator cache timeout value (in seconds). + func ice_getLocatorCacheTimeout() -> Int32 + + /// Creates a new proxy that is identical to this proxy, except for the locator cache timeout. + /// + /// - parameter _: `Int32` - The new locator cache timeout (in seconds). + /// + /// - returns: A new proxy with the specified cache timeout. + func ice_locatorCacheTimeout(_ timeout: Int32) -> Self + + /// Returns the invocation timeout of this proxy. + /// + /// - returns: `Int32` - The invocation timeout value (in seconds). + func ice_getInvocationTimeout() -> Int32 + + /// Creates a new proxy that is identical to this proxy, except for the invocation timeout. + /// + /// - parameter _: `Int32` - The new invocation timeout (in seconds). + /// + /// - returns: A new proxy with the specified invocation timeout. + func ice_invocationTimeout(_ timeout: Int32) -> Self + + /// Returns the connection id of this proxy. + /// + /// returns: `String` - The connection id. + func ice_getConnectionId() -> String + + /// Creates a new proxy that is identical to this proxy, except for its connection ID. + /// + /// - parameter _: `String` - The connection ID for the new proxy. An empty string removes the + /// connection ID. + /// + /// - returns: A new proxy with the specified connection ID. + func ice_connectionId(_ id: String) -> Self + + /// Returns whether this proxy caches connections. + /// + /// - returns: `Bool` - True if this proxy caches connections; false, otherwise. + func ice_isConnectionCached() -> Bool + + /// Creates a new proxy that is identical to this proxy, except for connection caching. + /// + /// - parameter _: `Bool` - True if the new proxy should cache connections; false, otherwise. + /// + /// - returns: The new proxy with the specified caching policy. + func ice_connectionCached(_ cached: Bool) -> Self + + /// Returns how this proxy selects endpoints (randomly or ordered). + /// + /// - returns: `Ice.EndpointSelectionType` - The endpoint selection policy. + func ice_getEndpointSelection() -> EndpointSelectionType + + /// Creates a new proxy that is identical to this proxy, except for the endpoint selection policy. + /// + /// - parameter _: `Ice.EndpointSelectionType` - The new endpoint selection policy. + /// + /// - returns: The new proxy with the specified endpoint selection policy. + func ice_endpointSelection(_ type: EndpointSelectionType) -> Self + + /// Returns the encoding version used to marshal requests parameters. + /// + /// - returns: `Ice.EncodingVersion` - The encoding version. + func ice_getEncodingVersion() -> EncodingVersion + + /// Creates a new proxy that is identical to this proxy, except for the encoding used to marshal + /// parameters. + /// + /// - parameter _: `Ice.EncodingVersion` - The encoding version to use to marshal requests parameters. + /// + /// - returns: The new proxy with the specified encoding version. + func ice_encodingVersion(_ encoding: EncodingVersion) -> Self + + /// Returns the router for this proxy. + /// + /// - returns: `Ice.RouterPrx?` - The router for the proxy. If no router is configured for the proxy, + /// the return value is nil. + func ice_getRouter() -> RouterPrx? + + /// Creates a new proxy that is identical to this proxy, except for the router. + /// + /// - parameter router: `Ice.RouterPrx?` - The router for the new proxy. + /// + /// - returns: The new proxy with the specified router. + func ice_router(_ router: RouterPrx?) -> Self + + /// Returns the locator for this proxy. + /// + /// - returns: `Ice.LocatorPrx?` - The locator for this proxy. If no locator is configured, the + /// return value is nil. + func ice_getLocator() -> LocatorPrx? + + /// Creates a new proxy that is identical to this proxy, except for the locator. + /// + /// - parameter _: `Ice.LocatorPrx` The locator for the new proxy. + /// + /// - returns: The new proxy with the specified locator. + func ice_locator(_ locator: LocatorPrx?) -> Self + + /// Returns whether this proxy communicates only via secure endpoints. + /// + /// - returns: `Bool` - True if this proxy communicates only via secure endpoints; false, otherwise. + func ice_isSecure() -> Bool + + /// Creates a new proxy that is identical to this proxy, except for how it selects endpoints. + /// + /// - parameter _: `Bool` - If true only endpoints that use a secure transport are used by the new proxy. + /// otherwise the returned proxy uses both secure and insecure endpoints. + /// + /// - returns: The new proxy with the specified selection policy. + func ice_secure(_ secure: Bool) -> Self + + /// Returns whether this proxy prefers secure endpoints. + /// + /// - returns: `Bool` - True if the proxy always attempts to invoke via secure endpoints before it + /// attempts to use insecure endpoints; false, otherwise. + func ice_isPreferSecure() -> Bool + + /// Creates a new proxy that is identical to this proxy, except for its endpoint selection policy. + /// + /// - parameter _: `Bool` - If true, the new proxy will use secure endpoints for invocations + /// and only use insecure endpoints if an invocation cannot be made via secure endpoints. Otherwise + /// the proxy prefers insecure endpoints to secure ones. + /// + /// - returns: The new proxy with the new endpoint selection policy. + func ice_preferSecure(_ preferSecure: Bool) -> Self + + /// Returns whether this proxy uses twoway invocations. + /// + /// - returns: `Bool` - True if this proxy uses twoway invocations; false, otherwise. + func ice_isTwoway() -> Bool + + /// Creates a new proxy that is identical to this proxy, but uses twoway invocations. + /// + /// - returns: A new proxy that uses twoway invocations. + func ice_twoway() -> Self + + /// Returns whether this proxy uses oneway invocations. + /// + /// - returns: `Bool` - True if this proxy uses oneway invocations; false, otherwise. + func ice_isOneway() -> Bool + + /// Creates a new proxy that is identical to this proxy, but uses oneway invocations. + /// + /// - returns: A new proxy that uses oneway invocations. + func ice_oneway() -> Self + + /// Returns whether this proxy uses batch oneway invocations. + /// + /// - returns: `Bool` - True if this proxy uses batch oneway invocations; false, otherwise. + func ice_isBatchOneway() -> Bool + + /// Creates a new proxy that is identical to this proxy, but uses batch oneway invocations. + /// + /// - returns: A new proxy that uses batch oneway invocations. + func ice_batchOneway() -> Self + + /// Returns whether this proxy uses datagram invocations. + /// + /// - returns: `Bool` - True if this proxy uses datagram invocations; false, otherwise. + func ice_isDatagram() -> Bool + + /// Creates a new proxy that is identical to this proxy, but uses datagram invocations. + /// + /// - returns: A new proxy that uses datagram invocations. + func ice_datagram() -> Self + + /// Returns whether this proxy uses batch datagram invocations. + /// + /// - returns: `Bool` - True if this proxy uses batch datagram invocations; false, otherwise. + func ice_isBatchDatagram() -> Bool + + /// Creates a new proxy that is identical to this proxy, but uses batch datagram invocations. + /// + /// - returns: A new proxy that uses batch datagram invocations. + func ice_batchDatagram() -> Self + + /// Obtains the compression override setting of this proxy. + /// + /// - returns: `Bool` - The compression override setting. If no optional value is present, no override is + /// set. Otherwise, true if compression is enabled, false otherwise. + func ice_getCompress() -> Bool? + + /// Creates a new proxy that is identical to this proxy, except for compression. + /// + /// - parameter _: `Bool` - True enables compression for the new proxy; false disables compression. + /// + /// - returns: A new proxy with the specified compression setting. + func ice_compress(_ compress: Bool) -> Self + + /// Obtains the timeout override of this proxy. + /// + /// - returns: `Int32?` - The timeout override. If no optional value is present, no override is set. + /// Otherwise, returns the timeout override value. + func ice_getTimeout() -> Int32? + + /// Creates a new proxy that is identical to this proxy, except for its timeout setting. + /// + /// - parameter _: `Int32` - The timeout for the new proxy in milliseconds. + /// + /// - returns: A new proxy with the specified timeout. + func ice_timeout(_ timeout: Int32) -> Self + + /// Returns a proxy that is identical to this proxy, except it's a fixed proxy bound + /// to the given connection. + /// + /// - parameter _: `Ice.Connection` - The fixed proxy connection. + /// + /// - returns: A fixed proxy bound to the given connection. + func ice_fixed(_ connection: Connection) -> Self + + /// Returns whether this proxy is a fixed proxy. + /// + /// - returns: `Bool` - True if this is a fixed proxy, false otherwise. + func ice_isFixed() -> Bool + + /// Returns the cached Connection for this proxy. If the proxy does not yet have an established + /// connection, it does not attempt to create a connection. + /// + /// - returns: `Ice.Connection?` - The cached Connection for this proxy (nil if the proxy does not have + /// an established connection). + /// + /// - throws: `CollocationOptimizationException` - If the proxy uses collocation optimization and denotes a + /// collocated object. + func ice_getCachedConnection() -> Connection? + + /// Returns the stringified form of this proxy. + /// + /// - returns: `String` - The stringified proxy + func ice_toString() -> String + + /// Returns whether this proxy uses collocation optimization. + /// + /// - returns: `Bool` - True if the proxy uses collocation optimization; false, otherwise. + func ice_isCollocationOptimized() -> Bool + + /// Creates a new proxy that is identical to this proxy, except for collocation optimization. + /// + /// - parameter _: `Bool` - True if the new proxy enables collocation optimization; false, otherwise. + /// + /// - returns: The new proxy the specified collocation optimization. + func ice_collocationOptimized(_ collocated: Bool) -> Self +} + +/// Casts a proxy to `Ice.ObjectPrx`. This call contacts the server and will throw an Ice run-time exception +/// if the target object does not exist or the server cannot be reached. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to cast to `Ice.ObjectPrx`. +/// +/// - parameter type: `Ice.ObjectPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String?` - The optional facet for the new proxy. +/// +/// - parameter context: `Ice.Context?` - The optional context dictionary for the invocation. +/// +/// - throws: Throws an Ice run-time exception if the target object does not exist, the specified facet +/// does not exist, or the server cannot be reached. +/// +/// - returns: The new proxy with the specified facet or nil if the target object does not support the specified +/// interface. +public func checkedCast(prx: Ice.ObjectPrx, + type _: ObjectPrx.Protocol, + facet: String? = nil, + context: Ice.Context? = nil) throws -> ObjectPrx? { + return try ObjectPrxI.checkedCast(prx: prx, facet: facet, context: context) as ObjectPrxI? +} + +/// Creates a new proxy that is identical to the passed proxy, except for its facet. This call does +/// not contact the server and always succeeds. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to cast to `Ice.ObjectPrx`. +/// +/// - parameter type: `Ice.ObjectPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String?` - The optional facet for the new proxy. +/// +/// - returns: The new proxy with the specified facet. +public func uncheckedCast(prx: Ice.ObjectPrx, + type _: ObjectPrx.Protocol, + facet: String? = nil) -> ObjectPrx { + return ObjectPrxI.uncheckedCast(prx: prx, facet: facet) as ObjectPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy class. +/// +/// - returns: `String` - The type id, "::Ice::Object". +public func ice_staticId(_: ObjectPrx.Protocol) -> Swift.String { + return ObjectTraits.staticId +} + +public func != (lhs: ObjectPrx?, rhs: ObjectPrx?) -> Bool { + return !(lhs == rhs) +} + +public func == (lhs: ObjectPrx?, rhs: ObjectPrx?) -> Bool { + if lhs === rhs { + return true + } else if lhs === nil && rhs === nil { + return true + } else if lhs === nil || rhs === nil { + return false + } else { + let lhsI = lhs as! ObjectPrxI + let rhsI = rhs as! ObjectPrxI + return lhsI.handle.isEqual(rhsI.handle) + } +} + +public extension ObjectPrx { + /// Returns the underdlying implementation object (Ice internal). + var _impl: ObjectPrxI { + return self as! ObjectPrxI + } + + /// Sends ping request to the target object. + /// + /// - parameter context: `Ice.Context` - The optional context dictionary for the invocation. + /// + /// - throws: `Ice.LocalException` such as `Ice.ObjectNotExistException` and + /// `Ice.ConnectionRefusedException`. + func ice_ping(context: Context? = nil) throws { + try _impl._invoke(operation: "ice_ping", + mode: OperationMode.Nonmutating, + context: context) + } + + /// Sends ping request to the target object asynchronously. + /// + /// - parameter context: `Ice.Context` - The optional context dictionary for the invocation. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` - Optional dispatch flags used to + /// dispatch sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - A promise object that will be resolved with + /// the result of the invocation. + func ice_pingAsync(context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + return _impl._invokeAsync(operation: "ice_ping", + mode: .Nonmutating, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Tests whether this object supports a specific Slice interface. + /// + /// - parameter id: `String` - The type ID of the Slice interface to test against. + /// + /// - parameter context: `Ice.Context` - The optional context dictionary for the invocation. + /// + /// - returns: `Bool` - True if the target object has the interface specified by id or derives + /// from the interface specified by id. + func ice_isA(id: String, context: Context? = nil) throws -> Bool { + return try _impl._invoke(operation: "ice_isA", + mode: .Nonmutating, + write: { ostr in + ostr.write(id) + }, + read: { istr in try istr.read() as Bool }, + context: context) + } + + /// Tests whether this object supports a specific Slice interface. + /// + /// - parameter id: `String` - The type ID of the Slice interface to test against. + /// + /// - parameter context: `Ice.Context` - The optional context dictionary for the invocation. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` - Optional dispatch flags used to + /// dispatch sent callback + /// + /// - parameter sent: `((Bool) -> Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - A promise object that will be resolved with + /// the result of the invocation. + func ice_isAAsync(id: String, context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + return _impl._invokeAsync(operation: "ice_isA", + mode: .Nonmutating, + write: { ostr in + ostr.write(id) + }, + read: { istr in try istr.read() as Bool }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + /// + /// - parameter context: `Ice.Context?` - The optional context dictionary for the invocation. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface. + func ice_id(context: Context? = nil) throws -> String { + return try _impl._invoke(operation: "ice_id", + mode: .Nonmutating, + read: { istr in try istr.read() as String }, + context: context) + } + + /// Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + /// + /// - parameter context: `Ice.Context?` - The optional context dictionary for the invocation. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` - Optional dispatch flags used to + /// dispatch sent callback + /// + /// - parameter sent: `((Bool) -> Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` A promise object that will be resolved with + /// the result of the invocation. + func ice_idAsync(context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + return _impl._invokeAsync(operation: "ice_id", + mode: .Nonmutating, + read: { istr in try istr.read() as String }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + /// + /// - parameter context: `Ice.Context?` - The optional context dictionary for the invocation. + /// + /// - returns: `Ice.StringSeq` - The Slice type IDs of the interfaces supported by the target object, + /// in base-to-derived order. The first element of the returned array is always `::Ice::Object`. + func ice_ids(context: Context? = nil) throws -> StringSeq { + return try _impl._invoke(operation: "ice_ids", + mode: .Nonmutating, + read: { istr in try istr.read() as StringSeq }, + context: context) + } + + /// Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + /// + /// - parameter context: `Ice.Context?` - The optional context dictionary for the invocation. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` - Optional dispatch flags used to + /// dispatch sent callback + /// + /// - parameter sent: `((Bool) -> Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - A promise object that will be resolved with + /// the result of the invocation. + func ice_idsAsync(context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + return _impl._invokeAsync(operation: "ice_ids", + mode: .Nonmutating, + read: { istr in try istr.read() as StringSeq }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Invokes an operation dynamically. + /// + /// - parameter operation: `String` - The name of the operation to invoke. + /// + /// - parameter mode: `Ice.OperationMode` - The operation mode (normal or idempotent). + /// + /// - parameter inEncaps: `Data` - The encoded in-parameters for the operation. + /// + /// - parameter context: `Ice.Context` - The context dictionary for the invocation. + /// + /// - returns: A tuple with the following fields: + /// + /// - ok: `Bool` - If the operation completed successfully, the value + /// is set to true. If the operation raises a user exception, the return value + /// is false; in this case, outEncaps contains the encoded user exception. If + /// the operation raises a run-time exception, it throws it directly. + /// + /// - outEncaps: `Data` - The encoded out-paramaters and return value for the operation. + /// The return value follows any out-parameters. + func ice_invoke(operation: String, + mode: OperationMode, + inEncaps: Data, + context: Context? = nil) throws -> (ok: Bool, outEncaps: Data) { + if _impl.isTwoway { + var data: Data? + var ok: Bool = false + try _impl.handle.invoke(operation, mode: mode.rawValue, inParams: inEncaps, context: context) { + ok = $0 + data = Data(bytes: $1, count: $2) // make a copy + } + return (ok, data!) + } else { + try _impl.handle.onewayInvoke(operation, mode: mode.rawValue, inParams: inEncaps, context: context) + return (true, Data()) + } + } + + /// Invokes an operation dynamically. + /// + /// - parameter operation: `String` - The name of the operation to invoke. + /// + /// - parameter mode: `Ice.OperationMode` - The operation mode (normal or idempotent). + /// + /// - parameter inEncaps: `Data` - The encoded in-parameters for the operation. + /// + /// - parameter context: `Ice.Context` - The context dictionary for the invocation. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` - Optional dispatch flags used to + /// dispatch the sent callback. + /// + /// - parameter sent: `((Bool) -> Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(ok: Bool, outEncaps: Data)>` - A promise object that will be + //// resolved with the result of the invocation. + func ice_invokeAsync(operation: String, + mode: OperationMode, + inEncaps: Data, + context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise<(ok: Bool, outEncaps: Data)> { + if _impl.isTwoway { + return Promise<(ok: Bool, outEncaps: Data)> { seal in + _impl.handle.invokeAsync(operation, + mode: mode.rawValue, + inParams: inEncaps, + context: context, + response: { ok, bytes, count in + do { + let istr = + InputStream(communicator: self._impl.communicator, + encoding: self._impl.encoding, + bytes: Data(bytes: bytes, count: count)) // make a copy + seal.fulfill((ok, try istr.readEncapsulation().bytes)) + } catch { + seal.reject(error) + } + }, + exception: { error in + seal.reject(error) + }, + sent: createSentCallback(sentOn: sentOn, + sentFlags: sentFlags, + sent: sent)) + } + } else { + let sentCB = createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent) + return Promise<(ok: Bool, outEncaps: Data)> { seal in + _impl.handle.invokeAsync(operation, + mode: mode.rawValue, + inParams: inEncaps, + context: context, + response: { _, _, _ in + fatalError("Unexpected response") + }, + exception: { error in + seal.reject(error) + }, + sent: { + seal.fulfill((true, Data())) + if let sentCB = sentCB { + sentCB($0) + } + }) + } + } + } + + /// Returns the connection for this proxy. If the proxy does not yet have an established connection, + /// it first attempts to create a connection. + /// + /// - returns: `Ice.Connection?` - The Connection for this proxy. + /// + /// - throws: `Ice.CollocationOptimizationException` - If the proxy uses collocation optimization and denotes a + /// collocated object. + func ice_getConnection() throws -> Connection? { + return try autoreleasepool { + // + // Returns Any which is either NSNull or ICEConnection + // + guard let handle = try _impl.handle.ice_getConnection() as? ICEConnection else { + return nil + } + return handle.getSwiftObject(ConnectionI.self) { ConnectionI(handle: handle) } + } + } + + /// Returns the connection for this proxy. If the proxy does not yet have an established connection, + /// it first attempts to create a connection. + /// + /// - returns: `PromiseKit.Promise` - A promise object that will be resolved with + /// the result of the invocation. + /// + /// - throws: `Ice.CollocationOptimizationException` - If the proxy uses collocation optimization and denotes a + /// collocated object. + func ice_getConnectionAsync() -> Promise { + return Promise { seal in + self._impl.handle.ice_getConnectionAsync({ conn in + seal.fulfill(conn?.getSwiftObject(ConnectionI.self) { + ConnectionI(handle: conn!) + }) + }, exception: { ex in seal.reject(ex) }) + } + } + + /// Flushes any pending batched requests for this communicator. The call blocks until the flush is complete. + func ice_flushBatchRequests() throws { + return try autoreleasepool { + try _impl.handle.ice_flushBatchRequests() + } + } + + /// Asynchronously flushes any pending batched requests for this proxy. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags` Optional dispatch flags used to + /// dispatch the sent callback. + /// + /// - parameter sent: `((Bool) -> Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise - A promise object that will be resolved when + /// the flush is complete. + func ice_flushBatchRequestsAsync(sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil.self, + sent: ((Bool) -> Void)? = nil) -> Promise { + let sentCB = createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent) + return Promise { seal in + _impl.handle.ice_flushBatchRequestsAsync( + exception: { + seal.reject($0) + }, + sent: { + seal.fulfill(()) + if let sentCB = sentCB { + sentCB($0) + } + } + ) + } + } +} + +// +// ObjectPrxI, the base proxy implementation class is an Ice-internal class used in the +// generated code - this is why we give it the open access level. +// +open class ObjectPrxI: ObjectPrx { + internal let handle: ICEObjectPrx + internal let communicator: Communicator + internal let encoding: EncodingVersion + fileprivate let isTwoway: Bool + + public var description: String { + return handle.ice_toString() + } + + public required init(handle: ICEObjectPrx, communicator: Communicator) { + self.handle = handle + self.communicator = communicator + var encoding = EncodingVersion() + handle.ice_getEncodingVersion(&encoding.major, minor: &encoding.minor) + self.encoding = encoding + isTwoway = handle.ice_isTwoway() + } + + public required init(from prx: ObjectPrx) { + let impl = prx as! ObjectPrxI + handle = impl.handle + communicator = impl.communicator + encoding = impl.encoding + isTwoway = impl.isTwoway + } + + internal func fromICEObjectPrx(_ h: ICEObjectPrx) -> ObjectPrxType where ObjectPrxType: ObjectPrxI { + return ObjectPrxType(handle: h, communicator: communicator) + } + + internal static func fromICEObjectPrx(handle: ICEObjectPrx, + communicator c: Communicator? = nil) -> Self { + let communicator = c ?? handle.ice_getCommunicator().getCachedSwiftObject(CommunicatorI.self) + return self.init(handle: handle, communicator: communicator) + } + + public func ice_getCommunicator() -> Communicator { + return communicator + } + + open class func ice_staticId() -> String { + return ObjectTraits.staticId + } + + public func ice_getIdentity() -> Identity { + var name = NSString() + var category = NSString() + handle.ice_getIdentity(&name, category: &category) + return Identity(name: name as String, category: category as String) + } + + public func ice_identity(_ id: Identity) -> Self { + precondition(!id.name.isEmpty, "Identity name cannot be empty") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_identity(id.name, category: id.category)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getContext() -> Context { + return handle.ice_getContext() as Context + } + + public func ice_context(_ context: Context) -> Self { + return fromICEObjectPrx(handle.ice_context(context)) + } + + public func ice_getFacet() -> String { + return handle.ice_getFacet() + } + + public func ice_facet(_ facet: String) -> ObjectPrx { + return fromICEObjectPrx(handle.ice_facet(facet)) + } + + public func ice_getAdapterId() -> String { + return handle.ice_getAdapterId() + } + + public func ice_adapterId(_ id: String) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with an adapterId") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_adapterId(id)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getEndpoints() -> EndpointSeq { + return handle.ice_getEndpoints().fromObjc() + } + + public func ice_endpoints(_ endpoints: EndpointSeq) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with endpoints") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_endpoints(endpoints.toObjc())) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getLocatorCacheTimeout() -> Int32 { + return handle.ice_getLocatorCacheTimeout() + } + + public func ice_locatorCacheTimeout(_ timeout: Int32) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a locatorCacheTimeout") + precondition(timeout >= -1, "Invalid locator cache timeout value") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_locatorCacheTimeout(timeout)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getInvocationTimeout() -> Int32 { + return handle.ice_getInvocationTimeout() + } + + public func ice_invocationTimeout(_ timeout: Int32) -> Self { + precondition(timeout >= 1 || timeout == -1 || timeout == -2, "Invalid invocation timeout value") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_invocationTimeout(timeout)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getConnectionId() -> String { + return handle.ice_getConnectionId() + } + + public func ice_connectionId(_ id: String) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a connectionId") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_connectionId(id)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_isConnectionCached() -> Bool { + return handle.ice_isConnectionCached() + } + + public func ice_connectionCached(_ cached: Bool) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a cached connection") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_connectionCached(cached)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getEndpointSelection() -> EndpointSelectionType { + return EndpointSelectionType(rawValue: handle.ice_getEndpointSelection())! + } + + public func ice_endpointSelection(_ type: EndpointSelectionType) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with an endpointSelectionType") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_endpointSelection(type.rawValue)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getEncodingVersion() -> EncodingVersion { + return encoding + } + + public func ice_encodingVersion(_ encoding: EncodingVersion) -> Self { + return fromICEObjectPrx(handle.ice_encodingVersion(encoding.major, minor: encoding.minor)) + } + + public func ice_getRouter() -> RouterPrx? { + guard let routerHandle = handle.ice_getRouter() else { + return nil + } + return fromICEObjectPrx(routerHandle) as RouterPrxI + } + + public func ice_router(_ router: RouterPrx?) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a router") + do { + return try autoreleasepool { + let r = router as? ObjectPrxI + return try fromICEObjectPrx(handle.ice_router(r?.handle ?? nil)) + } + } catch { + fatalError("\(error)") + } + } + + public func ice_getLocator() -> LocatorPrx? { + guard let locatorHandle = handle.ice_getLocator() else { + return nil + } + return fromICEObjectPrx(locatorHandle) as LocatorPrxI + } + + public func ice_locator(_ locator: LocatorPrx?) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a locator") + do { + return try autoreleasepool { + let l = locator as? ObjectPrxI + return try fromICEObjectPrx(handle.ice_locator(l?.handle ?? nil)) + } + } catch { + fatalError("\(error)") + } + } + + public func ice_isSecure() -> Bool { + return handle.ice_isSecure() + } + + public func ice_secure(_ secure: Bool) -> Self { + return fromICEObjectPrx(handle.ice_secure(secure)) + } + + public func ice_isPreferSecure() -> Bool { + return handle.ice_isPreferSecure() + } + + public func ice_preferSecure(_ preferSecure: Bool) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with preferSecure") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_preferSecure(preferSecure)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_isTwoway() -> Bool { + return isTwoway + } + + public func ice_twoway() -> Self { + return fromICEObjectPrx(handle.ice_twoway()) + } + + public func ice_isOneway() -> Bool { + return handle.ice_isOneway() + } + + public func ice_oneway() -> Self { + return fromICEObjectPrx(handle.ice_oneway()) + } + + public func ice_isBatchOneway() -> Bool { + return handle.ice_isBatchOneway() + } + + public func ice_batchOneway() -> Self { + return fromICEObjectPrx(handle.ice_batchOneway()) + } + + public func ice_isDatagram() -> Bool { + return handle.ice_isDatagram() + } + + public func ice_datagram() -> Self { + return fromICEObjectPrx(handle.ice_datagram()) + } + + public func ice_isBatchDatagram() -> Bool { + return handle.ice_isBatchDatagram() + } + + public func ice_batchDatagram() -> Self { + return fromICEObjectPrx(handle.ice_batchDatagram()) + } + + public func ice_getCompress() -> Bool? { + guard let compress = handle.ice_getCompress() as? Bool? else { + preconditionFailure("Bool? type was expected") + } + return compress + } + + public func ice_compress(_ compress: Bool) -> Self { + return fromICEObjectPrx(handle.ice_compress(compress)) + } + + public func ice_getTimeout() -> Int32? { + guard let timeout = handle.ice_getTimeout() as? Int32? else { + preconditionFailure("Int32? type was expected") + } + return timeout + } + + public func ice_timeout(_ timeout: Int32) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with a connection timeout") + precondition(timeout > 0 || timeout == -1, "Invalid connection timeout value") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_timeout(timeout)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_fixed(_ connection: Connection) -> Self { + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_fixed((connection as! ConnectionI).handle)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public func ice_isFixed() -> Bool { + return handle.ice_isFixed() + } + + public func ice_getCachedConnection() -> Connection? { + guard let handle = handle.ice_getCachedConnection() else { + return nil + } + return handle.getSwiftObject(ConnectionI.self) { ConnectionI(handle: handle) } + } + + public func ice_write(to os: OutputStream) { + handle.ice_write(os, encodingMajor: os.currentEncoding.major, encodingMinor: os.currentEncoding.minor) + } + + public func ice_toString() -> String { + return handle.ice_toString() + } + + public func ice_isCollocationOptimized() -> Bool { + return handle.ice_isCollocationOptimized() + } + + public func ice_collocationOptimized(_ collocated: Bool) -> Self { + precondition(!ice_isFixed(), "Cannot create a fixed proxy with collocation optimization") + do { + return try autoreleasepool { + try fromICEObjectPrx(handle.ice_collocationOptimized(collocated)) as Self + } + } catch { + fatalError("\(error)") + } + } + + public static func ice_read(from istr: InputStream) throws -> Self? { + // + // Unmarshaling of proxies is done in C++. Since we don't know how big this proxy will + // be we pass the current buffer position and remaining buffer capacity. + // + + // The number of bytes consumed reading the proxy + var bytesRead: Int = 0 + let encoding = istr.currentEncoding + let communicator = istr.communicator + + // + // Returns Any which is either NSNull or ICEObjectPrx + // + let handleOpt = try ICEObjectPrx.ice_read(istr.data[istr.pos ..< istr.data.count], + communicator: (communicator as! CommunicatorI).handle, + encodingMajor: encoding.major, + encodingMinor: encoding.minor, + bytesRead: &bytesRead) as? ICEObjectPrx + + // Since the proxy was read in C++ we need to skip over the bytes which were read + // We avoid using a defer statment for this since you can not throw from one + try istr.skip(bytesRead) + + guard let handle = handleOpt else { + return nil + } + + return self.init(handle: handle, communicator: communicator) + } + + public func _invoke(operation: String, + mode: OperationMode, + format: FormatType = FormatType.DefaultFormat, + write: ((OutputStream) -> Void)? = nil, + userException: ((UserException) throws -> Void)? = nil, + context: Context? = nil) throws { + if userException != nil, !isTwoway { + throw TwowayOnlyException(operation: operation) + } + + let ostr = OutputStream(communicator: communicator) + if let write = write { + ostr.startEncapsulation(encoding: encoding, format: format) + write(ostr) + ostr.endEncapsulation() + } + + if isTwoway { + var uex: Error? + try autoreleasepool { + try handle.invoke(operation, mode: mode.rawValue, + inParams: ostr.finished(), context: context, + response: { ok, bytes, count in + do { + let istr = InputStream(communicator: self.communicator, + encoding: self.encoding, + bytes: Data(bytesNoCopy: bytes, count: count, + deallocator: .none)) + if ok == false { + try ObjectPrxI.throwUserException(istr: istr, + userException: userException) + } + try istr.skipEmptyEncapsulation() + } catch { + uex = error + } + }) + + if let e = uex { + throw e + } + } + } else { + try autoreleasepool { + try handle.onewayInvoke(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context) + } + } + } + + public func _invoke(operation: String, + mode: OperationMode, + format: FormatType = FormatType.DefaultFormat, + write: ((OutputStream) -> Void)? = nil, + read: @escaping (InputStream) throws -> T, + userException: ((UserException) throws -> Void)? = nil, + context: Context? = nil) throws -> T { + if !isTwoway { + throw TwowayOnlyException(operation: operation) + } + let ostr = OutputStream(communicator: communicator) + if let write = write { + ostr.startEncapsulation(encoding: encoding, format: format) + write(ostr) + ostr.endEncapsulation() + } + var uex: Error? + var ret: T! + try autoreleasepool { + try handle.invoke(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context, + response: { ok, bytes, count in + do { + let istr = InputStream(communicator: self.communicator, + encoding: self.encoding, + bytes: Data(bytesNoCopy: bytes, count: count, + deallocator: .none)) + if ok == false { + try ObjectPrxI.throwUserException(istr: istr, + userException: userException) + } + try istr.startEncapsulation() + ret = try read(istr) + try istr.endEncapsulation() + } catch { + uex = error + } + }) + + if let e = uex { + throw e + } + } + + precondition(ret != nil) + return ret + } + + public func _invokeAsync(operation: String, + mode: OperationMode, + format: FormatType = FormatType.DefaultFormat, + write: ((OutputStream) -> Void)? = nil, + userException: ((UserException) throws -> Void)? = nil, + context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + if userException != nil, !isTwoway { + return Promise(error: TwowayOnlyException(operation: operation)) + } + let ostr = OutputStream(communicator: communicator) + if let write = write { + ostr.startEncapsulation(encoding: encoding, format: format) + write(ostr) + ostr.endEncapsulation() + } + if isTwoway { + return Promise { seal in + handle.invokeAsync(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context, + response: { ok, bytes, count in + do { + let istr = InputStream(communicator: self.communicator, + encoding: self.encoding, + bytes: Data(bytesNoCopy: bytes, count: count, + deallocator: .none)) + if ok == false { + try ObjectPrxI.throwUserException(istr: istr, + userException: userException) + } + try istr.skipEmptyEncapsulation() + seal.fulfill(()) + } catch { + seal.reject(error) + } + }, + exception: { error in + seal.reject(error) + }, + sent: createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent)) + } + } else { + if ice_isBatchOneway() || ice_isBatchDatagram() { + return Promise { seal in + try autoreleasepool { + try handle.onewayInvoke(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context) + + seal.fulfill(()) + } + } + } else { + return Promise { seal in + let sentCB = createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent) + handle.invokeAsync(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context, + response: { _, _, _ in + fatalError("Unexpected response") + }, + exception: { error in + seal.reject(error) + }, + sent: { + seal.fulfill(()) + if let sentCB = sentCB { + sentCB($0) + } + }) + } + } + } + } + + public func _invokeAsync(operation: String, + mode: OperationMode, + format: FormatType = FormatType.DefaultFormat, + write: ((OutputStream) -> Void)? = nil, + read: @escaping (InputStream) throws -> T, + userException: ((UserException) throws -> Void)? = nil, + context: Context? = nil, + sentOn: DispatchQueue? = nil, + sentFlags: DispatchWorkItemFlags? = nil, + sent: ((Bool) -> Void)? = nil) -> Promise { + if !isTwoway { + return Promise(error: TwowayOnlyException(operation: operation)) + } + let ostr = OutputStream(communicator: communicator) + if let write = write { + ostr.startEncapsulation(encoding: encoding, format: format) + write(ostr) + ostr.endEncapsulation() + } + return Promise { seal in + handle.invokeAsync(operation, + mode: mode.rawValue, + inParams: ostr.finished(), + context: context, + response: { ok, bytes, count in + do { + let istr = InputStream(communicator: self.communicator, + encoding: self.encoding, + bytes: Data(bytesNoCopy: bytes, count: count, + deallocator: .none)) + if ok == false { + try ObjectPrxI.throwUserException(istr: istr, + userException: userException) + } + try istr.startEncapsulation() + let l = try read(istr) + try istr.endEncapsulation() + seal.fulfill(l) + } catch { + seal.reject(error) + } + }, + exception: { error in + seal.reject(error) + }, + sent: createSentCallback(sentOn: sentOn, sentFlags: sentFlags, sent: sent)) + } + } + + private static func throwUserException(istr: InputStream, userException: ((UserException) throws -> Void)?) throws { + do { + try istr.startEncapsulation() + try istr.throwException() + } catch let error as UserException { + try istr.endEncapsulation() + if let userException = userException { + try userException(error) + } + throw UnknownUserException(unknown: error.ice_id()) + } + fatalError("Failed to throw user exception") + } + + public static func checkedCast(prx: ObjectPrx, + facet: String? = nil, + context: Context? = nil) throws -> ProxyImpl? + where ProxyImpl: ObjectPrxI { + do { + let objPrx = facet != nil ? prx.ice_facet(facet!) : prx + + // checkedCast always calls ice_isA - no optimization on purpose + guard try objPrx.ice_isA(id: ProxyImpl.ice_staticId(), context: context) else { + return nil + } + return ProxyImpl(from: objPrx) + } catch is FacetNotExistException { + return nil + } + } + + public static func uncheckedCast(prx: ObjectPrx, + facet: String? = nil) -> ProxyImpl where ProxyImpl: ObjectPrxI { + if let f = facet { + return ProxyImpl(from: prx.ice_facet(f)) + } else if let optimized = prx as? ProxyImpl { + return optimized + } else { + return ProxyImpl(from: prx) + } + } +} diff --git a/Sources/Ice/ServantManager.swift b/Sources/Ice/ServantManager.swift new file mode 100644 index 0000000..96c5327 --- /dev/null +++ b/Sources/Ice/ServantManager.swift @@ -0,0 +1,180 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +class ServantManager { + private let adapterName: String + private let communicator: Communicator + + private var servantMapMap = [Identity: [String: Disp]]() + private var defaultServantMap = [String: Disp]() + private var locatorMap = [String: ServantLocator]() + + // This is used to distingish between ObjectNotExistException and FacetNotExistException + // when a servant is not found on a Swift Admin OA. + private var adminId: Identity? + + private var mutex = Mutex() + + init(adapterName: String, communicator: Communicator) { + self.adapterName = adapterName + self.communicator = communicator + } + + func addServant(servant: Disp, id ident: Identity, facet: String) throws { + try mutex.sync { + if var m = servantMapMap[ident] { + if m[facet] != nil { + var id = communicator.identityToString(ident) + if !facet.isEmpty { + id += try " - f " + escapeString(string: facet, special: "", communicator: communicator) + } + throw AlreadyRegisteredException(kindOfObject: "servant", id: id) + } + m[facet] = servant + servantMapMap[ident] = m + } else { + servantMapMap[ident] = [facet: servant] + } + } + } + + func addDefaultServant(servant: Disp, category: String) throws { + try mutex.sync { + guard defaultServantMap[category] == nil else { + throw AlreadyRegisteredException(kindOfObject: "default servant", id: category) + } + + defaultServantMap[category] = servant + } + } + + func removeServant(id ident: Identity, facet: String) throws -> Disp { + return try mutex.sync { + guard var m = servantMapMap[ident], let obj = m.removeValue(forKey: facet) else { + var id = communicator.identityToString(ident) + if !facet.isEmpty { + id += try " - f " + escapeString(string: facet, special: "", communicator: communicator) + } + throw NotRegisteredException(kindOfObject: "servant", id: id) + } + + if m.isEmpty { + servantMapMap.removeValue(forKey: ident) + } else { + servantMapMap[ident] = m + } + return obj + } + } + + func removeDefaultServant(category: String) throws -> Disp { + return try mutex.sync { + guard let obj = defaultServantMap.removeValue(forKey: category) else { + throw NotRegisteredException(kindOfObject: "default servant", id: category) + } + + return obj + } + } + + func removeAllFacets(id: Identity) throws -> FacetMap { + return try mutex.sync { + guard let m = servantMapMap.removeValue(forKey: id) else { + throw NotRegisteredException(kindOfObject: "servant", id: identityToString(id: id)) + } + + return m + } + } + + func findServant(id: Identity, facet: String) -> Disp? { + return mutex.sync { + guard let m = servantMapMap[id] else { + guard let obj = defaultServantMap[id.category] else { + return defaultServantMap[""] + } + + return obj + } + + return m[facet] + } + } + + func findDefaultServant(category: String) -> Disp? { + return mutex.sync { + defaultServantMap[category] + } + } + + func findAllFacets(id: Identity) -> FacetMap { + return mutex.sync { + guard let m = servantMapMap[id] else { + return FacetMap() + } + + return m + } + } + + func hasServant(id: Identity) -> Bool { + return mutex.sync { + servantMapMap[id] != nil + } + } + + func addServantLocator(locator: ServantLocator, category: String) throws { + return try mutex.sync { + guard locatorMap[category] == nil else { + let id = try escapeString(string: category, special: "", communicator: communicator) + throw AlreadyRegisteredException(kindOfObject: "servant locator", id: id) + } + + locatorMap[category] = locator + } + } + + func removeServantLocator(category: String) throws -> ServantLocator { + return try mutex.sync { + guard let l = locatorMap.removeValue(forKey: category) else { + let id = try escapeString(string: category, special: "", communicator: communicator) + throw NotRegisteredException(kindOfObject: "servant locator", id: id) + } + + return l + } + } + + func findServantLocator(category: String) -> ServantLocator? { + return mutex.sync { + locatorMap[category] + } + } + + func setAdminId(_ id: Identity) { + mutex.sync { + adminId = id + } + } + + func isAdminId(_ id: Identity) -> Bool { + return mutex.sync { + adminId == id + } + } + + func destroy() { + var m = [String: ServantLocator]() + mutex.sync { + servantMapMap.removeAll() + defaultServantMap.removeAll() + m = locatorMap + locatorMap.removeAll() + } + + m.forEach { category, locator in + locator.deactivate(category) + } + } +} diff --git a/Sources/Ice/SliceFlags.swift b/Sources/Ice/SliceFlags.swift new file mode 100644 index 0000000..6b5e9bc --- /dev/null +++ b/Sources/Ice/SliceFlags.swift @@ -0,0 +1,17 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +struct SliceFlags: OptionSet { + let rawValue: UInt8 + + static let FLAG_HAS_TYPE_ID_STRING = SliceFlags(rawValue: 1 << 0) + static let FLAG_HAS_TYPE_ID_INDEX = SliceFlags(rawValue: 1 << 1) + static let FLAG_HAS_TYPE_ID_COMPACT = SliceFlags(rawValue: 1 << 1 | 1 << 0) + static let FLAG_HAS_OPTIONAL_MEMBERS = SliceFlags(rawValue: 1 << 2) + static let FLAG_HAS_INDIRECTION_TABLE = SliceFlags(rawValue: 1 << 3) + static let FLAG_HAS_SLICE_SIZE = SliceFlags(rawValue: 1 << 4) + static let FLAG_IS_LAST_SLICE = SliceFlags(rawValue: 1 << 5) + + static let OPTIONAL_END_MARKER = SliceFlags(rawValue: 0xFF) +} diff --git a/Sources/Ice/SliceInfo.swift b/Sources/Ice/SliceInfo.swift new file mode 100644 index 0000000..ee6549e --- /dev/null +++ b/Sources/Ice/SliceInfo.swift @@ -0,0 +1,26 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Foundation + +/// SliceInfo encapsulates the details of a slice for an unknown class or exception type. +public struct SliceInfo { + /// The Slice type ID for this slice. + public let typeId: String + + /// The Slice compact type ID for this slice. + public let compactId: Int32 + + /// The encoded bytes for this slice, including the leading size integer. + public let bytes: Data + + /// The class instances referenced by this slice. + public var instances: [Ice.Value] + + /// Whether or not the slice contains optional members. + public let hasOptionalMembers: Bool + + /// Whether or not this is the last slice. + public let isLastSlice: Bool +} diff --git a/Sources/Ice/SlicedData.swift b/Sources/Ice/SlicedData.swift new file mode 100644 index 0000000..c3eccc4 --- /dev/null +++ b/Sources/Ice/SlicedData.swift @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// SlicedData holds the slices of unknown class or exception types. +public final class SlicedData { + /// The details of each slice, in order of most-derived to least-derived. + public private(set) var slices: [SliceInfo] + + init(slices: [SliceInfo]) { + self.slices = slices + } + + /// Clears the slices to break potential cyclic references. + public func clear() { + let copy = slices + slices = [] // need to clear the slices before the loop to avoid recursive calls + for slice in copy { + for value in slice.instances { + value.ice_getSlicedData()?.clear() + } + } + } +} diff --git a/Sources/Ice/UnknownSlicedValue.swift b/Sources/Ice/UnknownSlicedValue.swift new file mode 100644 index 0000000..1cec309 --- /dev/null +++ b/Sources/Ice/UnknownSlicedValue.swift @@ -0,0 +1,46 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/// Unknown sliced value holds an instance of an unknown Slice class type. +public final class UnknownSlicedValue: Value { + private let unknownTypeId: String + private var slicedData: SlicedData? + + public required init() { + unknownTypeId = "" + } + + public init(unknownTypeId: String) { + self.unknownTypeId = unknownTypeId + } + + /// Returns the Slice type ID associated with this object. + /// + /// - returns: `String` - The type ID. + public override func ice_id() -> String { + return unknownTypeId + } + + public override class func ice_staticId() -> String { + return "::Ice::UnknownSlicedValue" + } + + /// Returns the sliced data if the value has a preserved-slice base class and has been sliced during + /// un-marshaling of the value, nil is returned otherwise. + /// + /// - returns: `Ice.SlicedData?` - The sliced data or nil. + public override func ice_getSlicedData() -> SlicedData? { + return slicedData + } + + public override func _iceRead(from ins: InputStream) throws { + ins.startValue() + slicedData = try ins.endValue(preserve: true) + } + + public override func _iceWrite(to os: OutputStream) { + os.startValue(data: slicedData) + os.endValue() + } +} diff --git a/Sources/Ice/Util.swift b/Sources/Ice/Util.swift new file mode 100644 index 0000000..bae6b79 --- /dev/null +++ b/Sources/Ice/Util.swift @@ -0,0 +1,82 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +import Dispatch +import IceImpl + +/// Converts a string to an encoding version. +/// +/// - parameter _: `String` - The string to convert. +/// +/// - returns: `Ice.EncodingVersion` - The converted encoding version. +func stringToEncodingVersion(_ s: String) throws -> EncodingVersion { + let (major, minor) = try stringToMajorMinor(s) + return EncodingVersion(major: major, minor: minor) +} + +func stringToMajorMinor(_ s: String) throws -> (UInt8, UInt8) { + let components = s.components(separatedBy: ".") + guard components.count == 2 else { + throw VersionParseException(str: "malformed value `\(s)'") + } + + guard let major = UInt8(components[0] as String), let minor = UInt8(components[1]) else { + throw VersionParseException(str: "invalid version value `\(s)'") + } + + return (major, minor) +} + +func createSentCallback(sentOn: DispatchQueue?, + sentFlags: DispatchWorkItemFlags?, + sent: ((Bool) -> Void)?) -> ((Bool) -> Void)? { + guard let s = sent else { + // If sent is nil, we keep it as-is + return sent + } + + guard let q = sentOn else { + // If sentOn is nil, we just wrap sent in an autorelease pool + return { sentSynchronously in + autoreleasepool { + s(sentSynchronously) + } + } + } + + // + // Create a closure to dispatch the sent callback in the specified queue + // + if let flags = sentFlags { + return { sentSynchronously in + q.async(flags: flags) { + s(sentSynchronously) + } + } + } else { + return { sentSynchronously in + q.async { + s(sentSynchronously) + } + } + } +} + +func escapeString(string: String, special: String, communicator: Communicator) throws -> String { + guard factoriesRegistered else { + fatalError("Unable to initialie Ice") + } + return try autoreleasepool { + try ICEUtil.escapeString(string: string, + special: special, + communicator: (communicator as! CommunicatorI).handle) + } +} + +func checkSupportedEncoding(_ v: EncodingVersion) throws { + let c = currentEncoding + if v.major != c.major || v.minor > c.minor { + throw UnsupportedEncodingException(reason: "", bad: v, supported: c) + } +} diff --git a/Sources/Ice/Value.swift b/Sources/Ice/Value.swift new file mode 100644 index 0000000..c5b8906 --- /dev/null +++ b/Sources/Ice/Value.swift @@ -0,0 +1,83 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// The base class for all Ice values. +open class Value { + public required init() {} + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID. + open func ice_id() -> String { + return ObjectTraits.staticId + } + + open func _iceReadImpl(from _: InputStream) throws {} + + open func _iceWriteImpl(to _: OutputStream) {} + + /// The Ice run time invokes this method prior to marshaling an object's data members. + /// This allows a subclass to override this method in order to validate its data + /// members. + open func ice_preMarshal() {} + + /// This Ice run time invokes this method after unmarshaling an object's data members. This allows a + /// subclass to override this method in order to perform additional initialization. + open func ice_postUnmarshal() {} + + /// Returns the sliced data if the value has a preserved-slice base class and has been sliced during + /// un-marshaling of the value, nil is returned otherwise. + /// + /// - returns: `SlicedData?` - The sliced data or nil. + open func ice_getSlicedData() -> SlicedData? { + return nil + } + + open func _iceRead(from istr: InputStream) throws { + istr.startValue() + try _iceReadImpl(from: istr) + try istr.endValue(preserve: false) + } + + open func _iceWrite(to os: OutputStream) { + os.startValue(data: nil) + _iceWriteImpl(to: os) + os.endValue() + } + + /// Returns the Slice type ID of this object. + /// + /// - returns: `String` - The Slice type ID. + open class func ice_staticId() -> String { + return ObjectTraits.staticId + } +} + +/// Helper class used to represent an interface passed by value. Note that +/// passing interface by values is deprecated. +open class InterfaceByValue: Value { + private var id: String + + public required init() { + fatalError("Not supported") + } + + public init(id: String) { + self.id = id + } + + open override func ice_id() -> String { + return id + } + + open override func _iceReadImpl(from ostr: InputStream) throws { + _ = try ostr.startSlice() + try ostr.endSlice() + } + + open override func _iceWriteImpl(to istr: OutputStream) { + istr.startSlice(typeId: ice_id(), compactId: -1, last: true) + istr.endSlice() + } +} diff --git a/Sources/Ice/ValueFactoryManagerI.swift b/Sources/Ice/ValueFactoryManagerI.swift new file mode 100644 index 0000000..0902d57 --- /dev/null +++ b/Sources/Ice/ValueFactoryManagerI.swift @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +class ValueFactoryManagerI: ValueFactoryManager { + private var factories = [String: ValueFactory]() + private var mutex = Mutex() + + func add(factory: @escaping ValueFactory, id: String) throws { + try mutex.sync { + if factories[id] != nil { + throw AlreadyRegisteredException(kindOfObject: "value factory", id: id, file: #file, line: #line) + } + factories[id] = factory + } + } + + func find(_ id: String) -> ValueFactory? { + return mutex.sync { + factories[id] + } + } +} diff --git a/Sources/IceCpp/ACM.cpp b/Sources/IceCpp/ACM.cpp new file mode 100644 index 0000000..3bfa3df --- /dev/null +++ b/Sources/IceCpp/ACM.cpp @@ -0,0 +1,380 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(ACMMonitor* p) { return p; } +IceUtil::Shared* IceInternal::upCast(FactoryACMMonitor* p) { return p; } +#endif + +IceInternal::ACMConfig::ACMConfig(bool server) : + timeout(IceUtil::Time::seconds(60)), + heartbeat(ICE_ENUM(ACMHeartbeat, HeartbeatOnDispatch)), + close(server ? ICE_ENUM(ACMClose, CloseOnInvocation) : ICE_ENUM(ACMClose, CloseOnInvocationAndIdle)) +{ +} + +IceInternal::ACMConfig::ACMConfig(const Ice::PropertiesPtr& p, + const Ice::LoggerPtr& l, + const string& prefix, + const ACMConfig& dflt) +{ + string timeoutProperty; + if((prefix == "Ice.ACM.Client" || prefix == "Ice.ACM.Server") && p->getProperty(prefix + ".Timeout").empty()) + { + timeoutProperty = prefix; // Deprecated property. + } + else + { + timeoutProperty = prefix + ".Timeout"; + } + + int timeoutVal = p->getPropertyAsIntWithDefault(timeoutProperty, static_cast(dflt.timeout.toSeconds())); + if(timeoutVal >= 0) + { + timeout = IceUtil::Time::seconds(timeoutVal); + } + else + { + l->warning("invalid value for property `" + timeoutProperty + "', default value will be used instead"); + timeout = dflt.timeout; + } + + int hb = p->getPropertyAsIntWithDefault(prefix + ".Heartbeat", static_cast(dflt.heartbeat)); + if(hb >= static_cast(ICE_ENUM(ACMHeartbeat, HeartbeatOff)) && + hb <= static_cast(ICE_ENUM(ACMHeartbeat, HeartbeatAlways))) + { + heartbeat = static_cast(hb); + } + else + { + l->warning("invalid value for property `" + prefix + ".Heartbeat" + "', default value will be used instead"); + heartbeat = dflt.heartbeat; + } + + int cl = p->getPropertyAsIntWithDefault(prefix + ".Close", static_cast(dflt.close)); + if(cl >= static_cast(ICE_ENUM(ACMClose, CloseOff)) && + cl <= static_cast(ICE_ENUM(ACMClose, CloseOnIdleForceful))) + { + close = static_cast(cl); + } + else + { + l->warning("invalid value for property `" + prefix + ".Close" + "', default value will be used instead"); + close = dflt.close; + } +} + +IceInternal::FactoryACMMonitor::FactoryACMMonitor(const InstancePtr& instance, const ACMConfig& config) : + _instance(instance), _config(config) +{ +} + +IceInternal::FactoryACMMonitor::~FactoryACMMonitor() +{ + assert(!_instance); + assert(_connections.empty()); + assert(_changes.empty()); + assert(_reapedConnections.empty()); +} + +void +IceInternal::FactoryACMMonitor::destroy() +{ + Lock sync(*this); + if(!_instance) + { + // + // Ensure all the connections have been cleared, it's important to wait here + // to prevent the timer destruction in IceInternal::Instance::destroy. + // + while(!_connections.empty()) + { + wait(); + } + return; + } + + // + // Cancel the scheduled timer task and schedule it again now to clear the + // connection set from the timer thread. + // + if(!_connections.empty()) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + _instance->timer()->schedule(ICE_SHARED_FROM_THIS, IceUtil::Time()); + } + + _instance = 0; + _changes.clear(); + + // + // Wait for the connection set to be cleared by the timer thread. + // + while(!_connections.empty()) + { + wait(); + } +} + +void +IceInternal::FactoryACMMonitor::add(const ConnectionIPtr& connection) +{ + if(_config.timeout == IceUtil::Time()) + { + return; + } + + Lock sync(*this); + if(_connections.empty()) + { + _connections.insert(connection); + _instance->timer()->scheduleRepeated(ICE_SHARED_FROM_THIS, _config.timeout / 2); + } + else + { + _changes.push_back(make_pair(connection, true)); + } +} + +void +IceInternal::FactoryACMMonitor::remove(const ConnectionIPtr& connection) +{ + if(_config.timeout == IceUtil::Time()) + { + return; + } + + Lock sync(*this); + assert(_instance); + _changes.push_back(make_pair(connection, false)); +} + +void +IceInternal::FactoryACMMonitor::reap(const ConnectionIPtr& connection) +{ + Lock sync(*this); + _reapedConnections.push_back(connection); +} + +ACMMonitorPtr +IceInternal::FactoryACMMonitor::acm(const IceUtil::Optional& timeout, + const IceUtil::Optional& close, + const IceUtil::Optional& heartbeat) +{ + Lock sync(*this); + assert(_instance); + + ACMConfig config(_config); + if(timeout) + { + config.timeout = IceUtil::Time::seconds(*timeout); + } + if(close) + { + config.close = *close; + } + if(heartbeat) + { + config.heartbeat = *heartbeat; + } + return ICE_MAKE_SHARED(ConnectionACMMonitor, ICE_SHARED_FROM_THIS, _instance->timer(), config); +} + +Ice::ACM +IceInternal::FactoryACMMonitor::getACM() +{ + Ice::ACM acm; + acm.timeout = static_cast(_config.timeout.toSeconds()); + acm.close = _config.close; + acm.heartbeat = _config.heartbeat; + return acm; +} + +void +IceInternal::FactoryACMMonitor::swapReapedConnections(vector& connections) +{ + Lock sync(*this); + _reapedConnections.swap(connections); +} + +void +IceInternal::FactoryACMMonitor::runTimerTask() +{ + { + Lock sync(*this); + if(!_instance) + { + _connections.clear(); + notifyAll(); + return; + } + + for(vector >::const_iterator p = _changes.begin(); p != _changes.end(); ++p) + { + if(p->second) + { + _connections.insert(p->first); + } + else + { + _connections.erase(p->first); + } + } + _changes.clear(); + + if(_connections.empty()) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + return; + } + } + + // + // Monitor connections outside the thread synchronization, so + // that connections can be added or removed during monitoring. + // + IceUtil::Time now = IceUtil::Time::now(IceUtil::Time::Monotonic); + for(set::const_iterator p = _connections.begin(); p != _connections.end(); ++p) + { + try + { + (*p)->monitor(now, _config); + } + catch(const exception& ex) + { + handleException(ex); + } + catch(...) + { + handleException(); + } + } +} + +void +FactoryACMMonitor::handleException(const exception& ex) +{ + Lock sync(*this); + if(!_instance) + { + return; + } + + Error out(_instance->initializationData().logger); + out << "exception in connection monitor:\n" << ex.what(); +} + +void +FactoryACMMonitor::handleException() +{ + Lock sync(*this); + if(!_instance) + { + return; + } + + Error out(_instance->initializationData().logger); + out << "unknown exception in connection monitor"; +} + +IceInternal::ConnectionACMMonitor::ConnectionACMMonitor(const FactoryACMMonitorPtr& parent, + const IceUtil::TimerPtr& timer, + const ACMConfig& config) : + _parent(parent), _timer(timer), _config(config) +{ +} + +IceInternal::ConnectionACMMonitor::~ConnectionACMMonitor() +{ + assert(!_connection); +} + +void +IceInternal::ConnectionACMMonitor::add(const ConnectionIPtr& connection) +{ + Lock sync(*this); + assert(!_connection && connection); + _connection = connection; + if(_config.timeout != IceUtil::Time()) + { + _timer->scheduleRepeated(ICE_SHARED_FROM_THIS, _config.timeout / 2); + } +} + +void +IceInternal::ConnectionACMMonitor::remove(ICE_MAYBE_UNUSED const ConnectionIPtr& connection) +{ +#ifdef _MSC_VER + UNREFERENCED_PARAMETER(connection); +#endif + Lock sync(*this); + assert(_connection == connection); + if(_config.timeout != IceUtil::Time()) + { + _timer->cancel(ICE_SHARED_FROM_THIS); + } + _connection = 0; +} + +void +IceInternal::ConnectionACMMonitor::reap(const ConnectionIPtr& connection) +{ + _parent->reap(connection); +} + +ACMMonitorPtr +IceInternal::ConnectionACMMonitor::acm(const IceUtil::Optional& timeout, + const IceUtil::Optional& close, + const IceUtil::Optional& heartbeat) +{ + return _parent->acm(timeout, close, heartbeat); +} + +Ice::ACM +IceInternal::ConnectionACMMonitor::getACM() +{ + Ice::ACM acm; + acm.timeout = static_cast(_config.timeout.toSeconds()); + acm.close = _config.close; + acm.heartbeat = _config.heartbeat; + return acm; +} + +void +IceInternal::ConnectionACMMonitor::runTimerTask() +{ + Ice::ConnectionIPtr connection; + { + Lock sync(*this); + if(!_connection) + { + return; + } + connection = _connection; + } + + try + { + connection->monitor(IceUtil::Time::now(IceUtil::Time::Monotonic), _config); + } + catch(const exception& ex) + { + _parent->handleException(ex); + } + catch(...) + { + _parent->handleException(); + } +} diff --git a/Sources/IceCpp/Acceptor.cpp b/Sources/IceCpp/Acceptor.cpp new file mode 100644 index 0000000..4728192 --- /dev/null +++ b/Sources/IceCpp/Acceptor.cpp @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Acceptor::~Acceptor() +{ + // Out of line to avoid weak vtable +} + +IceUtil::Shared* IceInternal::upCast(Acceptor* p) { return p; } diff --git a/Sources/IceCpp/Application.cpp b/Sources/IceCpp/Application.cpp new file mode 100644 index 0000000..fffd70d --- /dev/null +++ b/Sources/IceCpp/Application.cpp @@ -0,0 +1,661 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +#ifdef _WIN32 +const DWORD SIGHUP = CTRL_LOGOFF_EVENT; +#else +# include +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceUtil; +using namespace IceUtilInternal; + +// +// static member initialization +// +IceUtil::Mutex Ice::Application::_mutex; +IceUtil::Cond Ice::Application::_condVar; + +bool Ice::Application::_callbackInProgress = false; +bool Ice::Application::_destroyed = false; +bool Ice::Application::_interrupted = false; + +string Ice::Application::_appName; +Ice::CommunicatorPtr Ice::Application::_communicator; +Ice::SignalPolicy Ice::Application::_signalPolicy = ICE_ENUM(SignalPolicy, HandleSignals); +Ice::Application* Ice::Application::_application = 0; + +namespace +{ + +// +// Variables than can change while run() and communicator->destroy() are running! +// +bool _released = true; +CtrlCHandlerCallback _previousCallback = ICE_NULLPTR; + +// +// Variables that are immutable during run() and until communicator->destroy() has returned; +// before and after run(), and once communicator->destroy() has returned, we assume that +// only the main thread and CtrlCHandler threads are running. +// +CtrlCHandler* _ctrlCHandler = 0; +bool _nohup = false; + +} + +Ice::Application::Application(SignalPolicy signalPolicy) +{ + Ice::Application::_signalPolicy = signalPolicy; +} + +Ice::Application::~Application() +{ +} + +int +Ice::Application::main(int argc, const char* const argv[], ICE_CONFIG_FILE_STRING configFile, int version) +{ + _appName = ""; + if(argc > 0) + { + _appName = argv[0]; + } + + if(argc > 0 && argv[0] && ICE_DYNAMIC_CAST(LoggerI, getProcessLogger())) + { + setProcessLogger(ICE_MAKE_SHARED(LoggerI, argv[0], "", true)); + } + + InitializationData initData; +#ifndef ICE_CPP11_MAPPING + if(configFile) +#endif + { + try + { + initData.properties = createProperties(); + initData.properties->load(configFile); + } + catch(const Ice::Exception& ex) + { + Error out(getProcessLogger()); + out << ex; + return EXIT_FAILURE; + } + catch(const std::exception& ex) + { + Error out(getProcessLogger()); + out << ex; + return EXIT_FAILURE; + } + catch(...) + { + Error out(getProcessLogger()); + out << "unknown exception"; + return EXIT_FAILURE; + } + } + return main(argc, argv, initData, version); +} + +#ifdef _WIN32 +int +Ice::Application::main(int argc, const wchar_t* const argv[], const Ice::InitializationData& initData, int version) +{ + // + // On Windows the given wchar_t* strings are UTF16 and therefore + // needs to be converted to native narrow string encoding. + // + return main(argsToStringSeq(argc, argv), initData, version); +} + +int +Ice::Application::main(int argc, const wchar_t* const argv[], ICE_CONFIG_FILE_STRING config, int version) +{ + return main(argsToStringSeq(argc, argv), config, version); +} +#endif + +int +Ice::Application::main(int argc, const char* const argv[], const InitializationData& initializationData, int version) +{ + if(argc > 0 && argv[0] && ICE_DYNAMIC_CAST(LoggerI, getProcessLogger())) + { + const bool convert = initializationData.properties ? + initializationData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) > 0 && + initializationData.properties->getProperty("Ice.StdErr").empty() : true; + setProcessLogger(ICE_MAKE_SHARED(LoggerI, argv[0], "", convert)); + } + + if(_communicator != 0) + { + Error out(getProcessLogger()); + out << "only one instance of the Application class can be used"; + return EXIT_FAILURE; + } + int status; + + ArgVector av(argc, argv); // copy args + + // + // We parse the properties here to extract Ice.ProgramName. + // + InitializationData initData = initializationData; + try + { + initData.properties = createProperties(av.argc, av.argv, initData.properties); + } + catch(const Ice::Exception& ex) + { + Error out(getProcessLogger()); + out << ex; + return EXIT_FAILURE; + } + catch(const std::exception& ex) + { + Error out(getProcessLogger()); + out << ex; + return EXIT_FAILURE; + } + catch(...) + { + Error out(getProcessLogger()); + out << "unknown exception"; + return EXIT_FAILURE; + } + _appName = initData.properties->getPropertyWithDefault("Ice.ProgramName", _appName); + + // + // Used by destroyOnInterruptCallback and shutdownOnInterruptCallback. + // + _nohup = initData.properties->getPropertyAsInt("Ice.Nohup") > 0; + + _application = this; + + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + try + { + // + // The ctrlCHandler must be created before starting any thread, in particular + // before initializing the communicator. + // + CtrlCHandler ctrCHandler; + _ctrlCHandler = &ctrCHandler; + + status = doMain(av.argc, av.argv, initData, version); + + // + // Set _ctrlCHandler to 0 only once communicator->destroy() has completed. + // + _ctrlCHandler = 0; + } + catch(const CtrlCHandlerException&) + { + Error out(getProcessLogger()); + out << "only one instance of the CtrlCHandler class can be used"; + status = EXIT_FAILURE; + } + } + else + { + status = doMain(av.argc, av.argv, initData, version); + } + + return status; +} + +int +Ice::Application::main(const StringSeq& args, const InitializationData& initData, int version) +{ + ArgVector av(args); + return main(av.argc, av.argv, initData, version); +} + +int +Ice::Application::main(const StringSeq& args, ICE_CONFIG_FILE_STRING configFile, int version) +{ + ArgVector av(args); + return main(av.argc, av.argv, configFile, version); +} + +void +Ice::Application::interruptCallback(int) +{ +} + +const char* +Ice::Application::appName() +{ + return _appName.c_str(); +} + +CommunicatorPtr +Ice::Application::communicator() +{ + return _communicator; +} + +void +Ice::Application::destroyOnInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(!_released) + { + _released = true; + _condVar.signal(); + } + _ctrlCHandler->setCallback(destroyOnInterruptCallback); + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +void +Ice::Application::shutdownOnInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(!_released) + { + _released = true; + _condVar.signal(); + } + _ctrlCHandler->setCallback(shutdownOnInterruptCallback); + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +void +Ice::Application::ignoreInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(!_released) + { + _released = true; + _condVar.signal(); + } + _ctrlCHandler->setCallback(0); + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +void +Ice::Application::callbackOnInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(!_released) + { + _released = true; + _condVar.signal(); + } + _ctrlCHandler->setCallback(callbackOnInterruptCallback); + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +void +Ice::Application::holdInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(_released) + { + _released = false; + _previousCallback = _ctrlCHandler->setCallback(holdInterruptCallback); + } + // else, we were already holding signals + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +void +Ice::Application::releaseInterrupt() +{ + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + if(_ctrlCHandler != 0) + { + Mutex::Lock lock(_mutex); // we serialize all the interrupt-setting + if(!_released) + { + // + // Note that it's very possible no signal is held; + // in this case the callback is just replaced and + // setting _released to true and signalling _condVar + // do no harm. + // + + _released = true; + _ctrlCHandler->setCallback(_previousCallback); + _condVar.signal(); + } + // Else nothing to release. + } + } + else + { + Warning out(getProcessLogger()); + out << "interrupt method called on Application configured to not handle interrupts."; + } +} + +bool +Ice::Application::interrupted() +{ + Mutex::Lock lock(_mutex); + return _interrupted; +} + +int +Ice::Application::doMain(int argc, char* argv[], const InitializationData& initData, int version) +{ + int status; + + try + { + _interrupted = false; + + // + // If the process logger is the default logger, we now replace it with a + // a logger which is using the program name for the prefix. + // + if(initData.properties->getProperty("Ice.ProgramName") != "" && ICE_DYNAMIC_CAST(LoggerI, getProcessLogger())) + { + const bool convert = + initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) > 0 && + initData.properties->getProperty("Ice.StdErr").empty(); + + setProcessLogger(ICE_MAKE_SHARED(LoggerI, initData.properties->getProperty("Ice.ProgramName"), "", convert)); + } + + _communicator = initialize(argc, argv, initData, version); + _destroyed = false; + + // + // The default is to destroy when a signal is received. + // + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + destroyOnInterrupt(); + } + + status = run(argc, argv); + } + catch(const Ice::Exception& ex) + { + Error out(getProcessLogger()); + out << ex; + status = EXIT_FAILURE; + } + catch(const std::exception& ex) + { + Error out(getProcessLogger()); + out << ex; + status = EXIT_FAILURE; + } + catch(const std::string& msg) + { + Error out(getProcessLogger()); + out << msg; + status = EXIT_FAILURE; + } + catch(const char* msg) + { + Error out(getProcessLogger()); + out << msg; + status = EXIT_FAILURE; + } + catch(...) + { + Error out(getProcessLogger()); + out << "unknown exception"; + status = EXIT_FAILURE; + } + + // + // Don't want any new interrupt and at this point (post-run), + // it would not make sense to release a held signal to run + // shutdown or destroy. + // + if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) + { + ignoreInterrupt(); + } + + { + Mutex::Lock lock(_mutex); + while(_callbackInProgress) + { + _condVar.wait(lock); + } + if(_destroyed) + { + _communicator = 0; + } + else + { + _destroyed = true; + // + // And _communicator != 0, meaning will be destroyed + // next, _destroyed = true also ensures that any + // remaining callback won't do anything + // + } + _application = 0; + } + + if(_communicator != 0) + { + _communicator->destroy(); + _communicator = 0; + } + + return status; +} + +// +// CtrlCHandler callbacks. +// + +void +Ice::Application::holdInterruptCallback(int signal) +{ + CtrlCHandlerCallback callback = ICE_NULLPTR; + { + Mutex::Lock lock(_mutex); + while(!_released) + { + _condVar.wait(lock); + } + + if(_destroyed) + { + // + // Being destroyed by main thread + // + return; + } + assert(_ctrlCHandler != 0); + callback = _ctrlCHandler->getCallback(); + } + + if(callback) + { + callback(signal); + } +} + +void +Ice::Application::destroyOnInterruptCallback(int signal) +{ + { + Mutex::Lock lock(_mutex); + if(_destroyed) + { + // + // Being destroyed by main thread + // + return; + } + if(_nohup && signal == static_cast(SIGHUP)) + { + return; + } + + assert(!_callbackInProgress); + _callbackInProgress = true; + _interrupted = true; + _destroyed = true; + } + + assert(_communicator != 0); + _communicator->destroy(); + + { + Mutex::Lock lock(_mutex); + _callbackInProgress = false; + } + _condVar.signal(); +} + +void +Ice::Application::shutdownOnInterruptCallback(int signal) +{ + { + Mutex::Lock lock(_mutex); + if(_destroyed) + { + // + // Being destroyed by main thread + // + return; + } + if(_nohup && signal == static_cast(SIGHUP)) + { + return; + } + + assert(!_callbackInProgress); + _callbackInProgress = true; + _interrupted = true; + } + + assert(_communicator != 0); + _communicator->shutdown(); + + { + Mutex::Lock lock(_mutex); + _callbackInProgress = false; + } + _condVar.signal(); +} + +void +Ice::Application::callbackOnInterruptCallback(int signal) +{ + { + Mutex::Lock lock(_mutex); + if(_destroyed) + { + // + // Being destroyed by main thread + // + return; + } + // For SIGHUP the user callback is always called. It can + // decide what to do. + assert(!_callbackInProgress); + _callbackInProgress = true; + _interrupted = true; + } + + try + { + assert(_application != 0); + _application->interruptCallback(signal); + } + catch(const Ice::Exception& ex) + { + Error out(getProcessLogger()); + out << "(while interrupting in response to signal " << signal << "): Ice::Exception: " << ex; + } + catch(const std::exception& ex) + { + Error out(getProcessLogger()); + out << "(while interrupting in response to signal " << signal << "): std::exception: " << ex; + } + catch(const std::string& msg) + { + Error out(getProcessLogger()); + out << "(while interrupting in response to signal " << signal << "): " << msg; + } + catch(const char* msg) + { + Error out(getProcessLogger()); + out << "(while interrupting in response to signal " << signal << "): " << msg; + } + catch(...) + { + Error out(getProcessLogger()); + out << "(while interrupting in response to signal " << signal << "): unknown exception"; + } + + { + Mutex::Lock lock(_mutex); + _callbackInProgress = false; + } + _condVar.signal(); +} diff --git a/Sources/IceCpp/ArgVector.cpp b/Sources/IceCpp/ArgVector.cpp new file mode 100644 index 0000000..2a057f9 --- /dev/null +++ b/Sources/IceCpp/ArgVector.cpp @@ -0,0 +1,59 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +IceInternal::ArgVector::ArgVector(int argcP, const char* const argvP[]) +{ + assert(argcP >= 0); + _args.resize(static_cast(argcP)); + for(size_t i = 0; i < static_cast(argcP); ++i) + { + _args[i] = argvP[i]; + } + setupArgcArgv(); +} + +IceInternal::ArgVector::ArgVector(const ::std::vector< ::std::string>& vec) +{ + _args = vec; + setupArgcArgv(); +} + +IceInternal::ArgVector::ArgVector(const ArgVector& rhs) +{ + _args = rhs._args; + setupArgcArgv(); +} + +IceInternal::ArgVector& +IceInternal::ArgVector::operator=(const ArgVector& rhs) +{ + delete[] argv; + argv = 0; + _args = rhs._args; + setupArgcArgv(); + return *this; +} + +IceInternal::ArgVector::~ArgVector() +{ + delete[] argv; +} + +void +IceInternal::ArgVector::setupArgcArgv() +{ + argc = static_cast(_args.size()); + if((argv = new char*[static_cast(argc + 1)]) == 0) + { + throw ::std::bad_alloc(); + } + for(size_t i = 0; i < static_cast(argc); i++) + { + argv[i] = const_cast(_args[i].c_str()); + } + argv[argc] = 0; +} diff --git a/Sources/IceCpp/AsyncResult.cpp b/Sources/IceCpp/AsyncResult.cpp new file mode 100644 index 0000000..9e89833 --- /dev/null +++ b/Sources/IceCpp/AsyncResult.cpp @@ -0,0 +1,70 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CPP11_MAPPING + +#include +#include + +using namespace std; +using namespace Ice; + +IceUtil::Shared* Ice::upCast(AsyncResult* p) { return p; } + +AsyncResult::~AsyncResult() +{ + // Out of line to avoid weak vtable +} + +void +AsyncResult::_check(const AsyncResultPtr& r, const IceProxy::Ice::Object* prx, const string& operation) +{ + check(r, operation); + if(r->getProxy().get() != prx) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Proxy for call to end_" + operation + + " does not match proxy that was used to call corresponding begin_" + + operation + " method"); + } +} + +void +AsyncResult::_check(const AsyncResultPtr& r, const Ice::Communicator* com, const string& operation) +{ + check(r, operation); + if(r->getCommunicator().get() != com) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Communicator for call to end_" + operation + + " does not match communicator that was used to call corresponding " + + "begin_" + operation + " method"); + } +} + +void +AsyncResult::_check(const AsyncResultPtr& r, const Ice::Connection* con, const string& operation) +{ + check(r, operation); + if(r->getConnection().get() != con) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Connection for call to end_" + operation + + " does not match connection that was used to call corresponding " + + "begin_" + operation + " method"); + } +} + +void +AsyncResult::check(const AsyncResultPtr& r, const string& operation) +{ + if(!r) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "AsyncResult == null"); + } + else if(r->getOperation() != operation) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Incorrect operation for end_" + operation + + " method: " + r->getOperation()); + } +} + +#endif diff --git a/Sources/IceCpp/Base64.cpp b/Sources/IceCpp/Base64.cpp new file mode 100644 index 0000000..488f59c --- /dev/null +++ b/Sources/IceCpp/Base64.cpp @@ -0,0 +1,263 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; + +string +IceInternal::Base64::encode(const vector& plainSeq) +{ + string retval; + + if(plainSeq.size() == 0) + { + return retval; + } + + // Reserve enough space for the returned base64 string + size_t base64Bytes = (((plainSeq.size() * 4) / 3) + 1); + size_t newlineBytes = (((base64Bytes * 2) / 76) + 1); + size_t totalBytes = base64Bytes + newlineBytes; + + retval.reserve(totalBytes); + + unsigned char by1 = 0; + unsigned char by2 = 0; + unsigned char by3 = 0; + unsigned char by4 = 0; + unsigned char by5 = 0; + unsigned char by6 = 0; + unsigned char by7 = 0; + + for(size_t i = 0; i < plainSeq.size(); i += 3) + { + by1 = plainSeq[i]; + by2 = 0; + by3 = 0; + + if((i + 1) < plainSeq.size()) + { + by2 = plainSeq[i+1]; + } + + if((i + 2) < plainSeq.size()) + { + by3 = plainSeq[i+2]; + } + + by4 = by1 >> 2; + by5 = static_cast((by1 & 0x3) << 4) | (by2 >> 4); + by6 = static_cast((by2 & 0xf) << 2) | (by3 >> 6); + by7 = by3 & 0x3f; + + retval += encode(by4); + retval += encode(by5); + + if((i + 1) < plainSeq.size()) + { + retval += encode(by6); + } + else + { + retval += "="; + } + + if((i + 2) < plainSeq.size()) + { + retval += encode(by7); + } + else + { + retval += "="; + } + } + + string outString; + outString.reserve(totalBytes); + string::iterator iter = retval.begin(); + + while((retval.end() - iter) > 76) + { + copy(iter, iter+76, back_inserter(outString)); + outString += "\r\n"; + iter += 76; + } + + copy(iter, retval.end(), back_inserter(outString)); + + return outString; +} + +vector +IceInternal::Base64::decode(const string& str) +{ + string newStr; + + newStr.reserve(str.length()); + + for(size_t j = 0; j < str.length(); j++) + { + if(isBase64(str[j])) + { + newStr += str[j]; + } + } + + vector retval; + + if(newStr.length() == 0) + { + return retval; + } + + // Note: This is how we were previously computing the size of the return + // sequence. The method below is more efficient (and correct). + // size_t lines = str.size() / 78; + // size_t totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4); + + // Figure out how long the final sequence is going to be. + size_t totalBytes = (newStr.size() * 3 / 4) + 1; + + retval.reserve(totalBytes); + + unsigned char by1 = 0; + unsigned char by2 = 0; + unsigned char by3 = 0; + unsigned char by4 = 0; + + char c1, c2, c3, c4; + + for(size_t i = 0; i < newStr.length(); i += 4) + { + c2 = 'A'; + c3 = 'A'; + c4 = 'A'; + + c1 = newStr[i]; + + if((i + 1) < newStr.length()) + { + c2 = newStr[i + 1]; + } + + if((i + 2) < newStr.length()) + { + c3 = newStr[i + 2]; + } + + if((i + 3) < newStr.length()) + { + c4 = newStr[i + 3]; + } + + by1 = decode(c1); + by2 = decode(c2); + by3 = decode(c3); + by4 = decode(c4); + + retval.push_back(static_cast(by1 << 2) | (by2 >> 4)); + + if(c3 != '=') + { + retval.push_back(static_cast((by2 & 0xf) << 4) | (by3 >> 2)); + } + + if(c4 != '=') + { + retval.push_back(static_cast((by3 & 0x3) << 6) | by4); + } + } + + return retval; +} + +bool +IceInternal::Base64::isBase64(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return true; + } + + if(c >= 'a' && c <= 'z') + { + return true; + } + + if(c >= '0' && c <= '9') + { + return true; + } + + if(c == '+') + { + return true; + } + + if(c == '/') + { + return true; + } + + if(c == '=') + { + return true; + } + + return false; +} + +char +IceInternal::Base64::encode(unsigned char uc) +{ + if(uc < 26) + { + return 'A' + static_cast(uc); + } + + if(uc < 52) + { + return 'a' + static_cast(uc) - 26; + } + + if(uc < 62) + { + return '0' + static_cast(uc) - 52; + } + + if(uc == 62) + { + return '+'; + } + + return '/'; +} + +unsigned char +IceInternal::Base64::decode(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return static_cast(c - 'A'); + } + + if(c >= 'a' && c <= 'z') + { + return static_cast(c - 'a' + 26); + } + + if(c >= '0' && c <= '9') + { + return static_cast(c - '0' + 52); + } + + if(c == '+') + { + return 62; + } + + return 63; +} diff --git a/Sources/IceCpp/BatchRequestQueue.cpp b/Sources/IceCpp/BatchRequestQueue.cpp new file mode 100644 index 0000000..5fb4474 --- /dev/null +++ b/Sources/IceCpp/BatchRequestQueue.cpp @@ -0,0 +1,250 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(BatchRequestQueue* p) { return p; } + +namespace +{ + +const int udpOverhead = 20 + 8; + +class BatchRequestI : public Ice::BatchRequest +{ +public: + + BatchRequestI(BatchRequestQueue& queue, const Ice::ObjectPrxPtr& proxy, const string& operation, int size) : + _queue(queue), _proxy(proxy), _operation(operation), _size(size) + { + } + + virtual void + enqueue() const + { + _queue.enqueueBatchRequest(_proxy); + } + + virtual int + getSize() const + { + return _size; + } + + virtual const std::string& + getOperation() const + { + return _operation; + } + + virtual const Ice::ObjectPrxPtr& + getProxy() const + { + return _proxy; + } + +private: + + BatchRequestQueue& _queue; + const Ice::ObjectPrxPtr& _proxy; + const std::string& _operation; + const int _size; +}; + +} + +BatchRequestQueue::BatchRequestQueue(const InstancePtr& instance, bool datagram) : + _interceptor(instance->initializationData().batchRequestInterceptor), + _batchStream(instance.get(), Ice::currentProtocolEncoding), + _batchStreamInUse(false), + _batchStreamCanFlush(false), + _batchCompress(false), + _batchRequestNum(0) +{ + _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr)); + _batchMarker = _batchStream.b.size(); + + _maxSize = instance->batchAutoFlushSize(); + if(_maxSize > 0 && datagram) + { + const Ice::InitializationData& initData = instance->initializationData(); + size_t udpSndSize = static_cast(initData.properties->getPropertyAsIntWithDefault("Ice.UDP.SndSize", 65535 - udpOverhead)); + if(udpSndSize < _maxSize) + { + _maxSize = udpSndSize; + } + } +} + +void +BatchRequestQueue::prepareBatchRequest(OutputStream* os) +{ + Lock sync(*this); + if(_exception) + { + _exception->ice_throw(); + } + waitStreamInUse(false); + _batchStreamInUse = true; + _batchStream.swap(*os); +} + +void +BatchRequestQueue::finishBatchRequest(OutputStream* os, + const Ice::ObjectPrxPtr& proxy, + const std::string& operation) +{ + // + // No need for synchronization, no other threads are supposed + // to modify the queue since we set _batchStreamInUse to true. + // + assert(_batchStreamInUse); + _batchStream.swap(*os); + + try + { + _batchStreamCanFlush = true; // Allow flush to proceed even if the stream is marked in use. + + if(_maxSize > 0 && _batchStream.b.size() >= _maxSize) + { +#ifdef ICE_CPP11_MAPPING + proxy->ice_flushBatchRequestsAsync(); +#else + proxy->begin_ice_flushBatchRequests(); +#endif + } + + assert(_batchMarker < _batchStream.b.size()); + if(_interceptor) + { + BatchRequestI request(*this, proxy, operation, static_cast(_batchStream.b.size() - _batchMarker)); +#ifdef ICE_CPP11_MAPPING + _interceptor(request, _batchRequestNum, static_cast(_batchMarker)); +#else + _interceptor->enqueue(request, _batchRequestNum, static_cast(_batchMarker)); +#endif + } + else + { + bool compress; + if(proxy->_getReference()->getCompressOverride(compress)) + { + _batchCompress |= compress; + } + _batchMarker = _batchStream.b.size(); + ++_batchRequestNum; + } + + Lock sync(*this); + _batchStream.resize(_batchMarker); + _batchStreamInUse = false; + _batchStreamCanFlush = false; + notifyAll(); + } + catch(const std::exception&) + { + Lock sync(*this); + _batchStream.resize(_batchMarker); + _batchStreamInUse = false; + _batchStreamCanFlush = false; + notifyAll(); + throw; + } +} + +void +BatchRequestQueue::abortBatchRequest(OutputStream* os) +{ + Lock sync(*this); + if(_batchStreamInUse) + { + _batchStream.swap(*os); + _batchStream.resize(_batchMarker); + _batchStreamInUse = false; + notifyAll(); + } +} + +int +BatchRequestQueue::swap(OutputStream* os, bool& compress) +{ + Lock sync(*this); + if(_batchRequestNum == 0) + { + return 0; + } + + waitStreamInUse(true); + + vector lastRequest; + if(_batchMarker < _batchStream.b.size()) + { + vector(_batchStream.b.begin() + _batchMarker, _batchStream.b.end()).swap(lastRequest); + _batchStream.b.resize(_batchMarker); + } + + int requestNum = _batchRequestNum; + _batchStream.swap(*os); + compress = _batchCompress; + + // + // Reset the batch. + // + _batchRequestNum = 0; + _batchCompress = false; + _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr)); + _batchMarker = _batchStream.b.size(); + if(!lastRequest.empty()) + { + _batchStream.writeBlob(&lastRequest[0], lastRequest.size()); + } + return requestNum; +} + +void +BatchRequestQueue::destroy(const Ice::LocalException& ex) +{ + Lock sync(*this); +#ifdef ICE_CPP11_MAPPING + _exception = ex.ice_clone(); +#else + _exception.reset(ex.ice_clone()); +#endif +} + +bool +BatchRequestQueue::isEmpty() +{ + Lock sync(*this); + return _batchStream.b.size() == sizeof(requestBatchHdr); +} + +void +BatchRequestQueue::waitStreamInUse(bool flush) +{ + while(_batchStreamInUse && !(flush && _batchStreamCanFlush)) + { + wait(); + } +} + +void +BatchRequestQueue::enqueueBatchRequest(const Ice::ObjectPrxPtr& proxy) +{ + assert(_batchMarker < _batchStream.b.size()); + bool compress; + if(proxy->_getReference()->getCompressOverride(compress)) + { + _batchCompress |= compress; + } + _batchMarker = _batchStream.b.size(); + ++_batchRequestNum; +} diff --git a/Sources/IceCpp/Buffer.cpp b/Sources/IceCpp/Buffer.cpp new file mode 100644 index 0000000..50e5d52 --- /dev/null +++ b/Sources/IceCpp/Buffer.cpp @@ -0,0 +1,155 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +void +IceInternal::Buffer::swapBuffer(Buffer& other) +{ + b.swap(other.b); + std::swap(i, other.i); +} + +IceInternal::Buffer::Container::Container() : + _buf(0), + _size(0), + _capacity(0), + _shrinkCounter(0), + _owned(true) +{ +} + +IceInternal::Buffer::Container::Container(const_iterator beg, const_iterator end) : + _buf(const_cast(beg)), + _size(static_cast(end - beg)), + _capacity(static_cast(end - beg)), + _shrinkCounter(0), + _owned(false) +{ +} + +IceInternal::Buffer::Container::Container(const vector& v) : + _shrinkCounter(0) +{ + if(v.empty()) + { + _buf = 0; + _size = 0; + _capacity = 0; + _owned = true; + } + else + { + _buf = const_cast(&v[0]); + _size = v.size(); + _capacity = _size; + _owned = false; + } +} + +IceInternal::Buffer::Container::Container(Container& other, bool adopt) +{ + if(adopt) + { + _buf = other._buf; + _size = other._size; + _capacity = other._capacity; + _shrinkCounter = other._shrinkCounter; + _owned = other._owned; + + other._buf = 0; + other._size = 0; + other._capacity = 0; + other._shrinkCounter = 0; + other._owned = true; + } + else + { + _buf = other._buf; + _size = other._size; + _capacity = other._capacity; + _shrinkCounter = 0; + _owned = false; + } +} + +IceInternal::Buffer::Container::~Container() +{ + if(_buf && _owned) + { + ::free(_buf); + } +} + +void +IceInternal::Buffer::Container::swap(Container& other) +{ + std::swap(_buf, other._buf); + std::swap(_size, other._size); + std::swap(_capacity, other._capacity); + std::swap(_shrinkCounter, other._shrinkCounter); + std::swap(_owned, other._owned); +} + +void +IceInternal::Buffer::Container::clear() +{ + if(_buf && _owned) + { + ::free(_buf); + } + + _buf = 0; + _size = 0; + _capacity = 0; + _shrinkCounter = 0; + _owned = true; +} + +void +IceInternal::Buffer::Container::reserve(size_type n) +{ + size_type c = _capacity; + if(n > _capacity) + { + _capacity = std::max(n, 2 * _capacity); + _capacity = std::max(static_cast(240), _capacity); + } + else if(n < _capacity) + { + _capacity = n; + } + else + { + return; + } + + pointer p; + if(_owned) + { + p = reinterpret_cast(::realloc(_buf, _capacity)); + } + else + { + p = reinterpret_cast(::malloc(_capacity)); + if(p) + { + ::memcpy(p, _buf, _size); + _owned = true; + } + } + + if(!p) + { + _capacity = c; // Restore the previous capacity. + throw std::bad_alloc(); + } + + _buf = p; +} diff --git a/Sources/IceCpp/BuiltinSequences.cpp b/Sources/IceCpp/BuiltinSequences.cpp new file mode 100644 index 0000000..8edf2a7 --- /dev/null +++ b/Sources/IceCpp/BuiltinSequences.cpp @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `BuiltinSequences.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#else // C++98 mapping + +#endif diff --git a/Sources/IceCpp/CollocatedRequestHandler.cpp b/Sources/IceCpp/CollocatedRequestHandler.cpp new file mode 100644 index 0000000..58f5247 --- /dev/null +++ b/Sources/IceCpp/CollocatedRequestHandler.cpp @@ -0,0 +1,407 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +class InvokeAllAsync : public DispatchWorkItem +{ +public: + + InvokeAllAsync(const OutgoingAsyncBasePtr& outAsync, + OutputStream* os, + const CollocatedRequestHandlerPtr& handler, + Int requestId, + Int batchRequestNum) : + _outAsync(outAsync), _os(os), _handler(handler), _requestId(requestId), _batchRequestNum(batchRequestNum) + { + } + + virtual void + run() + { + if(_handler->sentAsync(_outAsync.get())) + { + _handler->invokeAll(_os, _requestId, _batchRequestNum); + } + } + +private: + + OutgoingAsyncBasePtr _outAsync; + OutputStream* _os; + CollocatedRequestHandlerPtr _handler; + Int _requestId; + Int _batchRequestNum; +}; + +void +fillInValue(OutputStream* os, int pos, Int value) +{ + const Byte* p = reinterpret_cast(&value); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), os->b.begin() + pos); +#else + copy(p, p + sizeof(Int), os->b.begin() + pos); +#endif +} + +} + +CollocatedRequestHandler::CollocatedRequestHandler(const ReferencePtr& ref, const ObjectAdapterPtr& adapter) : + RequestHandler(ref), + _adapter(ICE_DYNAMIC_CAST(ObjectAdapterI, adapter)), + _dispatcher(_reference->getInstance()->initializationData().dispatcher), + _logger(_reference->getInstance()->initializationData().logger), // Cached for better performance. + _traceLevels(_reference->getInstance()->traceLevels()), // Cached for better performance. + _requestId(0) +{ +} + +CollocatedRequestHandler::~CollocatedRequestHandler() +{ +} + +RequestHandlerPtr +CollocatedRequestHandler::update(const RequestHandlerPtr& previousHandler, const RequestHandlerPtr& newHandler) +{ + return previousHandler.get() == this ? newHandler : ICE_SHARED_FROM_THIS; +} + +AsyncStatus +CollocatedRequestHandler::sendAsyncRequest(const ProxyOutgoingAsyncBasePtr& outAsync) +{ + return outAsync->invokeCollocated(this); +} + +void +CollocatedRequestHandler::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, const LocalException& ex) +{ + Lock sync(*this); + + map::iterator p = _sendAsyncRequests.find(outAsync); + if(p != _sendAsyncRequests.end()) + { + if(p->second > 0) + { + _asyncRequests.erase(p->second); + } + _sendAsyncRequests.erase(p); + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + _adapter->decDirectCount(); // invokeAll won't be called, decrease the direct count. + return; + } + + OutgoingAsyncPtr o = ICE_DYNAMIC_CAST(OutgoingAsync, outAsync); + if(o) + { + for(map::iterator q = _asyncRequests.begin(); q != _asyncRequests.end(); ++q) + { + if(q->second.get() == o.get()) + { + _asyncRequests.erase(q); + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + return; + } + } + } +} + +AsyncStatus +CollocatedRequestHandler::invokeAsyncRequest(OutgoingAsyncBase* outAsync, int batchRequestNum, bool synchronous) +{ + // + // Increase the direct count to prevent the thread pool from being destroyed before + // invokeAll is called. This will also throw if the object adapter has been deactivated. + // + _adapter->incDirectCount(); + + int requestId = 0; + try + { + Lock sync(*this); + + // + // This will throw if the request is canceled + // + outAsync->cancelable(ICE_SHARED_FROM_THIS); + + if(_response) + { + requestId = ++_requestId; + _asyncRequests.insert(make_pair(requestId, ICE_GET_SHARED_FROM_THIS(outAsync))); + } + + _sendAsyncRequests.insert(make_pair(ICE_GET_SHARED_FROM_THIS(outAsync), requestId)); + } + catch(...) + { + _adapter->decDirectCount(); + throw; + } + + outAsync->attachCollocatedObserver(_adapter, requestId); + + if(!synchronous || !_response || _reference->getInvocationTimeout() > 0) + { + // Don't invoke from the user thread if async or invocation timeout is set + _adapter->getThreadPool()->dispatch(new InvokeAllAsync(ICE_GET_SHARED_FROM_THIS(outAsync), + outAsync->getOs(), + ICE_SHARED_FROM_THIS, + requestId, + batchRequestNum)); + } + else if(_dispatcher) + { + _adapter->getThreadPool()->dispatchFromThisThread(new InvokeAllAsync(ICE_GET_SHARED_FROM_THIS(outAsync), + outAsync->getOs(), + ICE_SHARED_FROM_THIS, + requestId, + batchRequestNum)); + } + else // Optimization: directly call invokeAll if there's no dispatcher. + { + // + // Make sure to hold a reference on this handler while the call is being + // dispatched. Otherwise, the handler could be deleted during the dispatch + // if a retry occurs. + // + + CollocatedRequestHandlerPtr self(ICE_SHARED_FROM_THIS); + if(sentAsync(outAsync)) + { + invokeAll(outAsync->getOs(), requestId, batchRequestNum); + } + } + return AsyncStatusQueued; +} + +void +CollocatedRequestHandler::sendResponse(Int requestId, OutputStream* os, Byte, bool amd) +{ + OutgoingAsyncBasePtr outAsync; + { + Lock sync(*this); + assert(_response); + + if(_traceLevels->protocol >= 1) + { + fillInValue(os, 10, static_cast(os->b.size())); + } + + InputStream is(os->instance(), os->getEncoding(), *os, true); // Adopting the OutputStream's buffer. + is.pos(sizeof(replyHdr) + 4); + + if(_traceLevels->protocol >= 1) + { + traceRecv(is, _logger, _traceLevels); + } + + map::iterator q = _asyncRequests.find(requestId); + if(q != _asyncRequests.end()) + { + is.swap(*q->second->getIs()); + if(q->second->response()) + { + outAsync = q->second; + } + _asyncRequests.erase(q); + } + } + + if(outAsync) + { + // + // If called from an AMD dispatch, invoke asynchronously + // the completion callback since this might be called from + // the user code. + // + if(amd) + { + outAsync->invokeResponseAsync(); + } + else + { + outAsync->invokeResponse(); + } + } + + _adapter->decDirectCount(); +} + +void +CollocatedRequestHandler::sendNoResponse() +{ + _adapter->decDirectCount(); +} + +bool +CollocatedRequestHandler::systemException(Int requestId, const SystemException& ex, bool amd) +{ + handleException(requestId, ex, amd); + _adapter->decDirectCount(); + return true; +} + +void +CollocatedRequestHandler::invokeException(Int requestId, const LocalException& ex, int /*invokeNum*/, bool amd) +{ + handleException(requestId, ex, amd); + _adapter->decDirectCount(); +} + +ConnectionIPtr +CollocatedRequestHandler::getConnection() +{ + return 0; +} + +ConnectionIPtr +CollocatedRequestHandler::waitForConnection() +{ + return 0; +} + +bool +CollocatedRequestHandler::sentAsync(OutgoingAsyncBase* outAsync) +{ + { + Lock sync(*this); + if(_sendAsyncRequests.erase(ICE_GET_SHARED_FROM_THIS(outAsync)) == 0) + { + return false; // The request timed-out. + } + + if(!outAsync->sent()) + { + return true; + } + } + outAsync->invokeSent(); + return true; +} + +void +CollocatedRequestHandler::invokeAll(OutputStream* os, Int requestId, Int batchRequestNum) +{ + if(_traceLevels->protocol >= 1) + { + fillInValue(os, 10, static_cast(os->b.size())); + if(requestId > 0) + { + fillInValue(os, headerSize, requestId); + } + else if(batchRequestNum > 0) + { + fillInValue(os, headerSize, batchRequestNum); + } + traceSend(*os, _logger, _traceLevels); + } + + InputStream is(os->instance(), os->getEncoding(), *os); + + if(batchRequestNum > 0) + { + is.pos(sizeof(requestBatchHdr)); + } + else + { + is.pos(sizeof(requestHdr)); + } + + int invokeNum = batchRequestNum > 0 ? batchRequestNum : 1; + ServantManagerPtr servantManager = _adapter->getServantManager(); + try + { + while(invokeNum > 0) + { + // + // Increase the direct count for the dispatch. We increase it again here for + // each dispatch. It's important for the direct count to be > 0 until the last + // collocated request response is sent to make sure the thread pool isn't + // destroyed before. + // + try + { + _adapter->incDirectCount(); + } + catch(const ObjectAdapterDeactivatedException& ex) + { + handleException(requestId, ex, false); + break; + } + + Incoming in(_reference->getInstance().get(), this, 0, _adapter, _response, 0, requestId); + in.invoke(servantManager, &is); + --invokeNum; + } + } + catch(const LocalException& ex) + { + invokeException(requestId, ex, invokeNum, false); // Fatal invocation exception + } + + _adapter->decDirectCount(); +} + +void +CollocatedRequestHandler::handleException(int requestId, const Exception& ex, bool amd) +{ + if(requestId == 0) + { + return; // Ignore exception for oneway messages. + } + + OutgoingAsyncBasePtr outAsync; + { + Lock sync(*this); + + map::iterator q = _asyncRequests.find(requestId); + if(q != _asyncRequests.end()) + { + if(q->second->exception(ex)) + { + outAsync = q->second; + } + _asyncRequests.erase(q); + } + } + + if(outAsync) + { + // + // If called from an AMD dispatch, invoke asynchronously + // the completion callback since this might be called from + // the user code. + // + if(amd) + { + outAsync->invokeExceptionAsync(); + } + else + { + outAsync->invokeException(); + } + } +} diff --git a/Sources/IceCpp/Communicator.cpp b/Sources/IceCpp/Communicator.cpp new file mode 100644 index 0000000..08f02a8 --- /dev/null +++ b/Sources/IceCpp/Communicator.cpp @@ -0,0 +1,79 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Communicator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::Communicator::~Communicator() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::Communicator::~Communicator() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Communicator* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/CommunicatorF.cpp b/Sources/IceCpp/CommunicatorF.cpp new file mode 100644 index 0000000..c0a8a7b --- /dev/null +++ b/Sources/IceCpp/CommunicatorF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `CommunicatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/CommunicatorI.cpp b/Sources/IceCpp/CommunicatorI.cpp new file mode 100644 index 0000000..b88bbe4 --- /dev/null +++ b/Sources/IceCpp/CommunicatorI.cpp @@ -0,0 +1,586 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ICE_SWIFT +# include +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(CommunicatorFlushBatchAsync* p) { return p; } +#endif + +CommunicatorFlushBatchAsync::~CommunicatorFlushBatchAsync() +{ + // Out of line to avoid weak vtable +} + +CommunicatorFlushBatchAsync::CommunicatorFlushBatchAsync(const InstancePtr& instance) : + OutgoingAsyncBase(instance) +{ + // + // _useCount is initialized to 1 to prevent premature callbacks. + // The caller must invoke ready() after all flush requests have + // been initiated. + // + _useCount = 1; +} + +void +CommunicatorFlushBatchAsync::flushConnection(const ConnectionIPtr& con, Ice::CompressBatch compressBatch) +{ + class FlushBatch : public OutgoingAsyncBase + { + public: + + FlushBatch(const CommunicatorFlushBatchAsyncPtr& outAsync, + const InstancePtr& instance, + InvocationObserver& observer) : + OutgoingAsyncBase(instance), _outAsync(outAsync), _parentObserver(observer) + { + } + + virtual bool + sent() + { + _childObserver.detach(); + _outAsync->check(false); + return false; + } + + virtual bool + exception(const Exception& ex) + { + _childObserver.failed(ex.ice_id()); + _childObserver.detach(); + _outAsync->check(false); + return false; + } + + virtual InvocationObserver& + getObserver() + { + return _parentObserver; + } + + virtual bool handleSent(bool, bool) + { + return false; + } + + virtual bool handleException(const Ice::Exception&) + { + return false; + } + + virtual bool handleResponse(bool) + { + return false; + } + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const + { + assert(false); + } + + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const + { + assert(false); + } + + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const + { + assert(false); + } + + private: + + const CommunicatorFlushBatchAsyncPtr _outAsync; + InvocationObserver& _parentObserver; + }; + + { + Lock sync(_m); + ++_useCount; + } + + try + { + OutgoingAsyncBasePtr flushBatch = ICE_MAKE_SHARED(FlushBatch, ICE_SHARED_FROM_THIS, _instance, _observer); + bool compress; + int batchRequestNum = con->getBatchRequestQueue()->swap(flushBatch->getOs(), compress); + if(batchRequestNum == 0) + { + flushBatch->sent(); + } + else + { + if(compressBatch == ICE_SCOPED_ENUM(CompressBatch, Yes)) + { + compress = true; + } + else if(compressBatch == ICE_SCOPED_ENUM(CompressBatch, No)) + { + compress = false; + } + con->sendAsyncRequest(flushBatch, compress, false, batchRequestNum); + } + } + catch(const LocalException&) + { + check(false); + throw; + } +} + +void +CommunicatorFlushBatchAsync::invoke(const string& operation, CompressBatch compressBatch) +{ + _observer.attach(_instance.get(), operation); + _instance->outgoingConnectionFactory()->flushAsyncBatchRequests(ICE_SHARED_FROM_THIS, compressBatch); + _instance->objectAdapterFactory()->flushAsyncBatchRequests(ICE_SHARED_FROM_THIS, compressBatch); + check(true); +} + +void +CommunicatorFlushBatchAsync::check(bool userThread) +{ + { + Lock sync(_m); + assert(_useCount > 0); + if(--_useCount > 0) + { + return; + } + } + + if(sentImpl(true)) + { + if(userThread) + { + _sentSynchronously = true; + invokeSent(); + } + else + { + invokeSentAsync(); + } + } +} + +void +Ice::CommunicatorI::destroy() ICE_NOEXCEPT +{ + if(_instance) + { + _instance->destroy(); + } +} + +void +Ice::CommunicatorI::shutdown() ICE_NOEXCEPT +{ + try + { + _instance->objectAdapterFactory()->shutdown(); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } +} + +void +Ice::CommunicatorI::waitForShutdown() ICE_NOEXCEPT +{ + try + { + _instance->objectAdapterFactory()->waitForShutdown(); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } +} + +bool +Ice::CommunicatorI::isShutdown() const ICE_NOEXCEPT +{ + try + { + return _instance->objectAdapterFactory()->isShutdown(); + } + catch(const Ice::CommunicatorDestroyedException&) + { + return true; + } +} + +ObjectPrxPtr +Ice::CommunicatorI::stringToProxy(const string& s) const +{ + return _instance->proxyFactory()->stringToProxy(s); +} + +string +Ice::CommunicatorI::proxyToString(const ObjectPrxPtr& proxy) const +{ + return _instance->proxyFactory()->proxyToString(proxy); +} + +ObjectPrxPtr +Ice::CommunicatorI::propertyToProxy(const string& p) const +{ + return _instance->proxyFactory()->propertyToProxy(p); +} + +PropertyDict +Ice::CommunicatorI::proxyToProperty(const ObjectPrxPtr& proxy, const string& property) const +{ + return _instance->proxyFactory()->proxyToProperty(proxy, property); +} + +Identity +Ice::CommunicatorI::stringToIdentity(const string& s) const +{ + return Ice::stringToIdentity(s); +} + +string +Ice::CommunicatorI::identityToString(const Identity& ident) const +{ + return Ice::identityToString(ident, _instance->toStringMode()); +} + +ObjectAdapterPtr +Ice::CommunicatorI::createObjectAdapter(const string& name) +{ + return _instance->objectAdapterFactory()->createObjectAdapter(name, ICE_NULLPTR); +} + +ObjectAdapterPtr +Ice::CommunicatorI::createObjectAdapterWithEndpoints(const string& name, const string& endpoints) +{ + string oaName = name; + if(oaName.empty()) + { + oaName = Ice::generateUUID(); + } + + getProperties()->setProperty(oaName + ".Endpoints", endpoints); + return _instance->objectAdapterFactory()->createObjectAdapter(oaName, ICE_NULLPTR); +} + +ObjectAdapterPtr +Ice::CommunicatorI::createObjectAdapterWithRouter(const string& name, const RouterPrxPtr& router) +{ + string oaName = name; + if(oaName.empty()) + { + oaName = Ice::generateUUID(); + } + + PropertyDict properties = proxyToProperty(router, oaName + ".Router"); + for(PropertyDict::const_iterator p = properties.begin(); p != properties.end(); ++p) + { + getProperties()->setProperty(p->first, p->second); + } + + return _instance->objectAdapterFactory()->createObjectAdapter(oaName, router); +} + +void +Ice::CommunicatorI::addObjectFactory(const ::Ice::ObjectFactoryPtr& factory, const string& id) +{ + _instance->addObjectFactory(factory, id); +} + +::Ice::ObjectFactoryPtr +Ice::CommunicatorI::findObjectFactory(const string& id) const ICE_NOEXCEPT +{ + return _instance->findObjectFactory(id); +} + +PropertiesPtr +Ice::CommunicatorI::getProperties() const ICE_NOEXCEPT +{ + return _instance->initializationData().properties; +} + +LoggerPtr +Ice::CommunicatorI::getLogger() const ICE_NOEXCEPT +{ + return _instance->initializationData().logger; +} + +Ice::Instrumentation::CommunicatorObserverPtr +Ice::CommunicatorI::getObserver() const ICE_NOEXCEPT +{ + return _instance->initializationData().observer; +} + +RouterPrxPtr +Ice::CommunicatorI::getDefaultRouter() const +{ + return _instance->referenceFactory()->getDefaultRouter(); +} + +void +Ice::CommunicatorI::setDefaultRouter(const RouterPrxPtr& router) +{ + _instance->setDefaultRouter(router); +} + +LocatorPrxPtr +Ice::CommunicatorI::getDefaultLocator() const +{ + return _instance->referenceFactory()->getDefaultLocator(); +} + +void +Ice::CommunicatorI::setDefaultLocator(const LocatorPrxPtr& locator) +{ + _instance->setDefaultLocator(locator); +} + +Ice::ImplicitContextPtr +Ice::CommunicatorI::getImplicitContext() const ICE_NOEXCEPT +{ + return _instance->getImplicitContext(); +} + +PluginManagerPtr +Ice::CommunicatorI::getPluginManager() const +{ + return _instance->pluginManager(); +} + +ValueFactoryManagerPtr +Ice::CommunicatorI::getValueFactoryManager() const ICE_NOEXCEPT +{ + return _instance->initializationData().valueFactoryManager; +} + +#ifdef ICE_SWIFT + +dispatch_queue_t +Ice::CommunicatorI::getClientDispatchQueue() const +{ + return _instance->clientThreadPool()->getDispatchQueue(); +} + +dispatch_queue_t +Ice::CommunicatorI::getServerDispatchQueue() const +{ + return _instance->serverThreadPool()->getDispatchQueue(); +} + +#endif + +namespace +{ + +const ::std::string flushBatchRequests_name = "flushBatchRequests"; + +} + +#ifdef ICE_CPP11_MAPPING + +::std::function +Ice::CommunicatorI::flushBatchRequestsAsync(CompressBatch compress, + function ex, + function sent) +{ + class CommunicatorFlushBatchLambda : public CommunicatorFlushBatchAsync, public LambdaInvoke + { + public: + + CommunicatorFlushBatchLambda(const InstancePtr& instance, + std::function ex, + std::function sent) : + CommunicatorFlushBatchAsync(instance), LambdaInvoke(std::move(ex), std::move(sent)) + { + } + }; + auto outAsync = make_shared(_instance, ex, sent); + outAsync->invoke(flushBatchRequests_name, compress); + return [outAsync]() { outAsync->cancel(); }; +} + +#else + +void +Ice::CommunicatorI::flushBatchRequests(CompressBatch compress) +{ + end_flushBatchRequests(begin_flushBatchRequests(compress)); +} + +AsyncResultPtr +Ice::CommunicatorI::begin_flushBatchRequests(CompressBatch compress) +{ + return _iceI_begin_flushBatchRequests(compress, ::IceInternal::dummyCallback, 0); +} + +AsyncResultPtr +Ice::CommunicatorI::begin_flushBatchRequests(CompressBatch compress, + const CallbackPtr& cb, + const LocalObjectPtr& cookie) +{ + return _iceI_begin_flushBatchRequests(compress, cb, cookie); +} + +AsyncResultPtr +Ice::CommunicatorI::begin_flushBatchRequests(CompressBatch compress, + const Callback_Communicator_flushBatchRequestsPtr& cb, + const LocalObjectPtr& cookie) +{ + return _iceI_begin_flushBatchRequests(compress, cb, cookie); +} + +AsyncResultPtr +Ice::CommunicatorI::_iceI_begin_flushBatchRequests(CompressBatch compress, + const IceInternal::CallbackBasePtr& cb, + const LocalObjectPtr& cookie) +{ + class CommunicatorFlushBatchAsyncWithCallback : public CommunicatorFlushBatchAsync, public CallbackCompletion + { + public: + + CommunicatorFlushBatchAsyncWithCallback(const Ice::CommunicatorPtr& communicator, + const InstancePtr& instance, + const CallbackBasePtr& callback, + const Ice::LocalObjectPtr& cookie) : + CommunicatorFlushBatchAsync(instance), CallbackCompletion(callback, cookie), _communicator(communicator) + { + _cookie = cookie; + } + + virtual Ice::CommunicatorPtr getCommunicator() const + { + return _communicator; + } + + virtual const std::string& + getOperation() const + { + return flushBatchRequests_name; + } + + private: + + Ice::CommunicatorPtr _communicator; + }; + + CommunicatorFlushBatchAsyncPtr result = new CommunicatorFlushBatchAsyncWithCallback(this, _instance, cb, cookie); + result->invoke(flushBatchRequests_name, compress); + return result; +} + +void +Ice::CommunicatorI::end_flushBatchRequests(const AsyncResultPtr& r) +{ + AsyncResult::_check(r, this, flushBatchRequests_name); + r->_waitForResponse(); +} +#endif + +ObjectPrxPtr +Ice::CommunicatorI::createAdmin(const ObjectAdapterPtr& adminAdapter, const Identity& adminId) +{ + return _instance->createAdmin(adminAdapter, adminId); +} +ObjectPrxPtr +Ice::CommunicatorI::getAdmin() const +{ + return _instance->getAdmin(); +} + +void +Ice::CommunicatorI::addAdminFacet(const Ice::ObjectPtr& servant, const string& facet) +{ + _instance->addAdminFacet(servant, facet); +} + +Ice::ObjectPtr +Ice::CommunicatorI::removeAdminFacet(const string& facet) +{ + return _instance->removeAdminFacet(facet); +} + +Ice::ObjectPtr +Ice::CommunicatorI::findAdminFacet(const string& facet) +{ + return _instance->findAdminFacet(facet); +} + +Ice::FacetMap +Ice::CommunicatorI::findAllAdminFacets() +{ + return _instance->findAllAdminFacets(); +} + +CommunicatorIPtr +Ice::CommunicatorI::create(const InitializationData& initData) +{ + Ice::CommunicatorIPtr communicator = ICE_MAKE_SHARED(CommunicatorI); + try + { + const_cast(communicator->_instance) = new Instance(communicator, initData); + + // + // Keep a reference to the dynamic library list to ensure + // the libraries are not unloaded until this Communicator's + // destructor is invoked. + // + const_cast(communicator->_dynamicLibraryList) = communicator->_instance->dynamicLibraryList(); + } + catch(...) + { + communicator->destroy(); + throw; + } + return communicator; +} + +Ice::CommunicatorI::~CommunicatorI() +{ + if(_instance && !_instance->destroyed()) + { + Warning out(_instance->initializationData().logger); + out << "Ice::Communicator::destroy() has not been called"; + } +} + +void +Ice::CommunicatorI::finishSetup(int& argc, const char* argv[]) +{ + try + { + _instance->finishSetup(argc, argv, ICE_SHARED_FROM_THIS); + } + catch(...) + { + destroy(); + throw; + } +} diff --git a/Sources/IceCpp/Cond.cpp b/Sources/IceCpp/Cond.cpp new file mode 100644 index 0000000..9f33e89 --- /dev/null +++ b/Sources/IceCpp/Cond.cpp @@ -0,0 +1,381 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#ifndef _WIN32 +# include +#endif + +#ifdef _WIN32 + +# ifdef ICE_HAS_WIN32_CONDVAR + +IceUtil::Cond::Cond() +{ + InitializeConditionVariable(&_cond); +} + +IceUtil::Cond::~Cond() +{ +} + +void +IceUtil::Cond::signal() +{ + WakeConditionVariable(&_cond); +} + +void +IceUtil::Cond::broadcast() +{ + WakeAllConditionVariable(&_cond); +} + +# else + +IceUtilInternal::Semaphore::Semaphore(long initial) +{ + _sem = CreateSemaphore(0, initial, 0x7fffffff, 0); + if(_sem == INVALID_HANDLE_VALUE) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +IceUtilInternal::Semaphore::~Semaphore() +{ + CloseHandle(_sem); +} + +void +IceUtilInternal::Semaphore::wait() const +{ + DWORD rc = WaitForSingleObject(_sem, INFINITE); + if(rc != WAIT_OBJECT_0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +bool +IceUtilInternal::Semaphore::timedWait(const IceUtil::Time& timeout) const +{ + IceUtil::Int64 msTimeout = timeout.toMilliSeconds(); + if(msTimeout < 0 || msTimeout > 0x7FFFFFFF) + { + throw IceUtil::InvalidTimeoutException(__FILE__, __LINE__, timeout); + } + + DWORD rc = WaitForSingleObject(_sem, static_cast(msTimeout)); + if(rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + return rc != WAIT_TIMEOUT; +} + +void +IceUtilInternal::Semaphore::post(int count) const +{ + int rc = ReleaseSemaphore(_sem, count, 0); + if(rc == 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +// +// The _queue semaphore is used to wait for the condition variable to +// be signaled. When signal is called any further thread signaling or +// threads waiting to wait (in preWait) are blocked from proceeding +// using an addition _gate semaphore) until the correct number of +// threads waiting on the _queue semaphore drain through postWait +// +// As each thread drains through postWait if there are further threads +// to unblock (toUnblock > 0) the _queue is posted again to wake a +// further waiting thread, otherwise the _gate is posted which permits +// any signaling or preWait threads to continue. Therefore, the _gate +// semaphore is used protect further entry into signal or wait until +// all signaled threads have woken. +// +// _blocked is the number of waiting threads. _unblocked is the +// number of threads which have unblocked. We use two variables +// because _blocked is protected by the _gate, whereas _unblocked is +// protected by the _internal mutex. There is an assumption here about +// memory visibility since postWait does not itself acquire the _gate +// semaphore (note that the _gate must be held if _state != StateIdle). +// +// Threads timing out present a particular issue because they may have +// woken without a corresponding notification and its easy to leave +// the _queue in a state where a spurious wakeup will occur -- +// consider a notify and a timed wake occuring at the same time. In +// this case, if we are not careful the _queue will have been posted, +// but the waking thread may not consume the semaphore. +// +IceUtil::Cond::Cond() : + _gate(1), + _blocked(0), + _unblocked(0), + _state(IceUtil::Cond::StateIdle) +{ +} + +IceUtil::Cond::~Cond() +{ +} + +void +IceUtil::Cond::signal() +{ + wake(false); +} + +void +IceUtil::Cond::broadcast() +{ + wake(true); +} + +void +IceUtil::Cond::wake(bool broadcast) +{ + // + // Lock gate. The gate will be locked if there are threads waiting + // to drain from postWait. + // + _gate.wait(); + + // + // Lock the internal mutex. + // + IceUtil::Mutex::Lock sync(_internal); + + // + // Adjust the count of the number of waiting/blocked threads. + // + if(_unblocked != 0) + { + _blocked -= _unblocked; + _unblocked = 0; + } + + // + // If there are waiting threads then we enter a signal or + // broadcast state. + // + if(_blocked > 0) + { + // + // Unblock some number of waiters. We use -1 for the signal + // case. + // + assert(_state == StateIdle); + _state = (broadcast) ? StateBroadcast : StateSignal; + // + // Posting the queue wakes a single waiting thread. After this + // occurs the waiting thread will wake and then either post on + // the _queue to wake the next waiting thread, or post on the + // gate to permit more signaling to proceed. + // + // Release before posting to avoid potential immediate + // context switch due to the mutex being locked. + // + sync.release(); + _queue.post(); + } + else + { + // + // Otherwise no blocked waiters, release the gate. + // + // Release before posting to avoid potential immediate + // context switch due to the mutex being locked. + // + sync.release(); + _gate.post(); + } +} + +void +IceUtil::Cond::preWait() const +{ + // + // _gate is used to protect _blocked. Furthermore, this prevents + // further threads from entering the wait state while a + // signal/broadcast is being processed. + // + _gate.wait(); + _blocked++; + _gate.post(); +} + +void +IceUtil::Cond::postWait(bool timedOutOrFailed) const +{ + IceUtil::Mutex::Lock sync(_internal); + + // + // One more thread has unblocked. + // + _unblocked++; + + // + // If _state is StateIdle then this must be a timeout, otherwise its a + // spurious wakeup which is incorrect. + // + if(_state == StateIdle) + { + assert(timedOutOrFailed); + return; + } + + if(timedOutOrFailed) + { + // + // If the thread was the last blocked thread and there's a + // pending signal/broadcast, reset the signal/broadcast to + // prevent spurious wakeup. + // + if(_blocked == _unblocked) + { + _state = StateIdle; + // + // Consume the queue post to prevent spurious wakeup. Note + // that although the internal mutex could be released + // prior to this wait() call, doing so gains nothing since + // this wait() MUST return immediately (if it does not + // there is a major bug and the entire application will + // deadlock). + // + _queue.wait(); + // + // Release before posting to avoid potential immediate + // context switch due to the mutex being locked. + // + sync.release(); + _gate.post(); + } + } + else + { + // + // At this point, the thread must have been woken up because + // of a signal/broadcast. + // + if(_state == StateSignal || _blocked == _unblocked) // Signal or no more blocked threads + { + _state = StateIdle; + // Release before posting to avoid potential immediate + // context switch due to the mutex being locked. + sync.release(); + _gate.post(); + } + else // Broadcast and more blocked threads to wake up. + { + // Release before posting to avoid potential immediate + // context switch due to the mutex being locked. + sync.release(); + _queue.post(); + } + } +} + +void +IceUtil::Cond::dowait() const +{ + try + { + _queue.wait(); + postWait(false); + } + catch(...) + { + postWait(true); + throw; + } +} + +bool +IceUtil::Cond::timedDowait(const Time& timeout) const +{ + try + { + bool rc = _queue.timedWait(timeout); + postWait(!rc); + return rc; + } + catch(...) + { + postWait(true); + throw; + } +} + +# endif // ICE_HAS_WIN32_CONDVAR + +#else + +IceUtil::Cond::Cond() +{ + pthread_condattr_t attr; + + int rc = pthread_condattr_init(&attr); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + +#if !defined(__hppa) && !defined(__APPLE__) + rc = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +#endif + + rc = pthread_cond_init(&_cond, &attr); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + rc = pthread_condattr_destroy(&attr); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +IceUtil::Cond::~Cond() +{ +#ifndef NDEBUG + int rc = pthread_cond_destroy(&_cond); + assert(rc == 0); +#else + pthread_cond_destroy(&_cond); +#endif +} + +void +IceUtil::Cond::signal() +{ + int rc = pthread_cond_signal(&_cond); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +void +IceUtil::Cond::broadcast() +{ + int rc = pthread_cond_broadcast(&_cond); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +#endif diff --git a/Sources/IceCpp/ConnectRequestHandler.cpp b/Sources/IceCpp/ConnectRequestHandler.cpp new file mode 100644 index 0000000..c50c474 --- /dev/null +++ b/Sources/IceCpp/ConnectRequestHandler.cpp @@ -0,0 +1,348 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(ConnectRequestHandler* p) { return p; } +#endif + +ConnectRequestHandler::ConnectRequestHandler(const ReferencePtr& ref, const Ice::ObjectPrxPtr& proxy) : + RequestHandler(ref), + _proxy(proxy), + _initialized(false), + _flushing(false) +{ +} + +RequestHandlerPtr +ConnectRequestHandler::connect(const Ice::ObjectPrxPtr& proxy) +{ + Lock sync(*this); + if(!initialized()) + { + _proxies.insert(proxy); + } + return _requestHandler ? _requestHandler : ICE_SHARED_FROM_THIS; +} + +RequestHandlerPtr +ConnectRequestHandler::update(const RequestHandlerPtr& previousHandler, const RequestHandlerPtr& newHandler) +{ + return previousHandler.get() == this ? newHandler : ICE_SHARED_FROM_THIS; +} + +AsyncStatus +ConnectRequestHandler::sendAsyncRequest(const ProxyOutgoingAsyncBasePtr& out) +{ + { + Lock sync(*this); + if(!_initialized) + { + out->cancelable(ICE_SHARED_FROM_THIS); // This will throw if the request is canceled + } + + if(!initialized()) + { + _requests.push_back(out); + return AsyncStatusQueued; + } + } + return out->invokeRemote(_connection, _compress, _response); +} + +void +ConnectRequestHandler::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, const Ice::LocalException& ex) +{ + { + Lock sync(*this); + if(_exception) + { + return; // The request has been notified of a failure already. + } + + if(!initialized()) + { + for(deque::iterator p = _requests.begin(); p != _requests.end(); ++p) + { + if(p->get() == outAsync.get()) + { + _requests.erase(p); + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + return; + } + } + } + } + _connection->asyncRequestCanceled(outAsync, ex); +} + +Ice::ConnectionIPtr +ConnectRequestHandler::getConnection() +{ + Lock sync(*this); + // + // First check for the connection, it's important otherwise the user could first get a connection + // and then the exception if he tries to obtain the proxy cached connection mutiple times (the + // exception can be set after the connection is set if the flush of pending requests fails). + // + if(_connection) + { + return _connection; + } + else if(_exception) + { + _exception->ice_throw(); + } + return ICE_NULLPTR; +} + +Ice::ConnectionIPtr +ConnectRequestHandler::waitForConnection() +{ + Lock sync(*this); + if(_exception) + { + throw RetryException(*_exception); + } + // + // Wait for the connection establishment to complete or fail. + // + while(!_initialized && !_exception) + { + wait(); + } + + if(_exception) + { + _exception->ice_throw(); + return 0; // Keep the compiler happy. + } + else + { + return _connection; + } +} + +void +ConnectRequestHandler::setConnection(const Ice::ConnectionIPtr& connection, bool compress) +{ + { + Lock sync(*this); + assert(!_flushing && !_exception && !_connection); + _connection = connection; + _compress = compress; + } + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + RouterInfoPtr ri = _reference->getRouterInfo(); + if(ri && !ri->addProxy(_proxy, ICE_SHARED_FROM_THIS)) + { + return; // The request handler will be initialized once addProxy returns. + } + + // + // We can now send the queued requests. + // + flushRequests(); +} + +void +ConnectRequestHandler::setException(const Ice::LocalException& ex) +{ + { + Lock sync(*this); + assert(!_flushing && !_initialized && !_exception); + _flushing = true; // Ensures request handler is removed before processing new requests. + ICE_SET_EXCEPTION_FROM_CLONE(_exception, ex.ice_clone()); + } + + // + // NOTE: remove the request handler *before* notifying the requests that the connection + // failed. It's important to ensure that future invocations will obtain a new connect + // request handler once invocations are notified. + // + try + { + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, ICE_SHARED_FROM_THIS); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } + + for(deque::const_iterator p = _requests.begin(); p != _requests.end(); ++p) + { + if((*p)->exception(ex)) + { + (*p)->invokeExceptionAsync(); + } + } + _requests.clear(); + + { + Lock sync(*this); + _flushing = false; + _proxies.clear(); + _proxy = 0; // Break cyclic reference count. + notifyAll(); + } +} + +void +ConnectRequestHandler::addedProxy() +{ + // + // The proxy was added to the router info, we're now ready to send the + // queued requests. + // + flushRequests(); +} + +bool +ConnectRequestHandler::initialized() +{ + // Must be called with the mutex locked. + + if(_initialized) + { + assert(_connection); + return true; + } + else + { + while(_flushing) + { + wait(); + } + + if(_exception) + { + if(_connection) + { + // + // Only throw if the connection didn't get established. If + // it died after being established, we allow the caller to + // retry the connection establishment by not throwing here + // (the connection will throw RetryException). + // + return true; + } + _exception->ice_throw(); + return false; // Keep the compiler happy. + } + else + { + return _initialized; + } + } +} + +void +ConnectRequestHandler::flushRequests() +{ + { + Lock sync(*this); + assert(_connection && !_initialized); + + // + // We set the _flushing flag to true to prevent any additional queuing. Callers + // might block for a little while as the queued requests are being sent but this + // shouldn't be an issue as the request sends are non-blocking. + // + _flushing = true; + } + +#ifdef ICE_CPP11_MAPPING + std::unique_ptr exception; +#else + IceInternal::UniquePtr exception; +#endif + while(!_requests.empty()) // _requests is immutable when _flushing = true + { + ProxyOutgoingAsyncBasePtr& req = _requests.front(); + try + { + if(req->invokeRemote(_connection, _compress, _response) & AsyncStatusInvokeSentCallback) + { + req->invokeSentAsync(); + } + } + catch(const RetryException& ex) + { + ICE_SET_EXCEPTION_FROM_CLONE(exception, ex.get()->ice_clone()); + + // Remove the request handler before retrying. + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, ICE_SHARED_FROM_THIS); + + req->retryException(*exception); + } + catch(const Ice::LocalException& ex) + { + ICE_SET_EXCEPTION_FROM_CLONE(exception, ex.ice_clone()); + + if(req->exception(ex)) + { + req->invokeExceptionAsync(); + } + } + _requests.pop_front(); + } + + // + // If we aren't caching the connection, don't bother creating a + // connection request handler. Otherwise, update the proxies + // request handler to use the more efficient connection request + // handler. + // + if(_reference->getCacheConnection() && !exception) + { + _requestHandler = ICE_MAKE_SHARED(ConnectionRequestHandler, _reference, _connection, _compress); + for(set::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + { + (*p)->_updateRequestHandler(ICE_SHARED_FROM_THIS, _requestHandler); + } + } + + { + Lock sync(*this); + assert(!_initialized); +#ifdef ICE_CPP11_MAPPING + swap(_exception, exception); +#else + _exception.swap(exception); +#endif + _initialized = !_exception; + _flushing = false; + + // + // Only remove once all the requests are flushed to + // guarantee serialization. + // + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, ICE_SHARED_FROM_THIS); + + _proxies.clear(); + _proxy = ICE_NULLPTR; // Break cyclic reference count. + notifyAll(); + } +} diff --git a/Sources/IceCpp/Connection.cpp b/Sources/IceCpp/Connection.cpp new file mode 100644 index 0000000..c4900ce --- /dev/null +++ b/Sources/IceCpp/Connection.cpp @@ -0,0 +1,155 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Connection.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ConnectionInfo::~ConnectionInfo() +{ +} + +Ice::Connection::~Connection() +{ +} + +Ice::IPConnectionInfo::~IPConnectionInfo() +{ +} + +Ice::TCPConnectionInfo::~TCPConnectionInfo() +{ +} + +Ice::UDPConnectionInfo::~UDPConnectionInfo() +{ +} + +Ice::WSConnectionInfo::~WSConnectionInfo() +{ +} + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ConnectionInfo::~ConnectionInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ConnectionInfo* p) { return p; } +/// \endcond + +Ice::CloseCallback::~CloseCallback() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(CloseCallback* p) { return p; } +/// \endcond + +Ice::HeartbeatCallback::~HeartbeatCallback() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(HeartbeatCallback* p) { return p; } +/// \endcond + +Ice::Connection::~Connection() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Connection* p) { return p; } +/// \endcond + +Ice::IPConnectionInfo::~IPConnectionInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(IPConnectionInfo* p) { return p; } +/// \endcond + +Ice::TCPConnectionInfo::~TCPConnectionInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(TCPConnectionInfo* p) { return p; } +/// \endcond + +Ice::UDPConnectionInfo::~UDPConnectionInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(UDPConnectionInfo* p) { return p; } +/// \endcond + +Ice::WSConnectionInfo::~WSConnectionInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(WSConnectionInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ConnectionF.cpp b/Sources/IceCpp/ConnectionF.cpp new file mode 100644 index 0000000..2c72531 --- /dev/null +++ b/Sources/IceCpp/ConnectionF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ConnectionFactory.cpp b/Sources/IceCpp/ConnectionFactory.cpp new file mode 100644 index 0000000..0764ff6 --- /dev/null +++ b/Sources/IceCpp/ConnectionFactory.cpp @@ -0,0 +1,1972 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // For getThreadPool(). +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if TARGET_OS_IPHONE != 0 +namespace IceInternal +{ + +bool registerForBackgroundNotification(const IceInternal::IncomingConnectionFactoryPtr&); +void unregisterForBackgroundNotification(const IceInternal::IncomingConnectionFactoryPtr&); + +} +#endif + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(OutgoingConnectionFactory* p) { return p; } + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(IncomingConnectionFactory* p) { return p; } +#endif + +namespace +{ + +#ifdef ICE_CPP11_COMPILER +template void +remove(Map& m, const typename Map::key_type& k, const typename Map::mapped_type& v) +{ + auto pr = m.equal_range(k); + assert(pr.first != pr.second); + for(auto q = pr.first; q != pr.second; ++q) + { + if(q->second.get() == v.get()) + { + m.erase(q); + return; + } + } + assert(false); // Nothing was removed which is an error. +} + +template typename Map::mapped_type +find(const Map& m, const typename Map::key_type& k, Predicate predicate) +{ + auto pr = m.equal_range(k); + for(auto q = pr.first; q != pr.second; ++q) + { + if(predicate(q->second)) + { + return q->second; + } + } + return nullptr; +} + +#else +template void +remove(multimap& m, K k, V v) +{ + pair::iterator, typename multimap::iterator> pr = m.equal_range(k); + assert(pr.first != pr.second); + for(typename multimap::iterator q = pr.first; q != pr.second; ++q) + { + if(q->second.get() == v.get()) + { + m.erase(q); + return; + } + } + assert(false); // Nothing was removed which is an error. +} + +template ::IceInternal::Handle +find(const multimap >& m, + K k, + const ::IceUtilInternal::ConstMemFun >& predicate) +{ + pair >::const_iterator, + typename multimap >::const_iterator> pr = m.equal_range(k); + for(typename multimap >::const_iterator q = pr.first; q != pr.second; ++q) + { + if(predicate(q->second)) + { + return q->second; + } + } + return IceInternal::Handle(); +} +#endif + +class StartAcceptor : public IceUtil::TimerTask +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + StartAcceptor(const IncomingConnectionFactoryPtr& factory, const InstancePtr& instance) : + _factory(factory), _instance(instance) + { + } + + void + runTimerTask() + { + try + { + _factory->startAcceptor(); + } + catch(const Ice::Exception& ex) + { + Error out(_instance->initializationData().logger); + out << "acceptor creation failed:\n" << ex << '\n' << _factory->toString(); + _instance->timer()->schedule(ICE_SHARED_FROM_THIS, IceUtil::Time::seconds(1)); + } + } + +private: + + IncomingConnectionFactoryPtr _factory; + InstancePtr _instance; +}; + +#if TARGET_OS_IPHONE != 0 +class FinishCall : public DispatchWorkItem +{ +public: + + FinishCall(const IncomingConnectionFactoryPtr& factory) : _factory(factory) + { + } + + virtual void + run() + { + _factory->finish(); + } + +private: + + const IncomingConnectionFactoryPtr _factory; +}; +#endif + +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectorInfo::operator==(const ConnectorInfo& other) const +{ + return connector == other.connector; +} + +void +IceInternal::OutgoingConnectionFactory::destroy() +{ + IceUtil::Monitor::Lock sync(*this); + + if(_destroyed) + { + return; + } + +#ifdef ICE_CPP11_COMPILER + for(const auto& p : _connections) + { + p.second->destroy(ConnectionI::CommunicatorDestroyed); + } +#else + for_each(_connections.begin(), _connections.end(), + bind2nd(Ice::secondVoidMemFun1 + (&ConnectionI::destroy), ConnectionI::CommunicatorDestroyed)); +#endif + _destroyed = true; + _communicator = 0; + + notifyAll(); +} + +void +IceInternal::OutgoingConnectionFactory::updateConnectionObservers() +{ + IceUtil::Monitor::Lock sync(*this); +#ifdef ICE_CPP11_COMPILER + for(const auto& p : _connections) + { + p.second->updateObserver(); + } +#else + for_each(_connections.begin(), _connections.end(), + Ice::secondVoidMemFun(&ConnectionI::updateObserver)); +#endif +} + +void +IceInternal::OutgoingConnectionFactory::waitUntilFinished() +{ + multimap connections; + + { + IceUtil::Monitor::Lock sync(*this); + + // + // First we wait until the factory is destroyed. We also wait + // until there are no pending connections anymore. Only then + // we can be sure the _connections contains all connections. + // + while(!_destroyed || !_pending.empty() || _pendingConnectCount > 0) + { + wait(); + } + + // + // We want to wait until all connections are finished outside the + // thread synchronization. + // + connections = _connections; + } + +#ifdef ICE_CPP11_COMPILER + for(const auto& p : _connections) + { + p.second->waitUntilFinished(); + } +#else + for_each(connections.begin(), connections.end(), + Ice::secondVoidMemFun(&ConnectionI::waitUntilFinished)); +#endif + { + IceUtil::Monitor::Lock sync(*this); + // Ensure all the connections are finished and reapable at this point. + vector cons; + _monitor->swapReapedConnections(cons); + assert(cons.size() == _connections.size()); + cons.clear(); + _connections.clear(); + _connectionsByEndpoint.clear(); + } + + // + // Must be destroyed outside the synchronization since this might block waiting for + // a timer task to complete. + // + _monitor->destroy(); +} + +void +IceInternal::OutgoingConnectionFactory::create(const vector& endpts, + bool hasMore, + Ice::EndpointSelectionType selType, + const CreateConnectionCallbackPtr& callback) +{ + assert(!endpts.empty()); + + // + // Apply the overrides. + // + vector endpoints = applyOverrides(endpts); + + // + // Try to find a connection to one of the given endpoints. + // + try + { + bool compress; + Ice::ConnectionIPtr connection = findConnection(endpoints, compress); + if(connection) + { + callback->setConnection(connection, compress); + return; + } + } + catch(const Ice::LocalException& ex) + { + callback->setException(ex); + return; + } + +#ifdef ICE_CPP11_MAPPING + auto cb = make_shared(_instance, this, endpoints, hasMore, callback, selType); +#else + ConnectCallbackPtr cb = new ConnectCallback(_instance, this, endpoints, hasMore, callback, selType); +#endif + cb->getConnectors(); +} + +void +IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& routerInfo) +{ + assert(routerInfo); + ObjectAdapterPtr adapter = routerInfo->getAdapter(); + vector endpoints = routerInfo->getClientEndpoints(); // Must be called outside the synchronization + + IceUtil::Monitor::Lock sync(*this); + + if(_destroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + // + // Search for connections to the router's client proxy endpoints, + // and update the object adapter for such connections, so that + // callbacks from the router can be received over such + // connections. + // + for(vector::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + EndpointIPtr endpoint = *p; + + // + // Modify endpoints with overrides. + // + if(_instance->defaultsAndOverrides()->overrideTimeout) + { + endpoint = endpoint->timeout(_instance->defaultsAndOverrides()->overrideTimeoutValue); + } + + // + // The Connection object does not take the compression flag of + // endpoints into account, but instead gets the information + // about whether messages should be compressed or not from + // other sources. In order to allow connection sharing for + // endpoints that differ in the value of the compression flag + // only, we always set the compression flag to false here in + // this connection factory. + // + endpoint = endpoint->compress(false); + + for(multimap::const_iterator q = _connections.begin(); + q != _connections.end(); ++q) + { + if(q->second->endpoint() == endpoint) + { + q->second->setAdapter(adapter); + } + } + } +} + +void +IceInternal::OutgoingConnectionFactory::removeAdapter(const ObjectAdapterPtr& adapter) +{ + IceUtil::Monitor::Lock sync(*this); + + if(_destroyed) + { + return; + } + + for(multimap::const_iterator p = _connections.begin(); p != _connections.end(); ++p) + { + if(p->second->getAdapter() == adapter) + { + p->second->setAdapter(0); + } + } +} + +void +IceInternal::OutgoingConnectionFactory::flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr& outAsync, + Ice::CompressBatch compress) +{ + list c; + + { + IceUtil::Monitor::Lock sync(*this); + for(multimap::const_iterator p = _connections.begin(); p != _connections.end(); + ++p) + { + if(p->second->isActiveOrHolding()) + { + c.push_back(p->second); + } + } + } + + for(list::const_iterator p = c.begin(); p != c.end(); ++p) + { + try + { + outAsync->flushConnection(*p, compress); + } + catch(const LocalException&) + { + // Ignore. + } + } +} + +IceInternal::OutgoingConnectionFactory::OutgoingConnectionFactory(const CommunicatorPtr& communicator, + const InstancePtr& instance) : + _communicator(communicator), + _instance(instance), + _monitor(new FactoryACMMonitor(instance, instance->clientACM())), + _destroyed(false), + _pendingConnectCount(0) +{ +} + +IceInternal::OutgoingConnectionFactory::~OutgoingConnectionFactory() +{ + assert(_destroyed); + assert(_connections.empty()); + assert(_connectionsByEndpoint.empty()); + assert(_pending.empty()); + assert(_pendingConnectCount == 0); +} + +vector +IceInternal::OutgoingConnectionFactory::applyOverrides(const vector& endpts) +{ + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + vector endpoints = endpts; + for(vector::iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + // + // Modify endpoints with overrides. + // + if(defaultsAndOverrides->overrideTimeout) + { + *p = (*p)->timeout(defaultsAndOverrides->overrideTimeoutValue); + } + } + return endpoints; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::findConnection(const vector& endpoints, bool& compress) +{ + IceUtil::Monitor::Lock sync(*this); + if(_destroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + assert(!endpoints.empty()); + for(vector::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { +#ifdef ICE_CPP11_COMPILER + auto connection = find(_connectionsByEndpoint, *p, + [](const ConnectionIPtr& conn) + { + return conn->isActiveOrHolding(); + }); +#else + ConnectionIPtr connection = find(_connectionsByEndpoint, *p, Ice::constMemFun(&ConnectionI::isActiveOrHolding)); +#endif + if(connection) + { + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = (*p)->compress(); + } + return connection; + } + } + return 0; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::findConnection(const vector& connectors, bool& compress) +{ + // This must be called with the mutex locked. + + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + if(_pending.find(p->connector) != _pending.end()) + { + continue; + } + +#ifdef ICE_CPP11_COMPILER + auto connection = find(_connections, p->connector, + [](const ConnectionIPtr& conn) + { + return conn->isActiveOrHolding(); + }); +#else + ConnectionIPtr connection = find(_connections, p->connector, Ice::constMemFun(&ConnectionI::isActiveOrHolding)); +#endif + if(connection) + { + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = p->endpoint->compress(); + } + return connection; + } + } + + return 0; +} + +void +IceInternal::OutgoingConnectionFactory::incPendingConnectCount() +{ + // + // Keep track of the number of pending connects. The outgoing connection factory + // waitUntilFinished() method waits for all the pending connects to terminate before + // to return. This ensures that the communicator client thread pool isn't destroyed + // too soon and will still be available to execute the ice_exception() callbacks for + // the asynchronous requests waiting on a connection to be established. + // + + IceUtil::Monitor::Lock sync(*this); + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + ++_pendingConnectCount; +} + +void +IceInternal::OutgoingConnectionFactory::decPendingConnectCount() +{ + IceUtil::Monitor::Lock sync(*this); + --_pendingConnectCount; + assert(_pendingConnectCount >= 0); + if(_destroyed && _pendingConnectCount == 0) + { + notifyAll(); + } +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::getConnection(const vector& connectors, + const ConnectCallbackPtr& cb, + bool& compress) +{ + { + IceUtil::Monitor::Lock sync(*this); + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + // + // Reap closed connections + // + vector cons; + _monitor->swapReapedConnections(cons); + for(vector::const_iterator p = cons.begin(); p != cons.end(); ++p) + { + remove(_connections, (*p)->connector(), *p); + remove(_connectionsByEndpoint, (*p)->endpoint(), *p); + remove(_connectionsByEndpoint, (*p)->endpoint()->compress(true), *p); + } + + // + // Try to get the connection. We may need to wait for other threads to + // finish if one of them is currently establishing a connection to one + // of our connectors. + // + while(true) + { + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + // + // Search for a matching connection. If we find one, we're done. + // + Ice::ConnectionIPtr connection = findConnection(connectors, compress); + if(connection) + { + return connection; + } + + // + // Determine whether another thread/request is currently attempting to connect to + // one of our endpoints; if so we wait until it's done. + // + if(addToPending(cb, connectors)) + { + // + // If a callback is not specified we wait until another thread notifies us about a + // change to the pending list. Otherwise, if a callback is provided we're done: + // when the pending list changes the callback will be notified and will try to + // get the connection again. + // + if(!cb) + { + wait(); + } + else + { + return 0; + } + } + else + { + // + // If no thread is currently establishing a connection to one of our connectors, + // we get out of this loop and start the connection establishment to one of the + // given connectors. + // + break; + } + } + } + + // + // At this point, we're responsible for establishing the connection to one of + // the given connectors. If it's a non-blocking connect, calling nextConnector + // will start the connection establishment. Otherwise, we return null to get + // the caller to establish the connection. + // + if(cb) + { + cb->nextConnector(); + } + + return 0; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::createConnection(const TransceiverPtr& transceiver, const ConnectorInfo& ci) +{ + IceUtil::Monitor::Lock sync(*this); + assert(_pending.find(ci.connector) != _pending.end() && transceiver); + + // + // Create and add the connection to the connection map. Adding the connection to the map + // is necessary to support the interruption of the connection initialization and validation + // in case the communicator is destroyed. + // + Ice::ConnectionIPtr connection; + try + { + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + connection = ConnectionI::create(_communicator, _instance, _monitor, transceiver, ci.connector, + ci.endpoint->compress(false), ICE_NULLPTR); + } + catch(const Ice::LocalException&) + { + try + { + transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Ignore + } + throw; + } + + _connections.insert(pair(ci.connector, connection)); + _connectionsByEndpoint.insert(pair(connection->endpoint(), connection)); + _connectionsByEndpoint.insert(pair(connection->endpoint()->compress(true), + connection)); + return connection; +} + +void +IceInternal::OutgoingConnectionFactory::finishGetConnection(const vector& connectors, + const ConnectorInfo& ci, + const ConnectionIPtr& connection, + const ConnectCallbackPtr& cb) +{ + set connectionCallbacks; + if(cb) + { + connectionCallbacks.insert(cb); + } + + set callbacks; + { + IceUtil::Monitor::Lock sync(*this); + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map >::iterator q = _pending.find(p->connector); + if(q != _pending.end()) + { + for(set::const_iterator r = q->second.begin(); r != q->second.end(); ++r) + { + if((*r)->hasConnector(ci)) + { + connectionCallbacks.insert(*r); + } + else + { + callbacks.insert(*r); + } + } + _pending.erase(q); + } + } + + for(set::iterator r = connectionCallbacks.begin(); r != connectionCallbacks.end(); ++r) + { + (*r)->removeFromPending(); + callbacks.erase(*r); + } + for(set::iterator r = callbacks.begin(); r != callbacks.end(); ++r) + { + (*r)->removeFromPending(); + } + notifyAll(); + } + + bool compress; + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = ci.endpoint->compress(); + } + + for(set::const_iterator p = callbacks.begin(); p != callbacks.end(); ++p) + { + (*p)->getConnection(); + } + for(set::const_iterator p = connectionCallbacks.begin(); p != connectionCallbacks.end(); ++p) + { + (*p)->setConnection(connection, compress); + } +} + +void +IceInternal::OutgoingConnectionFactory::finishGetConnection(const vector& connectors, + const Ice::LocalException& ex, + const ConnectCallbackPtr& cb) +{ + set failedCallbacks; + if(cb) + { + failedCallbacks.insert(cb); + } + + set callbacks; + { + IceUtil::Monitor::Lock sync(*this); + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map >::iterator q = _pending.find(p->connector); + if(q != _pending.end()) + { + for(set::const_iterator r = q->second.begin(); r != q->second.end(); ++r) + { + if((*r)->removeConnectors(connectors)) + { + failedCallbacks.insert(*r); + } + else + { + callbacks.insert(*r); + } + } + _pending.erase(q); + } + } + + for(set::iterator r = callbacks.begin(); r != callbacks.end(); ++r) + { + assert(failedCallbacks.find(*r) == failedCallbacks.end()); + (*r)->removeFromPending(); + } + notifyAll(); + } + + for(set::const_iterator p = callbacks.begin(); p != callbacks.end(); ++p) + { + (*p)->getConnection(); + } + for(set::const_iterator p = failedCallbacks.begin(); p != failedCallbacks.end(); ++p) + { + (*p)->setException(ex); + } +} + +bool +IceInternal::OutgoingConnectionFactory::addToPending(const ConnectCallbackPtr& cb, + const vector& connectors) +{ + // + // Add the callback to each connector pending list. + // + bool found = false; + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map >::iterator q = _pending.find(p->connector); + if(q != _pending.end()) + { + found = true; + if(cb) + { + q->second.insert(cb); + } + } + } + + if(found) + { + return true; + } + + // + // If there's no pending connection for the given connectors, we're + // responsible for its establishment. We add empty pending lists, + // other callbacks to the same connectors will be queued. + // + for(vector::const_iterator r = connectors.begin(); r != connectors.end(); ++r) + { + if(_pending.find(r->connector) == _pending.end()) + { + _pending.insert(pair >(r->connector, set())); + } + } + return false; +} + +void +IceInternal::OutgoingConnectionFactory::removeFromPending(const ConnectCallbackPtr& cb, + const vector& connectors) +{ + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map >::iterator q = _pending.find(p->connector); + if(q != _pending.end()) + { + q->second.erase(cb); + } + } +} + +void +IceInternal::OutgoingConnectionFactory::handleException(const LocalException& ex, bool hasMore) +{ + TraceLevelsPtr traceLevels = _instance->traceLevels(); + if(traceLevels->network >= 2) + { + Trace out(_instance->initializationData().logger, traceLevels->networkCat); + + out << "couldn't resolve endpoint host"; + if(dynamic_cast(&ex)) + { + out << "\n"; + } + else + { + if(hasMore) + { + out << ", trying next endpoint\n"; + } + else + { + out << " and no more endpoints to try\n"; + } + } + out << ex; + } +} + +void +IceInternal::OutgoingConnectionFactory::handleConnectionException(const LocalException& ex, bool hasMore) +{ + TraceLevelsPtr traceLevels = _instance->traceLevels(); + if(traceLevels->network >= 2) + { + Trace out(_instance->initializationData().logger, traceLevels->networkCat); + + out << "connection to endpoint failed"; + if(dynamic_cast(&ex)) + { + out << "\n"; + } + else + { + if(hasMore) + { + out << ", trying next endpoint\n"; + } + else + { + out << " and no more endpoints to try\n"; + } + } + out << ex; + } +} + +IceInternal::OutgoingConnectionFactory::ConnectCallback::ConnectCallback(const InstancePtr& instance, + const OutgoingConnectionFactoryPtr& factory, + const vector& endpoints, + bool hasMore, + const CreateConnectionCallbackPtr& cb, + Ice::EndpointSelectionType selType) : + _instance(instance), + _factory(factory), + _endpoints(endpoints), + _hasMore(hasMore), + _callback(cb), + _selType(selType) +{ + _endpointsIter = _endpoints.begin(); +} + +// +// Methods from ConnectionI.StartCallback +// +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectionStartCompleted(const ConnectionIPtr& connection) +{ + if(_observer) + { + _observer->detach(); + } + + connection->activate(); + _factory->finishGetConnection(_connectors, *_iter, connection, ICE_SHARED_FROM_THIS); +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectionStartFailed(const ConnectionIPtr& /*connection*/, + const LocalException& ex) +{ + assert(_iter != _connectors.end()); + if(connectionStartFailedImpl(ex)) + { + nextConnector(); + } +} + +// +// Methods from EndpointI_connectors +// +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectors(const vector& connectors) +{ + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + _connectors.push_back(ConnectorInfo(*p, *_endpointsIter)); + } + + if(++_endpointsIter != _endpoints.end()) + { + nextEndpoint(); + } + else + { + assert(!_connectors.empty()); + + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.begin(); + getConnection(); + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::exception(const Ice::LocalException& ex) +{ + _factory->handleException(ex, _hasMore || _endpointsIter != _endpoints.end() - 1); + if(++_endpointsIter != _endpoints.end()) + { + nextEndpoint(); + } + else if(!_connectors.empty()) + { + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.begin(); + getConnection(); + } + else + { + _callback->setException(ex); + _factory->decPendingConnectCount(); // Must be called last. + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::getConnectors() +{ + try + { + // + // Notify the factory that there's an async connect pending. This is necessary + // to prevent the outgoing connection factory to be destroyed before all the + // pending asynchronous connects are finished. + // + _factory->incPendingConnectCount(); + } + catch(const Ice::LocalException& ex) + { + _callback->setException(ex); + return; + } + + nextEndpoint(); +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::nextEndpoint() +{ + try + { + assert(_endpointsIter != _endpoints.end()); + (*_endpointsIter)->connectors_async(_selType, ICE_SHARED_FROM_THIS); + + } + catch(const Ice::LocalException& ex) + { + exception(ex); + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::getConnection() +{ + try + { + // + // If all the connectors have been created, we ask the factory to get a + // connection. + // + bool compress; + Ice::ConnectionIPtr connection = _factory->getConnection(_connectors, ICE_SHARED_FROM_THIS, compress); + if(!connection) + { + // + // A null return value from getConnection indicates that the connection + // is being established and that everthing has been done to ensure that + // the callback will be notified when the connection establishment is + // done or that the callback already obtain the connection. + // + return; + } + + _callback->setConnection(connection, compress); + _factory->decPendingConnectCount(); // Must be called last. + } + catch(const Ice::LocalException& ex) + { + _callback->setException(ex); + _factory->decPendingConnectCount(); // Must be called last. + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::nextConnector() +{ + while(true) + { + try + { + const CommunicatorObserverPtr& obsv = _factory->_instance->initializationData().observer; + if(obsv) + { + _observer = obsv->getConnectionEstablishmentObserver(_iter->endpoint, _iter->connector->toString()); + if(_observer) + { + _observer->attach(); + } + } + + assert(_iter != _connectors.end()); + + if(_instance->traceLevels()->network >= 2) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "trying to establish " << _iter->endpoint->protocol() << " connection to " + << _iter->connector->toString(); + } + Ice::ConnectionIPtr connection = _factory->createConnection(_iter->connector->connect(), *_iter); + connection->start(ICE_SHARED_FROM_THIS); + } + catch(const Ice::LocalException& ex) + { + if(_instance->traceLevels()->network >= 2) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "failed to establish " << _iter->endpoint->protocol() << " connection to " + << _iter->connector->toString() << "\n" << ex; + } + + if(connectionStartFailedImpl(ex)) + { + continue; // More connectors to try, continue. + } + } + break; + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::setConnection(const Ice::ConnectionIPtr& connection, + bool compress) +{ + // + // Callback from the factory: the connection to one of the callback + // connectors has been established. + // + _callback->setConnection(connection, compress); + _factory->decPendingConnectCount(); // Must be called last. +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::setException(const Ice::LocalException& ex) +{ + // + // Callback from the factory: connection establishment failed. + // + _callback->setException(ex); + _factory->decPendingConnectCount(); // Must be called last. +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectCallback::hasConnector(const ConnectorInfo& ci) +{ + return find(_connectors.begin(), _connectors.end(), ci) != _connectors.end(); +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectCallback::removeConnectors(const vector& connectors) +{ + // + // Callback from the factory: connecting to the given connectors + // failed, we remove the connectors and return true if there's + // no more connectors left to try. + // + for(vector::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + _connectors.erase(remove(_connectors.begin(), _connectors.end(), *p), _connectors.end()); + } + return _connectors.empty(); +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::removeFromPending() +{ + _factory->removeFromPending(ICE_SHARED_FROM_THIS, _connectors); +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectCallback::operator<(const ConnectCallback& rhs) const +{ + return this < &rhs; +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectionStartFailedImpl(const Ice::LocalException& ex) +{ + if(_observer) + { + _observer->failed(ex.ice_id()); + _observer->detach(); + } + + _factory->handleConnectionException(ex, _hasMore || _iter != _connectors.end() - 1); + if(dynamic_cast(&ex)) // No need to continue. + { + _factory->finishGetConnection(_connectors, ex, ICE_SHARED_FROM_THIS); + } + else if(++_iter != _connectors.end()) // Try the next connector. + { + return true; + } + else + { + _factory->finishGetConnection(_connectors, ex, ICE_SHARED_FROM_THIS); + } + return false; +} + +void +IceInternal::IncomingConnectionFactory::activate() +{ + IceUtil::Monitor::Lock sync(*this); + setState(StateActive); +} + +void +IceInternal::IncomingConnectionFactory::hold() +{ + IceUtil::Monitor::Lock sync(*this); + setState(StateHolding); +} + +void +IceInternal::IncomingConnectionFactory::destroy() +{ + IceUtil::Monitor::Lock sync(*this); + setState(StateClosed); +} + +void +IceInternal::IncomingConnectionFactory::updateConnectionObservers() +{ + IceUtil::Monitor::Lock sync(*this); +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : _connections) + { + conn->updateObserver(); + } +#else + for_each(_connections.begin(), _connections.end(), Ice::voidMemFun(&ConnectionI::updateObserver)); +#endif +} + +void +IceInternal::IncomingConnectionFactory::waitUntilHolding() const +{ + set connections; + + { + IceUtil::Monitor::Lock sync(*this); + + // + // First we wait until the connection factory itself is in holding + // state. + // + while(_state < StateHolding) + { + wait(); + } + + // + // We want to wait until all connections are in holding state + // outside the thread synchronization. + // + connections = _connections; + } + + // + // Now we wait until each connection is in holding state. + // +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : connections) + { + conn->waitUntilHolding(); + } +#else + for_each(connections.begin(), connections.end(), Ice::constVoidMemFun(&ConnectionI::waitUntilHolding)); +#endif +} + +void +IceInternal::IncomingConnectionFactory::waitUntilFinished() +{ + set connections; + { + IceUtil::Monitor::Lock sync(*this); + + // + // First we wait until the factory is destroyed. If we are using + // an acceptor, we also wait for it to be closed. + // + while(_state != StateFinished) + { + wait(); + } + + // + // Clear the OA. See bug 1673 for the details of why this is necessary. + // + _adapter = 0; + + // We want to wait until all connections are finished outside the + // thread synchronization. + // + connections = _connections; + } + +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : connections) + { + conn->waitUntilFinished(); + } +#else + for_each(connections.begin(), connections.end(), Ice::voidMemFun(&ConnectionI::waitUntilFinished)); +#endif + + { + IceUtil::Monitor::Lock sync(*this); + if(_transceiver) + { + assert(_connections.size() <= 1); // The connection isn't monitored or reaped. + } + else + { + // Ensure all the connections are finished and reapable at this point. + vector cons; + _monitor->swapReapedConnections(cons); + assert(cons.size() == _connections.size()); + cons.clear(); + } + _connections.clear(); + } + + // + // Must be destroyed outside the synchronization since this might block waiting for + // a timer task to complete. + // + _monitor->destroy(); +} + +bool +IceInternal::IncomingConnectionFactory::isLocal(const EndpointIPtr& endpoint) const +{ + if(_publishedEndpoint && endpoint->equivalent(_publishedEndpoint)) + { + return true; + } + IceUtil::Monitor::Lock sync(*this); + return endpoint->equivalent(_endpoint); +} + +EndpointIPtr +IceInternal::IncomingConnectionFactory::endpoint() const +{ + if(_publishedEndpoint) + { + return _publishedEndpoint; + } + IceUtil::Monitor::Lock sync(*this); + return _endpoint; +} + +list +IceInternal::IncomingConnectionFactory::connections() const +{ + IceUtil::Monitor::Lock sync(*this); + + list result; + + // + // Only copy connections which have not been destroyed. + // +#ifdef ICE_CPP11_COMPILER + remove_copy_if(_connections.begin(), _connections.end(), back_inserter(result), + [](const ConnectionIPtr& conn) + { + return !conn->isActiveOrHolding(); + }); +#else + remove_copy_if(_connections.begin(), _connections.end(), back_inserter(result), + not1(Ice::constMemFun(&ConnectionI::isActiveOrHolding))); +#endif + return result; +} + +void +IceInternal::IncomingConnectionFactory::flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr& outAsync, + Ice::CompressBatch compress) +{ + list c = connections(); // connections() is synchronized, so no need to synchronize here. + + for(list::const_iterator p = c.begin(); p != c.end(); ++p) + { + try + { + outAsync->flushConnection(*p, compress); + } + catch(const LocalException&) + { + // Ignore. + } + } +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::IncomingConnectionFactory::startAsync(SocketOperation) +{ + assert(_acceptor); + if(_state >= StateClosed) + { + return false; + } + + try + { + _acceptor->startAccept(); + } + catch(const Ice::LocalException& ex) + { + ICE_SET_EXCEPTION_FROM_CLONE(_acceptorException, ex.ice_clone()); + _acceptor->getNativeInfo()->completed(SocketOperationRead); + } + return true; +} + +bool +IceInternal::IncomingConnectionFactory::finishAsync(SocketOperation) +{ + assert(_acceptor); + try + { + if(_acceptorException) + { + _acceptorException->ice_throw(); + } + _acceptor->finishAccept(); + } + catch(const LocalException& ex) + { + _acceptorException.reset(ICE_NULLPTR); + + Error out(_instance->initializationData().logger); + out << "couldn't accept connection:\n" << ex << '\n' << _acceptor->toString(); + if(_acceptorStarted) + { + _acceptorStarted = false; + if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true)) + { + closeAcceptor(); + } + } + } + return _state < StateClosed; +} +#endif + +void +IceInternal::IncomingConnectionFactory::message(ThreadPoolCurrent& current) +{ + ConnectionIPtr connection; + + ThreadPoolMessage msg(current, *this); + + { + IceUtil::Monitor::Lock sync(*this); + + ThreadPoolMessage::IOScope io(msg); + if(!io) + { + return; + } + + if(_state >= StateClosed) + { + return; + } + else if(_state == StateHolding) + { + IceUtil::ThreadControl::yield(); + return; + } + + // + // Reap closed connections + // + vector cons; + _monitor->swapReapedConnections(cons); + for(vector::const_iterator p = cons.begin(); p != cons.end(); ++p) + { + _connections.erase(*p); + } + + if(!_acceptorStarted) + { + return; + } + + // + // Now accept a new connection. + // + TransceiverPtr transceiver; + try + { + transceiver = _acceptor->accept(); + + if(_instance->traceLevels()->network >= 2) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "trying to accept " << _endpoint->protocol() << " connection\n" << transceiver->toString(); + } + } + catch(const SocketException& ex) + { + if(noMoreFds(ex.error)) + { + Error out(_instance->initializationData().logger); + out << "can't accept more connections:\n" << ex << '\n' << _acceptor->toString(); + + assert(_acceptorStarted); + _acceptorStarted = false; + if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true)) + { + closeAcceptor(); + } + } + + // Ignore socket exceptions. + return; + } + catch(const LocalException& ex) + { + // Warn about other Ice local exceptions. + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "connection exception:\n" << ex << '\n' << _acceptor->toString(); + } + return; + } + + assert(transceiver); + + try + { + connection = ConnectionI::create(_adapter->getCommunicator(), _instance, _monitor, transceiver, 0, + _endpoint, _adapter); + } + catch(const LocalException& ex) + { + try + { + transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Ignore. + } + + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "connection exception:\n" << ex << '\n' << _acceptor->toString(); + } + return; + } + + _connections.insert(connection); + } + + assert(connection); + + connection->start(ICE_SHARED_FROM_THIS); +} + +void +IceInternal::IncomingConnectionFactory::finished(ThreadPoolCurrent&, bool close) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state < StateClosed) + { + if(close) + { + closeAcceptor(); + } + + // + // If the acceptor hasn't been explicitly stopped (which is the case if the acceptor got closed + // because of an unexpected error), try to restart the acceptor in 1 second. + // + if(!_acceptorStopped) + { + _instance->timer()->schedule(ICE_MAKE_SHARED(StartAcceptor, ICE_SHARED_FROM_THIS, _instance), + IceUtil::Time::seconds(1)); + } + return; + } + + assert(_state >= StateClosed); + setState(StateFinished); + + if(close) + { + closeAcceptor(); + } + +#if TARGET_OS_IPHONE != 0 + sync.release(); + finish(); +#endif +} + +#if TARGET_OS_IPHONE != 0 +void +IceInternal::IncomingConnectionFactory::finish() +{ + unregisterForBackgroundNotification(ICE_SHARED_FROM_THIS); +} +#endif + +string +IceInternal::IncomingConnectionFactory::toString() const +{ + IceUtil::Monitor::Lock sync(*this); + if(_transceiver) + { + return _transceiver->toString(); + } + else if(_acceptor) + { + return _acceptor->toString(); + } + else + { + return string(); + } +} + +NativeInfoPtr +IceInternal::IncomingConnectionFactory::getNativeInfo() +{ + if(_transceiver) + { + return _transceiver->getNativeInfo(); + } + else if(_acceptor) + { + return _acceptor->getNativeInfo(); + } + else + { + return 0; + } +} + +void +IceInternal::IncomingConnectionFactory::connectionStartCompleted(const Ice::ConnectionIPtr& connection) +{ + IceUtil::Monitor::Lock sync(*this); + + // + // Initialy, connections are in the holding state. If the factory is active + // we activate the connection. + // + if(_state == StateActive) + { + connection->activate(); + } +} + +void +IceInternal::IncomingConnectionFactory::connectionStartFailed(const Ice::ConnectionIPtr& /*connection*/, + const Ice::LocalException&) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + return; + } + + // + // Do not warn about connection exceptions here. The connection is not yet validated. + // +} + +// +// COMPILERFIX: The ConnectionFactory setup is broken out into a separate initialize +// function because when it was part of the constructor C++Builder 2007 apps would +// crash if an execption was thrown from any calls within the constructor. +// +IceInternal::IncomingConnectionFactory::IncomingConnectionFactory(const InstancePtr& instance, + const EndpointIPtr& endpoint, + const EndpointIPtr& publishedEndpoint, + const ObjectAdapterIPtr& adapter) : + _instance(instance), + _monitor(new FactoryACMMonitor(instance, dynamic_cast(adapter.get())->getACM())), + _endpoint(endpoint), + _publishedEndpoint(publishedEndpoint), + _acceptorStarted(false), + _acceptorStopped(false), + _adapter(adapter), + _warn(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Connections") > 0), + _state(StateHolding) +{ +} + +void +IceInternal::IncomingConnectionFactory::startAcceptor() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed || _acceptorStarted) + { + return; + } + + _acceptorStopped = false; + createAcceptor(); +} + +void +IceInternal::IncomingConnectionFactory::stopAcceptor() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed || !_acceptorStarted) + { + return; + } + + _acceptorStopped = true; + _acceptorStarted = false; + if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true)) + { + closeAcceptor(); + } +} + +void +IceInternal::IncomingConnectionFactory::initialize() +{ + if(_instance->defaultsAndOverrides()->overrideTimeout) + { + _endpoint = _endpoint->timeout(_instance->defaultsAndOverrides()->overrideTimeoutValue); + } + + if(_instance->defaultsAndOverrides()->overrideCompress) + { + _endpoint = _endpoint->compress(_instance->defaultsAndOverrides()->overrideCompressValue); + } + try + { + const_cast(_transceiver) = _endpoint->transceiver(); + if(_transceiver) + { + if(_instance->traceLevels()->network >= 2) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "attempting to bind to " << _endpoint->protocol() << " socket\n" << _transceiver->toString(); + } + const_cast(_endpoint) = _transceiver->bind(); + ConnectionIPtr connection(ConnectionI::create(_adapter->getCommunicator(), _instance, 0, _transceiver, 0, + _endpoint, _adapter)); + connection->start(0); + _connections.insert(connection); + } + else + { +#if TARGET_OS_IPHONE != 0 + // + // The notification center will call back on the factory to + // start the acceptor if necessary. + // + registerForBackgroundNotification(ICE_SHARED_FROM_THIS); +#else + createAcceptor(); +#endif + } + } + catch(const Ice::Exception&) + { + if(_transceiver) + { + try + { + _transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Ignore + } + } + + _state = StateFinished; + _monitor->destroy(); + _connections.clear(); + throw; + } +} + +IceInternal::IncomingConnectionFactory::~IncomingConnectionFactory() +{ + assert(_state == StateFinished); + assert(_connections.empty()); +} + +void +IceInternal::IncomingConnectionFactory::setState(State state) +{ + if(_state == state) // Don't switch twice. + { + return; + } + + switch(state) + { + case StateActive: + { + if(_state != StateHolding) // Can only switch from holding to active. + { + return; + } + if(_acceptor) + { + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "accepting " << _endpoint->protocol() << " connections at " << _acceptor->toString(); + } + _adapter->getThreadPool()->_register(ICE_SHARED_FROM_THIS, SocketOperationRead); + } +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : _connections) + { + conn->activate(); + } +#else + for_each(_connections.begin(), _connections.end(), Ice::voidMemFun(&ConnectionI::activate)); +#endif + break; + } + + case StateHolding: + { + if(_state != StateActive) // Can only switch from active to holding. + { + return; + } + if(_acceptor) + { + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "holding " << _endpoint->protocol() << " connections at " << _acceptor->toString(); + } + _adapter->getThreadPool()->unregister(ICE_SHARED_FROM_THIS, SocketOperationRead); + } +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : _connections) + { + conn->hold(); + } +#else + for_each(_connections.begin(), _connections.end(), Ice::voidMemFun(&ConnectionI::hold)); +#endif + break; + } + + case StateClosed: + { + if(_acceptorStarted) + { + // + // If possible, close the acceptor now to prevent new connections from + // being accepted while we are deactivating. This is especially useful + // if there are no more threads in the thread pool available to dispatch + // the finish() call. Not all selector implementations do support this + // however. + // + _acceptorStarted = false; + if(_adapter->getThreadPool()->finish(ICE_SHARED_FROM_THIS, true)) + { + closeAcceptor(); + } + } + else + { +#if TARGET_OS_IPHONE != 0 + _adapter->getThreadPool()->dispatch(new FinishCall(ICE_SHARED_FROM_THIS)); +#endif + state = StateFinished; + } + +#ifdef ICE_CPP11_COMPILER + for(const auto& conn : _connections) + { + conn->destroy(ConnectionI::ObjectAdapterDeactivated); + } +#else + for_each(_connections.begin(), _connections.end(), + bind2nd(Ice::voidMemFun1(&ConnectionI::destroy), ConnectionI::ObjectAdapterDeactivated)); +#endif + break; + } + + case StateFinished: + { + assert(_state == StateClosed); + break; + } + } + + _state = state; + notifyAll(); +} + +void +IceInternal::IncomingConnectionFactory::createAcceptor() +{ + try + { + assert(!_acceptorStarted); + _acceptor = _endpoint->acceptor(_adapter->getName()); + assert(_acceptor); + if(_instance->traceLevels()->network >= 2) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "attempting to bind to " << _endpoint->protocol() << " socket " << _acceptor->toString(); + } + + _endpoint = _acceptor->listen(); + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "listening for " << _endpoint->protocol() << " connections\n" << _acceptor->toDetailedString(); + } + + _adapter->getThreadPool()->initialize(ICE_SHARED_FROM_THIS); + if(_state == StateActive) + { + _adapter->getThreadPool()->_register(ICE_SHARED_FROM_THIS, SocketOperationRead); + } + + _acceptorStarted = true; + } + catch(const Ice::Exception&) + { + if(_acceptor) + { + _acceptor->close(); + } + throw; + } +} + +void +IceInternal::IncomingConnectionFactory::closeAcceptor() +{ + assert(_acceptor); + + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "stopping to accept " << _endpoint->protocol() << " connections at " << _acceptor->toString(); + } + + assert(!_acceptorStarted); + _acceptor->close(); +} diff --git a/Sources/IceCpp/ConnectionI.cpp b/Sources/IceCpp/ConnectionI.cpp new file mode 100644 index 0000000..c4d68eb --- /dev/null +++ b/Sources/IceCpp/ConnectionI.cpp @@ -0,0 +1,3670 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // For getThreadPool() and getServantManager(). +#include +#include +#include +#include +#include // For RetryException +#include // For createProxy(). +#include // For createProxy(). +#include + +#ifdef ICE_HAS_BZIP2 +# include +#endif + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +Ice::LocalObject* Ice::upCast(ConnectionI* p) { return p; } +#endif + +namespace +{ + +const ::std::string flushBatchRequests_name = "flushBatchRequests"; + +class TimeoutCallback : public IceUtil::TimerTask +{ +public: + + TimeoutCallback(Ice::ConnectionI* connection) : _connection(connection) + { + } + + void + runTimerTask() + { + _connection->timedOut(); + } + +private: + + Ice::ConnectionI* _connection; +}; + +class DispatchCall : public DispatchWorkItem +{ +public: + + DispatchCall(const ConnectionIPtr& connection, const ConnectionI::StartCallbackPtr& startCB, + const vector& sentCBs, Byte compress, Int requestId, + Int invokeNum, const ServantManagerPtr& servantManager, const ObjectAdapterPtr& adapter, + const OutgoingAsyncBasePtr& outAsync, const ICE_DELEGATE(HeartbeatCallback)& heartbeatCallback, + InputStream& stream) : + DispatchWorkItem(connection), + _connection(connection), + _startCB(startCB), + _sentCBs(sentCBs), + _compress(compress), + _requestId(requestId), + _invokeNum(invokeNum), + _servantManager(servantManager), + _adapter(adapter), + _outAsync(outAsync), + _heartbeatCallback(heartbeatCallback), + _stream(stream.instance(), currentProtocolEncoding) + { + _stream.swap(stream); + } + + virtual void + run() + { + _connection->dispatch(_startCB, _sentCBs, _compress, _requestId, _invokeNum, _servantManager, _adapter, + _outAsync, _heartbeatCallback, _stream); + } + +private: + + const ConnectionIPtr _connection; + const ConnectionI::StartCallbackPtr _startCB; + const vector _sentCBs; + const Byte _compress; + const Int _requestId; + const Int _invokeNum; + const ServantManagerPtr _servantManager; + const ObjectAdapterPtr _adapter; + const OutgoingAsyncBasePtr _outAsync; + const ICE_DELEGATE(HeartbeatCallback) _heartbeatCallback; + InputStream _stream; +}; + +class FinishCall : public DispatchWorkItem +{ +public: + + FinishCall(const Ice::ConnectionIPtr& connection, bool close) : + DispatchWorkItem(connection), _connection(connection), _close(close) + { + } + + virtual void + run() + { + _connection->finish(_close); + } + +private: + + const ConnectionIPtr _connection; + const bool _close; +}; + +// +// Class for handling Ice::Connection::begin_flushBatchRequests +// +class ConnectionFlushBatchAsync : public OutgoingAsyncBase +{ +public: + + ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const InstancePtr&); + + virtual Ice::ConnectionPtr getConnection() const; + + void invoke(const std::string&, Ice::CompressBatch); + +private: + + const Ice::ConnectionIPtr _connection; +}; +typedef IceUtil::Handle ConnectionFlushBatchAsyncPtr; + +ConnectionState connectionStateMap[] = { + ICE_ENUM(ConnectionState, ConnectionStateValidating), // StateNotInitialized + ICE_ENUM(ConnectionState, ConnectionStateValidating), // StateNotValidated + ICE_ENUM(ConnectionState, ConnectionStateActive), // StateActive + ICE_ENUM(ConnectionState, ConnectionStateHolding), // StateHolding + ICE_ENUM(ConnectionState, ConnectionStateClosing), // StateClosing + ICE_ENUM(ConnectionState, ConnectionStateClosing), // StateClosingPending + ICE_ENUM(ConnectionState, ConnectionStateClosed), // StateClosed + ICE_ENUM(ConnectionState, ConnectionStateClosed), // StateFinished +}; + +} + +ConnectionFlushBatchAsync::ConnectionFlushBatchAsync(const ConnectionIPtr& connection, const InstancePtr& instance) : + OutgoingAsyncBase(instance), _connection(connection) +{ +} + +ConnectionPtr +ConnectionFlushBatchAsync::getConnection() const +{ + return _connection; +} + +void +ConnectionFlushBatchAsync::invoke(const string& operation, Ice::CompressBatch compressBatch) +{ + _observer.attach(_instance.get(), operation); + try + { + AsyncStatus status; + bool compress; + int batchRequestNum = _connection->getBatchRequestQueue()->swap(&_os, compress); + if(batchRequestNum == 0) + { + status = AsyncStatusSent; + if(sent()) + { + status = static_cast(status | AsyncStatusInvokeSentCallback); + } + } + else + { + if(compressBatch == ICE_SCOPED_ENUM(CompressBatch, Yes)) + { + compress = true; + } + else if(compressBatch == ICE_SCOPED_ENUM(CompressBatch, No)) + { + compress = false; + } + status = _connection->sendAsyncRequest(ICE_SHARED_FROM_THIS, compress, false, batchRequestNum); + } + + if(status & AsyncStatusSent) + { + _sentSynchronously = true; + if(status & AsyncStatusInvokeSentCallback) + { + invokeSent(); + } + } + } + catch(const RetryException& ex) + { + if(exception(*ex.get())) + { + invokeExceptionAsync(); + } + } + catch(const Exception& ex) + { + if(exception(ex)) + { + invokeExceptionAsync(); + } + } +} + +Ice::ConnectionI::Observer::Observer() : _readStreamPos(0), _writeStreamPos(0) +{ +} + +void +Ice::ConnectionI::Observer::startRead(const Buffer& buf) +{ + if(_readStreamPos) + { + assert(!buf.b.empty()); + _observer->receivedBytes(static_cast(buf.i - _readStreamPos)); + } + _readStreamPos = buf.b.empty() ? 0 : buf.i; +} + +void +Ice::ConnectionI::Observer::finishRead(const Buffer& buf) +{ + if(_readStreamPos == 0) + { + return; + } + assert(buf.i >= _readStreamPos); + _observer->receivedBytes(static_cast(buf.i - _readStreamPos)); + _readStreamPos = 0; +} + +void +Ice::ConnectionI::Observer::startWrite(const Buffer& buf) +{ + if(_writeStreamPos) + { + assert(!buf.b.empty()); + _observer->sentBytes(static_cast(buf.i - _writeStreamPos)); + } + _writeStreamPos = buf.b.empty() ? 0 : buf.i; +} + +void +Ice::ConnectionI::Observer::finishWrite(const Buffer& buf) +{ + if(_writeStreamPos == 0) + { + return; + } + if(buf.i > _writeStreamPos) + { + _observer->sentBytes(static_cast(buf.i - _writeStreamPos)); + } + _writeStreamPos = 0; +} + +void +Ice::ConnectionI::Observer::attach(const Ice::Instrumentation::ConnectionObserverPtr& observer) +{ + ObserverHelperT::attach(observer); + if(!observer) + { + _writeStreamPos = 0; + _readStreamPos = 0; + } +} + +void +Ice::ConnectionI::OutgoingMessage::adopt(OutputStream* str) +{ + if(adopted) + { + if(str) + { + delete stream; + stream = 0; + adopted = false; + } + else + { + return; // Stream is already adopted. + } + } + else if(!str) + { + if(outAsync) + { + return; // Adopting request stream is not necessary. + } + else + { + str = stream; // Adopt this stream + stream = 0; + } + } + + assert(str); + stream = new OutputStream(str->instance(), currentProtocolEncoding); + stream->swap(*str); + adopted = true; +} + +void +Ice::ConnectionI::OutgoingMessage::canceled(bool adoptStream) +{ + assert(outAsync); // Only requests can timeout. + outAsync = 0; + if(adoptStream) + { + adopt(0); // Adopt the request stream + } + else + { + assert(!adopted); + } +} + +bool +Ice::ConnectionI::OutgoingMessage::sent() +{ + if(adopted) + { + delete stream; + } + stream = 0; + + if(outAsync) + { +#if defined(ICE_USE_IOCP) + invokeSent = outAsync->sent(); + return invokeSent || receivedReply; +#else + return outAsync->sent(); +#endif + } + return false; +} + +void +Ice::ConnectionI::OutgoingMessage::completed(const Ice::LocalException& ex) +{ + if(outAsync) + { + if(outAsync->exception(ex)) + { + outAsync->invokeException(); + } + } + + if(adopted) + { + delete stream; + } + stream = 0; +} + +void +Ice::ConnectionI::start(const StartCallbackPtr& callback) +{ + try + { + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) // The connection might already be closed if the communicator was destroyed. + { + assert(_exception); + _exception->ice_throw(); + } + + if(!initialize() || !validate()) + { + if(callback) + { + _startCallback = callback; + return; + } + + // + // Wait for the connection to be validated. + // + while(_state <= StateNotValidated) + { + wait(); + } + + if(_state >= StateClosing) + { + assert(_exception); + _exception->ice_throw(); + } + } + + // + // We start out in holding state. + // + setState(StateHolding); + } + catch(const Ice::LocalException& ex) + { + exception(ex); + if(callback) + { + callback->connectionStartFailed(ICE_SHARED_FROM_THIS, ex); + return; + } + else + { + waitUntilFinished(); + throw; + } + } + + if(callback) + { + callback->connectionStartCompleted(ICE_SHARED_FROM_THIS); + } +} + +void +Ice::ConnectionI::activate() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state <= StateNotValidated) + { + return; + } + if(_acmLastActivity != IceUtil::Time()) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + setState(StateActive); +} + +void +Ice::ConnectionI::hold() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state <= StateNotValidated) + { + return; + } + + setState(StateHolding); +} + +void +Ice::ConnectionI::destroy(DestructionReason reason) +{ + IceUtil::Monitor::Lock sync(*this); + + switch(reason) + { + case ObjectAdapterDeactivated: + { + setState(StateClosing, ObjectAdapterDeactivatedException(__FILE__, __LINE__)); + break; + } + + case CommunicatorDestroyed: + { + setState(StateClosing, CommunicatorDestroyedException(__FILE__, __LINE__)); + break; + } + } +} + +void +Ice::ConnectionI::close(ConnectionClose mode) ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + + if(mode == ICE_SCOPED_ENUM(ConnectionClose, Forcefully)) + { + setState(StateClosed, ConnectionManuallyClosedException(__FILE__, __LINE__, false)); + } + else if(mode == ICE_SCOPED_ENUM(ConnectionClose, Gracefully)) + { + setState(StateClosing, ConnectionManuallyClosedException(__FILE__, __LINE__, true)); + } + else + { + assert(mode == ICE_SCOPED_ENUM(ConnectionClose, GracefullyWithWait)); + + // + // Wait until all outstanding requests have been completed. + // + while(!_asyncRequests.empty()) + { + wait(); + } + + setState(StateClosing, ConnectionManuallyClosedException(__FILE__, __LINE__, true)); + } +} + +bool +Ice::ConnectionI::isActiveOrHolding() const +{ + // + // We can not use trylock here, otherwise the outgoing connection + // factory might return destroyed (closing or closed) connections, + // resulting in connection retry exhaustion. + // + IceUtil::Monitor::Lock sync(*this); + + return _state > StateNotValidated && _state < StateClosing; +} + +bool +Ice::ConnectionI::isFinished() const +{ + // + // We can use trylock here, because as long as there are still + // threads operating in this connection object, connection + // destruction is considered as not yet finished. + // + IceUtil::Monitor::TryLock sync(*this); + + if(!sync.acquired()) + { + return false; + } + + if(_state != StateFinished || _dispatchCount != 0) + { + return false; + } + + assert(_state == StateFinished); + return true; +} + +void +Ice::ConnectionI::throwException() const +{ + IceUtil::Monitor::Lock sync(*this); + + if(_exception) + { + assert(_state >= StateClosing); + _exception->ice_throw(); + } +} + +void +Ice::ConnectionI::waitUntilHolding() const +{ + IceUtil::Monitor::Lock sync(*this); + + while(_state < StateHolding || _dispatchCount > 0) + { + wait(); + } +} + +void +Ice::ConnectionI::waitUntilFinished() +{ + IceUtil::Monitor::Lock sync(*this); + + // + // We wait indefinitely until the connection is finished and all + // outstanding requests are completed. Otherwise we couldn't + // guarantee that there are no outstanding calls when deactivate() + // is called on the servant locators. + // + while(_state < StateFinished || _dispatchCount > 0) + { + wait(); + } + + assert(_state == StateFinished); + + // + // Clear the OA. See bug 1673 for the details of why this is necessary. + // + _adapter = 0; +} + +void +Ice::ConnectionI::updateObserver() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state < StateNotValidated || _state > StateClosed) + { + return; + } + + assert(_instance->initializationData().observer); + + ConnectionObserverPtr o = _instance->initializationData().observer->getConnectionObserver(initConnectionInfo(), + _endpoint, + toConnectionState(_state), + _observer.get()); + _observer.attach(o); +} + +void +Ice::ConnectionI::monitor(const IceUtil::Time& now, const ACMConfig& acm) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state != StateActive) + { + return; + } + assert(acm.timeout != IceUtil::Time()); + + // + // We send a heartbeat if there was no activity in the last + // (timeout / 4) period. Sending a heartbeat sooner than really + // needed is safer to ensure that the receiver will receive the + // heartbeat in time. Sending the heartbeat if there was no + // activity in the last (timeout / 2) period isn't enough since + // monitor() is called only every (timeout / 2) period. + // + // Note that this doesn't imply that we are sending 4 heartbeats + // per timeout period because the monitor() method is still only + // called every (timeout / 2) period. + // + if(acm.heartbeat == ICE_ENUM(ACMHeartbeat, HeartbeatAlways) || + (acm.heartbeat != ICE_ENUM(ACMHeartbeat, HeartbeatOff) && + _writeStream.b.empty() && now >= (_acmLastActivity + acm.timeout / 4))) + { + if(acm.heartbeat != ICE_ENUM(ACMHeartbeat, HeartbeatOnDispatch) || _dispatchCount > 0) + { + sendHeartbeatNow(); + } + } + + if(static_cast(_readStream.b.size()) > headerSize || !_writeStream.b.empty()) + { + // + // If writing or reading, nothing to do, the connection + // timeout will kick-in if writes or reads don't progress. + // This check is necessary because the actitivy timer is + // only set when a message is fully read/written. + // + return; + } + + if(acm.close != ICE_ENUM(ACMClose, CloseOff) && now >= (_acmLastActivity + acm.timeout)) + { + if(acm.close == ICE_ENUM(ACMClose, CloseOnIdleForceful) || + (acm.close != ICE_ENUM(ACMClose, CloseOnIdle) && !_asyncRequests.empty())) + { + // + // Close the connection if we didn't receive a heartbeat in + // the last period. + // + setState(StateClosed, ConnectionTimeoutException(__FILE__, __LINE__)); + } + else if(acm.close != ICE_ENUM(ACMClose, CloseOnInvocation) && + _dispatchCount == 0 && _batchRequestQueue->isEmpty() && _asyncRequests.empty()) + { + // + // The connection is idle, close it. + // + setState(StateClosing, ConnectionTimeoutException(__FILE__, __LINE__)); + } + } +} + +AsyncStatus +Ice::ConnectionI::sendAsyncRequest(const OutgoingAsyncBasePtr& out, bool compress, bool response, int batchRequestNum) +{ + OutputStream* os = out->getOs(); + + IceUtil::Monitor::Lock sync(*this); + // + // If the exception is closed before we even have a chance + // to send our request, we always try to send the request + // again. + // + if(_exception) + { + throw RetryException(*_exception); + } + assert(_state > StateNotValidated); + assert(_state < StateClosing); + + // + // Ensure the message isn't bigger than what we can send with the + // transport. + // + _transceiver->checkSendSize(*os); + + // + // Notify the request that it's cancelable with this connection. + // This will throw if the request is canceled. + // + out->cancelable(ICE_SHARED_FROM_THIS); + Int requestId = 0; + if(response) + { + // + // Create a new unique request ID. + // + requestId = _nextRequestId++; + if(requestId <= 0) + { + _nextRequestId = 1; + requestId = _nextRequestId++; + } + + // + // Fill in the request ID. + // + const Byte* p = reinterpret_cast(&requestId); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize); +#else + copy(p, p + sizeof(Int), os->b.begin() + headerSize); +#endif + } + else if(batchRequestNum > 0) + { + const Byte* p = reinterpret_cast(&batchRequestNum); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize); +#else + copy(p, p + sizeof(Int), os->b.begin() + headerSize); +#endif + } + + out->attachRemoteObserver(initConnectionInfo(), _endpoint, requestId); + + AsyncStatus status = AsyncStatusQueued; + try + { + OutgoingMessage message(out, os, compress, requestId); + status = sendMessage(message); + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + assert(_exception); + _exception->ice_throw(); + } + + if(response) + { + // + // Add to the async requests map. + // + _asyncRequestsHint = _asyncRequests.insert(_asyncRequests.end(), + pair(requestId, out)); + } + return status; +} + +BatchRequestQueuePtr +Ice::ConnectionI::getBatchRequestQueue() const +{ + return _batchRequestQueue; +} + +#ifdef ICE_CPP11_MAPPING +std::function +Ice::ConnectionI::flushBatchRequestsAsync(CompressBatch compress, + ::std::function ex, + ::std::function sent) +{ + class ConnectionFlushBatchLambda : public ConnectionFlushBatchAsync, public LambdaInvoke + { + public: + + ConnectionFlushBatchLambda(std::shared_ptr&& connection, + const InstancePtr& instance, + std::function ex, + std::function sent) : + ConnectionFlushBatchAsync(connection, instance), LambdaInvoke(std::move(ex), std::move(sent)) + { + } + }; + auto outAsync = make_shared(ICE_SHARED_FROM_THIS, _instance, ex, sent); + outAsync->invoke(flushBatchRequests_name, compress); + return [outAsync]() { outAsync->cancel(); }; +} +#else +void +Ice::ConnectionI::flushBatchRequests(CompressBatch compress) +{ + end_flushBatchRequests(begin_flushBatchRequests(compress)); +} + +AsyncResultPtr +Ice::ConnectionI::begin_flushBatchRequests(CompressBatch compress) +{ + return _iceI_begin_flushBatchRequests(compress, dummyCallback, 0); +} + +AsyncResultPtr +Ice::ConnectionI::begin_flushBatchRequests(CompressBatch compress, + const CallbackPtr& cb, + const LocalObjectPtr& cookie) +{ + return _iceI_begin_flushBatchRequests(compress, cb, cookie); +} + +AsyncResultPtr +Ice::ConnectionI::begin_flushBatchRequests(CompressBatch compress, + const Callback_Connection_flushBatchRequestsPtr& cb, + const LocalObjectPtr& cookie) +{ + return _iceI_begin_flushBatchRequests(compress, cb, cookie); +} + +AsyncResultPtr +Ice::ConnectionI::_iceI_begin_flushBatchRequests(CompressBatch compress, + const CallbackBasePtr& cb, + const LocalObjectPtr& cookie) +{ + class ConnectionFlushBatchAsyncWithCallback : public ConnectionFlushBatchAsync, public CallbackCompletion + { + public: + + ConnectionFlushBatchAsyncWithCallback(const Ice::ConnectionIPtr& connection, + const Ice::CommunicatorPtr& communicator, + const InstancePtr& instance, + const CallbackBasePtr& callback, + const Ice::LocalObjectPtr& cookie) : + ConnectionFlushBatchAsync(connection, instance), + CallbackCompletion(callback, cookie), + _communicator(communicator), + _connection(connection) + { + _cookie = cookie; + } + + virtual Ice::CommunicatorPtr getCommunicator() const + { + return _communicator; + } + + virtual Ice::ConnectionPtr getConnection() const + { + return _connection; + } + + virtual const std::string& + getOperation() const + { + return flushBatchRequests_name; + } + + private: + + Ice::CommunicatorPtr _communicator; + Ice::ConnectionPtr _connection; + }; + + ConnectionFlushBatchAsyncPtr result = new ConnectionFlushBatchAsyncWithCallback(this, + _communicator, + _instance, + cb, + cookie); + result->invoke(flushBatchRequests_name, compress); + return result; +} + +void +Ice::ConnectionI::end_flushBatchRequests(const AsyncResultPtr& r) +{ + AsyncResult::_check(r, this, flushBatchRequests_name); + r->_waitForResponse(); +} +#endif + +namespace +{ + +const ::std::string heartbeat_name = "heartbeat"; + +class HeartbeatAsync : public OutgoingAsyncBase +{ +public: + + HeartbeatAsync(const ConnectionIPtr& connection, + const CommunicatorPtr& communicator, + const InstancePtr& instance) : + OutgoingAsyncBase(instance), + _communicator(communicator), + _connection(connection) + { + } + + virtual CommunicatorPtr getCommunicator() const + { + return _communicator; + } + + virtual ConnectionPtr getConnection() const + { + return _connection; + } + + virtual const string& getOperation() const + { + return heartbeat_name; + } + + void invoke() + { + _observer.attach(_instance.get(), heartbeat_name); + try + { + _os.write(magic[0]); + _os.write(magic[1]); + _os.write(magic[2]); + _os.write(magic[3]); + _os.write(currentProtocol); + _os.write(currentProtocolEncoding); + _os.write(validateConnectionMsg); + _os.write(static_cast(0)); // Compression status (always zero for validate connection). + _os.write(headerSize); // Message size. + _os.i = _os.b.begin(); + + AsyncStatus status = _connection->sendAsyncRequest(ICE_SHARED_FROM_THIS, false, false, 0); + if(status & AsyncStatusSent) + { + _sentSynchronously = true; + if(status & AsyncStatusInvokeSentCallback) + { + invokeSent(); + } + } + } + catch(const RetryException& ex) + { + if(exception(*ex.get())) + { + invokeExceptionAsync(); + } + } + catch(const Exception& ex) + { + if(exception(ex)) + { + invokeExceptionAsync(); + } + } + } + +private: + + CommunicatorPtr _communicator; + ConnectionIPtr _connection; +}; +typedef IceUtil::Handle HeartbeatAsyncPtr; + +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::ConnectionI::heartbeat() +{ + Connection::heartbeatAsync().get(); +} + +std::function +Ice::ConnectionI::heartbeatAsync(::std::function ex, ::std::function sent) +{ + class HeartbeatLambda : public HeartbeatAsync, public LambdaInvoke + { + public: + + HeartbeatLambda(std::shared_ptr&& connection, + std::shared_ptr& communicator, + const InstancePtr& instance, + std::function ex, + std::function sent) : + HeartbeatAsync(connection, communicator, instance), LambdaInvoke(std::move(ex), std::move(sent)) + { + } + }; + auto outAsync = make_shared(ICE_SHARED_FROM_THIS, _communicator, _instance, ex, sent); + outAsync->invoke(); + return [outAsync]() { outAsync->cancel(); }; +} +#else +void +Ice::ConnectionI::heartbeat() +{ + end_heartbeat(begin_heartbeat()); +} + +AsyncResultPtr +Ice::ConnectionI::begin_heartbeat() +{ + return _iceI_begin_heartbeat(dummyCallback, 0); +} + +AsyncResultPtr +Ice::ConnectionI::begin_heartbeat(const CallbackPtr& cb, const LocalObjectPtr& cookie) +{ + return _iceI_begin_heartbeat(cb, cookie); +} + +AsyncResultPtr +Ice::ConnectionI::begin_heartbeat(const Callback_Connection_heartbeatPtr& cb, const LocalObjectPtr& cookie) +{ + return _iceI_begin_heartbeat(cb, cookie); +} + +AsyncResultPtr +Ice::ConnectionI::_iceI_begin_heartbeat(const CallbackBasePtr& cb, const LocalObjectPtr& cookie) +{ + class HeartbeatCallback : public HeartbeatAsync, public CallbackCompletion + { + public: + + HeartbeatCallback(const ConnectionIPtr& connection, + const CommunicatorPtr& communicator, + const InstancePtr& instance, + const CallbackBasePtr& callback, + const LocalObjectPtr& cookie) : + HeartbeatAsync(connection, communicator, instance), + CallbackCompletion(callback, cookie) + { + _cookie = cookie; + } + }; + + HeartbeatAsyncPtr result = new HeartbeatCallback(this, _communicator, _instance, cb, cookie); + result->invoke(); + return result; +} + +void +Ice::ConnectionI::end_heartbeat(const AsyncResultPtr& r) +{ + AsyncResult::_check(r, this, heartbeat_name); + r->_waitForResponse(); +} +#endif + +void +Ice::ConnectionI::setHeartbeatCallback(ICE_IN(ICE_DELEGATE(HeartbeatCallback)) callback) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + return; + } + _heartbeatCallback = callback; +} + +void +Ice::ConnectionI::setCloseCallback(ICE_IN(ICE_DELEGATE(CloseCallback)) callback) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + if(callback) + { + class CallbackWorkItem : public DispatchWorkItem + { + public: + + CallbackWorkItem(const ConnectionIPtr& connection, ICE_IN(ICE_DELEGATE(CloseCallback)) callback) : + _connection(connection), +#ifdef ICE_CPP11_MAPPING + _callback(std::move(callback)) +#else + _callback(callback) +#endif + { + } + + virtual void run() + { + _connection->closeCallback(_callback); + } + + private: + + const ConnectionIPtr _connection; + const ICE_DELEGATE(CloseCallback) _callback; + }; +#ifdef ICE_CPP11_MAPPING + _threadPool->dispatch(new CallbackWorkItem(ICE_SHARED_FROM_THIS, std::move(callback))); +#else + _threadPool->dispatch(new CallbackWorkItem(ICE_SHARED_FROM_THIS, callback)); +#endif + } + } + else + { + _closeCallback = callback; + } +} + +void +Ice::ConnectionI::closeCallback(const ICE_DELEGATE(CloseCallback)& callback) +{ + try + { +#ifdef ICE_CPP11_MAPPING + callback(ICE_SHARED_FROM_THIS); +#else + callback->closed(ICE_SHARED_FROM_THIS); +#endif + } + catch(const std::exception& ex) + { + Error out(_instance->initializationData().logger); + out << "connection callback exception:\n" << ex << '\n' << _desc; + } + catch(...) + { + Error out(_instance->initializationData().logger); + out << "connection callback exception:\nunknown c++ exception" << '\n' << _desc; + } +} + +void +Ice::ConnectionI::setACM(const IceUtil::Optional& timeout, + const IceUtil::Optional& close, + const IceUtil::Optional& heartbeat) +{ + IceUtil::Monitor::Lock sync(*this); + if(timeout && *timeout < 0) + { +#ifdef ICE_CPP11_MAPPING + throw invalid_argument("invalid negative ACM timeout value"); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "invalid negative ACM timeout value"); +#endif + } + if(!_monitor || _state >= StateClosed) + { + return; + } + + if(_state == StateActive) + { + _monitor->remove(ICE_SHARED_FROM_THIS); + } + _monitor = _monitor->acm(timeout, close, heartbeat); + + if(_monitor->getACM().timeout <= 0) + { + _acmLastActivity = IceUtil::Time(); // Disable the recording of last activity. + } + else if(_acmLastActivity == IceUtil::Time() && _state == StateActive) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + + if(_state == StateActive) + { + _monitor->add(ICE_SHARED_FROM_THIS); + } +} + +ACM +Ice::ConnectionI::getACM() ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + ACM acm; + acm.timeout = 0; + acm.close = ICE_ENUM(ACMClose, CloseOff); + acm.heartbeat = ICE_ENUM(ACMHeartbeat, HeartbeatOff); + return _monitor ? _monitor->getACM() : acm; +} + +void +Ice::ConnectionI::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, const LocalException& ex) +{ + // + // NOTE: This isn't called from a thread pool thread. + // + + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + return; // The request has already been or will be shortly notified of the failure. + } + + for(deque::iterator o = _sendStreams.begin(); o != _sendStreams.end(); ++o) + { + if(o->outAsync.get() == outAsync.get()) + { + if(o->requestId) + { + if(_asyncRequestsHint != _asyncRequests.end() && + _asyncRequestsHint->second == ICE_DYNAMIC_CAST(OutgoingAsync, outAsync)) + { + _asyncRequests.erase(_asyncRequestsHint); + _asyncRequestsHint = _asyncRequests.end(); + } + else + { + _asyncRequests.erase(o->requestId); + } + } + + if(dynamic_cast(&ex)) + { + setState(StateClosed, ex); + } + else + { + // + // If the request is being sent, don't remove it from the send streams, + // it will be removed once the sending is finished. + // + if(o == _sendStreams.begin()) + { + o->canceled(true); // true = adopt the stream + } + else + { + o->canceled(false); + _sendStreams.erase(o); + } + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + } + return; + } + } + + if(ICE_DYNAMIC_CAST(OutgoingAsync, outAsync)) + { + if(_asyncRequestsHint != _asyncRequests.end()) + { + if(_asyncRequestsHint->second == outAsync) + { + if(dynamic_cast(&ex)) + { + setState(StateClosed, ex); + } + else + { + _asyncRequests.erase(_asyncRequestsHint); + _asyncRequestsHint = _asyncRequests.end(); + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + } + return; + } + } + + for(map::iterator p = _asyncRequests.begin(); p != _asyncRequests.end(); ++p) + { + if(p->second.get() == outAsync.get()) + { + if(dynamic_cast(&ex)) + { + setState(StateClosed, ex); + } + else + { + assert(p != _asyncRequestsHint); + _asyncRequests.erase(p); + if(outAsync->exception(ex)) + { + outAsync->invokeExceptionAsync(); + } + } + return; + } + } + } +} + +void +Ice::ConnectionI::sendResponse(Int, OutputStream* os, Byte compressFlag, bool /*amd*/) +{ + IceUtil::Monitor::Lock sync(*this); + assert(_state > StateNotValidated); + + try + { + if(--_dispatchCount == 0) + { + if(_state == StateFinished) + { + reap(); + } + notifyAll(); + } + + if(_state >= StateClosed) + { + assert(_exception); + _exception->ice_throw(); + } + + OutgoingMessage message(os, compressFlag > 0); + sendMessage(message); + + if(_state == StateClosing && _dispatchCount == 0) + { + initiateShutdown(); + } + + return; + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + } +} + +void +Ice::ConnectionI::sendNoResponse() +{ + IceUtil::Monitor::Lock sync(*this); + assert(_state > StateNotValidated); + + try + { + if(--_dispatchCount == 0) + { + if(_state == StateFinished) + { + reap(); + } + notifyAll(); + } + + if(_state >= StateClosed) + { + assert(_exception); + _exception->ice_throw(); + } + + if(_state == StateClosing && _dispatchCount == 0) + { + initiateShutdown(); + } + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + } +} + +bool +Ice::ConnectionI::systemException(Int, const SystemException&, bool /*amd*/) +{ + return false; // System exceptions aren't marshalled. +} + +void +Ice::ConnectionI::invokeException(Ice::Int, const LocalException& ex, int invokeNum, bool /*amd*/) +{ + // + // Fatal exception while invoking a request. Since sendResponse/sendNoResponse isn't + // called in case of a fatal exception we decrement _dispatchCount here. + // + + IceUtil::Monitor::Lock sync(*this); + setState(StateClosed, ex); + + if(invokeNum > 0) + { + assert(_dispatchCount >= invokeNum); + _dispatchCount -= invokeNum; + if(_dispatchCount == 0) + { + if(_state == StateFinished) + { + reap(); + } + notifyAll(); + } + } +} + +EndpointIPtr +Ice::ConnectionI::endpoint() const +{ + return _endpoint; // No mutex protection necessary, _endpoint is immutable. +} + +ConnectorPtr +Ice::ConnectionI::connector() const +{ + return _connector; // No mutex protection necessary, _connector is immutable. +} + +void +Ice::ConnectionI::setAdapter(const ObjectAdapterPtr& adapter) +{ + if(adapter) + { + // Go through the adapter to set the adapter and servant manager on this connection + // to ensure the object adapter is still active. + dynamic_cast(adapter.get())->setAdapterOnConnection(ICE_SHARED_FROM_THIS); + } + else + { + IceUtil::Monitor::Lock sync(*this); + if(_state <= StateNotValidated || _state >= StateClosing) + { + return; + } + + _adapter = 0; + _servantManager = 0; + } + + // + // We never change the thread pool with which we were initially + // registered, even if we add or remove an object adapter. + // +} + +ObjectAdapterPtr +Ice::ConnectionI::getAdapter() const ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + return _adapter; +} + +EndpointPtr +Ice::ConnectionI::getEndpoint() const ICE_NOEXCEPT +{ + return _endpoint; // No mutex protection necessary, _endpoint is immutable. +} + +ObjectPrxPtr +Ice::ConnectionI::createProxy(const Identity& ident) const +{ + // + // Create a reference and return a reverse proxy for this + // reference. + // + return _instance->proxyFactory()->referenceToProxy( + _instance->referenceFactory()->create(ident, ICE_SHARED_FROM_CONST_THIS(ConnectionI))); +} + +void +Ice::ConnectionI::setAdapterAndServantManager(const ObjectAdapterPtr& adapter, + const IceInternal::ServantManagerPtr& servantManager) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state <= StateNotValidated || _state >= StateClosing) + { + return; + } + assert(adapter); // Called by ObjectAdapterI::setAdapterOnConnection + _adapter = adapter; + _servantManager = servantManager; +} + +#if defined(ICE_USE_IOCP) +bool +Ice::ConnectionI::startAsync(SocketOperation operation) +{ + if(_state >= StateClosed) + { + return false; + } + + try + { + if(operation & SocketOperationWrite) + { + if(_observer) + { + _observer.startWrite(_writeStream); + } + + if(_transceiver->startWrite(_writeStream) && !_sendStreams.empty()) + { + // The whole message is written, assume it's sent now for at-most-once semantics. + _sendStreams.front().isSent = true; + } + } + else if(operation & SocketOperationRead) + { + if(_observer && !_readHeader) + { + _observer.startRead(_readStream); + } + + _transceiver->startRead(_readStream); + } + } + catch(const Ice::LocalException& ex) + { + setState(StateClosed, ex); + return false; + } + return true; +} + +bool +Ice::ConnectionI::finishAsync(SocketOperation operation) +{ + try + { + if(operation & SocketOperationWrite) + { + Buffer::Container::iterator start = _writeStream.i; + _transceiver->finishWrite(_writeStream); + if(_instance->traceLevels()->network >= 3 && _writeStream.i != start) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "sent " << (_writeStream.i - start); + if(!_endpoint->datagram()) + { + out << " of " << (_writeStream.b.end() - start); + } + out << " bytes via " << _endpoint->protocol() << "\n" << toString(); + } + + if(_observer) + { + _observer.finishWrite(_writeStream); + } + } + else if(operation & SocketOperationRead) + { + Buffer::Container::iterator start = _readStream.i; + _transceiver->finishRead(_readStream); + if(_instance->traceLevels()->network >= 3 && _readStream.i != start) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "received "; + if(_endpoint->datagram()) + { + out << _readStream.b.size(); + } + else + { + out << (_readStream.i - start) << " of " << (_readStream.b.end() - start); + } + out << " bytes via " << _endpoint->protocol() << "\n" << toString(); + } + + if(_observer && !_readHeader) + { + _observer.finishRead(_readStream); + } + } + } + catch(const Ice::LocalException& ex) + { + setState(StateClosed, ex); + } + return _state < StateClosed; +} +#endif + +void +Ice::ConnectionI::message(ThreadPoolCurrent& current) +{ + StartCallbackPtr startCB; + vector sentCBs; + Byte compress = 0; + Int requestId = 0; + Int invokeNum = 0; + ServantManagerPtr servantManager; + ObjectAdapterPtr adapter; + OutgoingAsyncBasePtr outAsync; + ICE_DELEGATE(HeartbeatCallback) heartbeatCallback; + int dispatchCount = 0; + + ThreadPoolMessage msg(current, *this); + { + IceUtil::Monitor::Lock sync(*this); + + ThreadPoolMessage::IOScope io(msg); + if(!io) + { + return; + } + + if(_state >= StateClosed) + { + return; + } + + SocketOperation readyOp = current.operation; + try + { + unscheduleTimeout(current.operation); + + SocketOperation writeOp = SocketOperationNone; + SocketOperation readOp = SocketOperationNone; + if(readyOp & SocketOperationWrite) + { + if(_observer) + { + _observer.startWrite(_writeStream); + } + writeOp = write(_writeStream); + if(_observer && !(writeOp & SocketOperationWrite)) + { + _observer.finishWrite(_writeStream); + } + } + + while(readyOp & SocketOperationRead) + { + if(_observer && !_readHeader) + { + _observer.startRead(_readStream); + } + + readOp = read(_readStream); + if(readOp & SocketOperationRead) + { + break; + } + if(_observer && !_readHeader) + { + assert(_readStream.i == _readStream.b.end()); + _observer.finishRead(_readStream); + } + + if(_readHeader) // Read header if necessary. + { + _readHeader = false; + + if(_observer) + { + _observer->receivedBytes(static_cast(headerSize)); + } + + // + // Connection is validated on first message. This is only used by + // setState() to check wether or not we can print a connection + // warning (a client might close the connection forcefully if the + // connection isn't validated, we don't want to print a warning + // in this case). + // + _validated = true; + + ptrdiff_t pos = _readStream.i - _readStream.b.begin(); + if(pos < headerSize) + { + // + // This situation is possible for small UDP packets. + // + throw IllegalMessageSizeException(__FILE__, __LINE__); + } + + _readStream.i = _readStream.b.begin(); + const Byte* m; + _readStream.readBlob(m, static_cast(sizeof(magic))); + if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3]) + { + throw BadMagicException(__FILE__, __LINE__, "", Ice::ByteSeq(&m[0], &m[0] + sizeof(magic))); + } + ProtocolVersion pv; + _readStream.read(pv); + checkSupportedProtocol(pv); + EncodingVersion ev; + _readStream.read(ev); + checkSupportedProtocolEncoding(ev); + + Byte messageType; + _readStream.read(messageType); + Byte compressByte; + _readStream.read(compressByte); + Int size; + _readStream.read(size); + if(size < headerSize) + { + throw IllegalMessageSizeException(__FILE__, __LINE__); + } + + if(size > static_cast(_messageSizeMax)) + { + Ex::throwMemoryLimitException(__FILE__, __LINE__, static_cast(size), _messageSizeMax); + } + if(static_cast(size) > _readStream.b.size()) + { + _readStream.b.resize(static_cast(size)); + } + _readStream.i = _readStream.b.begin() + pos; + } + + if(_readStream.i != _readStream.b.end()) + { + if(_endpoint->datagram()) + { + throw DatagramLimitException(__FILE__, __LINE__); // The message was truncated. + } + continue; + } + break; + } + + SocketOperation newOp = static_cast(readOp | writeOp); + readyOp = static_cast(readyOp & ~newOp); + assert(readyOp || newOp); + + if(_state <= StateNotValidated) + { + if(newOp) + { + // + // Wait for all the transceiver conditions to be + // satisfied before continuing. + // + scheduleTimeout(newOp); + _threadPool->update(ICE_SHARED_FROM_THIS, current.operation, newOp); + return; + } + + if(_state == StateNotInitialized && !initialize(current.operation)) + { + return; + } + + if(_state <= StateNotValidated && !validate(current.operation)) + { + return; + } + + _threadPool->unregister(ICE_SHARED_FROM_THIS, current.operation); + + // + // We start out in holding state. + // + setState(StateHolding); + if(_startCallback) + { + swap(_startCallback, startCB); + if(startCB) + { + ++dispatchCount; + } + } + } + else + { + assert(_state <= StateClosingPending); + + // + // We parse messages first, if we receive a close + // connection message we won't send more messages. + // + if(readyOp & SocketOperationRead) + { + newOp = static_cast(newOp | parseMessage(current.stream, + invokeNum, + requestId, + compress, + servantManager, + adapter, + outAsync, + heartbeatCallback, + dispatchCount)); + } + + if(readyOp & SocketOperationWrite) + { + newOp = static_cast(newOp | sendNextMessage(sentCBs)); + if(!sentCBs.empty()) + { + ++dispatchCount; + } + } + + if(_state < StateClosed) + { + scheduleTimeout(newOp); + _threadPool->update(ICE_SHARED_FROM_THIS, current.operation, newOp); + } + } + + if(_acmLastActivity != IceUtil::Time()) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + + if(dispatchCount == 0) + { + return; // Nothing to dispatch we're done! + } + + _dispatchCount += dispatchCount; + io.completed(); + } + catch(const DatagramLimitException&) // Expected. + { + if(_warnUdp) + { + Warning out(_instance->initializationData().logger); + out << "maximum datagram size of " << _readStream.i - _readStream.b.begin() << " exceeded"; + } + _readStream.resize(headerSize); + _readStream.i = _readStream.b.begin(); + _readHeader = true; + return; + } + catch(const SocketException& ex) + { + setState(StateClosed, ex); + return; + } + catch(const LocalException& ex) + { + if(_endpoint->datagram()) + { + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "datagram connection exception:\n" << ex << '\n' << _desc; + } + _readStream.resize(headerSize); + _readStream.i = _readStream.b.begin(); + _readHeader = true; + } + else + { + setState(StateClosed, ex); + } + return; + } + } + +// dispatchFromThisThread dispatches to the correct DispatchQueue +#ifdef ICE_SWIFT + _threadPool->dispatchFromThisThread(new DispatchCall(ICE_SHARED_FROM_THIS, startCB, sentCBs, compress, requestId, + invokeNum, servantManager, adapter, outAsync, + heartbeatCallback, current.stream)); +#else + if(!_dispatcher) // Optimization, call dispatch() directly if there's no dispatcher. + { + dispatch(startCB, sentCBs, compress, requestId, invokeNum, servantManager, adapter, outAsync, heartbeatCallback, + current.stream); + } + else + { + _threadPool->dispatchFromThisThread(new DispatchCall(ICE_SHARED_FROM_THIS, startCB, sentCBs, compress, requestId, + invokeNum, servantManager, adapter, outAsync, + heartbeatCallback, current.stream)); + + } +#endif +} + +void +ConnectionI::dispatch(const StartCallbackPtr& startCB, const vector& sentCBs, + Byte compress, Int requestId, Int invokeNum, const ServantManagerPtr& servantManager, + const ObjectAdapterPtr& adapter, const OutgoingAsyncBasePtr& outAsync, + const ICE_DELEGATE(HeartbeatCallback)& heartbeatCallback, InputStream& stream) +{ + int dispatchedCount = 0; + + // + // Notify the factory that the connection establishment and + // validation has completed. + // + if(startCB) + { + startCB->connectionStartCompleted(ICE_SHARED_FROM_THIS); + ++dispatchedCount; + } + + // + // Notify AMI calls that the message was sent. + // + if(!sentCBs.empty()) + { + for(vector::const_iterator p = sentCBs.begin(); p != sentCBs.end(); ++p) + { +#if defined(ICE_USE_IOCP) + if(p->invokeSent) + { + p->outAsync->invokeSent(); + } + if(p->receivedReply) + { + OutgoingAsyncPtr o = ICE_DYNAMIC_CAST(OutgoingAsync, p->outAsync); + if(o->response()) + { + o->invokeResponse(); + } + } +#else + p->outAsync->invokeSent(); +#endif + } + ++dispatchedCount; + } + + // + // Asynchronous replies must be handled outside the thread + // synchronization, so that nested calls are possible. + // + if(outAsync) + { + outAsync->invokeResponse(); + ++dispatchedCount; + } + + if(heartbeatCallback) + { + try + { +#ifdef ICE_CPP11_MAPPING + heartbeatCallback(ICE_SHARED_FROM_THIS); +#else + heartbeatCallback->heartbeat(ICE_SHARED_FROM_THIS); +#endif + } + catch(const std::exception& ex) + { + Error out(_instance->initializationData().logger); + out << "connection callback exception:\n" << ex << '\n' << _desc; + } + catch(...) + { + Error out(_instance->initializationData().logger); + out << "connection callback exception:\nunknown c++ exception" << '\n' << _desc; + } + ++dispatchedCount; + } + + // + // Method invocation (or multiple invocations for batch messages) + // must be done outside the thread synchronization, so that nested + // calls are possible. + // + if(invokeNum) + { + invokeAll(stream, invokeNum, requestId, compress, servantManager, adapter); + + // + // Don't increase count, the dispatch count is + // decreased when the incoming reply is sent. + // + } + + // + // Decrease dispatch count. + // + if(dispatchedCount > 0) + { + IceUtil::Monitor::Lock sync(*this); + _dispatchCount -= dispatchedCount; + if(_dispatchCount == 0) + { + // + // Only initiate shutdown if not already done. It might + // have already been done if the sent callback or AMI + // callback was dispatched when the connection was already + // in the closing state. + // + if(_state == StateClosing) + { + try + { + initiateShutdown(); + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + } + } + else if(_state == StateFinished) + { + reap(); + } + notifyAll(); + } + } +} + +void +Ice::ConnectionI::finished(ThreadPoolCurrent& current, bool close) +{ + { + IceUtil::Monitor::Lock sync(*this); + assert(_state == StateClosed); + unscheduleTimeout(static_cast(SocketOperationRead | SocketOperationWrite)); + } + + // + // If there are no callbacks to call, we don't call ioCompleted() since we're not going + // to call code that will potentially block (this avoids promoting a new leader and + // unecessary thread creation, especially if this is called on shutdown). + // + if(!_startCallback && _sendStreams.empty() && _asyncRequests.empty() && !_closeCallback && !_heartbeatCallback) + { + finish(close); + return; + } + + current.ioCompleted(); + +// dispatchFromThisThread dispatches to the correct DispatchQueue +#ifdef ICE_SWIFT + _threadPool->dispatchFromThisThread(new FinishCall(ICE_SHARED_FROM_THIS, close)); +#else + if(!_dispatcher) // Optimization, call finish() directly if there's no dispatcher. + { + finish(close); + } + else + { + _threadPool->dispatchFromThisThread(new FinishCall(ICE_SHARED_FROM_THIS, close)); + } +#endif +} + +void +Ice::ConnectionI::finish(bool close) +{ + if(!_initialized) + { + if(_instance->traceLevels()->network >= 2) + { + string verb = _connector ? "establish" : "accept"; + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + + out << "failed to " << verb << " " << _endpoint->protocol() << " connection\n" << toString() + << "\n" << *_exception; + } + } + else + { + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "closed " << _endpoint->protocol() << " connection\n" << toString(); + + if(!(dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()))) + { + out << "\n" << *_exception; + } + } + } + + if(close) + { + try + { + _transceiver->close(); + } + catch(const Ice::LocalException& ex) + { + Error out(_logger); + out << "unexpected connection exception:\n" << ex << '\n' << _desc; + } + } + + if(_startCallback) + { + assert(_exception); + + _startCallback->connectionStartFailed(ICE_SHARED_FROM_THIS, *_exception); + _startCallback = 0; + } + + if(!_sendStreams.empty()) + { + if(!_writeStream.b.empty()) + { + // + // Return the stream to the outgoing call. This is important for + // retriable AMI calls which are not marshalled again. + // + OutgoingMessage* message = &_sendStreams.front(); + _writeStream.swap(*message->stream); + +#if defined(ICE_USE_IOCP) + // + // The current message might be sent but not yet removed from _sendStreams. If + // the response has been received in the meantime, we remove the message from + // _sendStreams to not call finished on a message which is already done. + // + if(message->isSent || message->receivedReply) + { + if(message->sent() && message->invokeSent) + { + message->outAsync->invokeSent(); + } + if(message->receivedReply) + { + OutgoingAsyncPtr outAsync = ICE_DYNAMIC_CAST(OutgoingAsync, message->outAsync); + if(outAsync->response()) + { + outAsync->invokeResponse(); + } + } + _sendStreams.pop_front(); + } +#endif + } + + for(deque::iterator o = _sendStreams.begin(); o != _sendStreams.end(); ++o) + { + o->completed(*_exception); + if(o->requestId) // Make sure finished isn't called twice. + { + _asyncRequests.erase(o->requestId); + } + } + + _sendStreams.clear(); + } + + for(map::const_iterator q = _asyncRequests.begin(); q != _asyncRequests.end(); ++q) + { + if(q->second->exception(*_exception)) + { + q->second->invokeException(); + } + } + + _asyncRequests.clear(); + + // + // Don't wait to be reaped to reclaim memory allocated by read/write streams. + // + _writeStream.clear(); + _writeStream.b.clear(); + _readStream.clear(); + _readStream.b.clear(); + + if(_closeCallback) + { + closeCallback(_closeCallback); + _closeCallback = ICE_NULLPTR; + } + + _heartbeatCallback = ICE_NULLPTR; + + // + // This must be done last as this will cause waitUntilFinished() to return (and communicator + // objects such as the timer might be destroyed too). + // + { + IceUtil::Monitor::Lock sync(*this); + setState(StateFinished); + + if(_dispatchCount == 0) + { + reap(); + } + } +} + +string +Ice::ConnectionI::toString() const ICE_NOEXCEPT +{ + return _desc; // No mutex lock, _desc is immutable. +} + +NativeInfoPtr +Ice::ConnectionI::getNativeInfo() +{ + return _transceiver->getNativeInfo(); +} + +void +Ice::ConnectionI::timedOut() +{ + IceUtil::Monitor::Lock sync(*this); + if(_state <= StateNotValidated) + { + setState(StateClosed, ConnectTimeoutException(__FILE__, __LINE__)); + } + else if(_state < StateClosing) + { + setState(StateClosed, TimeoutException(__FILE__, __LINE__)); + } + else if(_state < StateClosed) + { + setState(StateClosed, CloseTimeoutException(__FILE__, __LINE__)); + } +} + +string +Ice::ConnectionI::type() const ICE_NOEXCEPT +{ + return _type; // No mutex lock, _type is immutable. +} + +Ice::Int +Ice::ConnectionI::timeout() const ICE_NOEXCEPT +{ + return _endpoint->timeout(); // No mutex lock, _endpoint is immutable. +} + +ConnectionInfoPtr +Ice::ConnectionI::getInfo() const +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + _exception->ice_throw(); + } + return initConnectionInfo(); +} + +void +Ice::ConnectionI::setBufferSize(Ice::Int rcvSize, Ice::Int sndSize) +{ + IceUtil::Monitor::Lock sync(*this); + if(_state >= StateClosed) + { + _exception->ice_throw(); + } + _transceiver->setBufferSize(rcvSize, sndSize); + _info = 0; // Invalidate the cached connection info +} + +void +Ice::ConnectionI::exception(const LocalException& ex) +{ + IceUtil::Monitor::Lock sync(*this); + setState(StateClosed, ex); +} + +Ice::ConnectionI::ConnectionI(const CommunicatorPtr& communicator, + const InstancePtr& instance, + const ACMMonitorPtr& monitor, + const TransceiverPtr& transceiver, + const ConnectorPtr& connector, + const EndpointIPtr& endpoint, + const ObjectAdapterIPtr& adapter) : + _communicator(communicator), + _instance(instance), + _monitor(monitor), + _transceiver(transceiver), + _desc(transceiver->toString()), + _type(transceiver->protocol()), + _connector(connector), + _endpoint(endpoint), + _adapter(adapter), + _dispatcher(_instance->initializationData().dispatcher), // Cached for better performance. + _logger(_instance->initializationData().logger), // Cached for better performance. + _traceLevels(_instance->traceLevels()), // Cached for better performance. + _timer(_instance->timer()), // Cached for better performance. + _writeTimeout(new TimeoutCallback(this)), + _writeTimeoutScheduled(false), + _readTimeout(new TimeoutCallback(this)), + _readTimeoutScheduled(false), + _warn(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Connections") > 0), + _warnUdp(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Datagrams") > 0), + _compressionLevel(1), + _nextRequestId(1), + _asyncRequestsHint(_asyncRequests.end()), + _messageSizeMax(adapter ? adapter->messageSizeMax() : _instance->messageSizeMax()), + _batchRequestQueue(new BatchRequestQueue(instance, endpoint->datagram())), + _readStream(_instance.get(), Ice::currentProtocolEncoding), + _readHeader(false), + _writeStream(_instance.get(), Ice::currentProtocolEncoding), + _dispatchCount(0), + _state(StateNotInitialized), + _shutdownInitiated(false), + _initialized(false), + _validated(false) +{ + const Ice::PropertiesPtr& properties = _instance->initializationData().properties; + + int& compressionLevel = const_cast(_compressionLevel); + compressionLevel = properties->getPropertyAsIntWithDefault("Ice.Compression.Level", 1); + if(compressionLevel < 1) + { + compressionLevel = 1; + } + else if(compressionLevel > 9) + { + compressionLevel = 9; + } + + if(adapter) + { + _servantManager = adapter->getServantManager(); + } + + if(_monitor && _monitor->getACM().timeout > 0) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } +} + +Ice::ConnectionIPtr +Ice::ConnectionI::create(const CommunicatorPtr& communicator, + const InstancePtr& instance, + const ACMMonitorPtr& monitor, + const TransceiverPtr& transceiver, + const ConnectorPtr& connector, + const EndpointIPtr& endpoint, + const ObjectAdapterIPtr& adapter) +{ + Ice::ConnectionIPtr conn(new ConnectionI(communicator, instance, monitor, transceiver, connector, + endpoint, adapter)); + if(adapter) + { + const_cast(conn->_threadPool) = adapter->getThreadPool(); + } + else + { + const_cast(conn->_threadPool) = conn->_instance->clientThreadPool(); + } + conn->_threadPool->initialize(conn); + return conn; +} + +Ice::ConnectionI::~ConnectionI() +{ + assert(!_startCallback); + assert(!_closeCallback); + assert(!_heartbeatCallback); + assert(_state == StateFinished); + assert(_dispatchCount == 0); + assert(_sendStreams.empty()); + assert(_asyncRequests.empty()); +} + +void +Ice::ConnectionI::setState(State state, const LocalException& ex) +{ + // + // If setState() is called with an exception, then only closed and + // closing states are permissible. + // + assert(state >= StateClosing); + + if(_state == state) // Don't switch twice. + { + return; + } + + if(!_exception) + { + // + // If we are in closed state, an exception must be set. + // + assert(_state != StateClosed); + ICE_SET_EXCEPTION_FROM_CLONE(_exception, ex.ice_clone()); + // + // We don't warn if we are not validated. + // + if(_warn && _validated) + { + // + // Don't warn about certain expected exceptions. + // + if(!(dynamic_cast(&ex) || + dynamic_cast(&ex) || + dynamic_cast(&ex) || + dynamic_cast(&ex) || + dynamic_cast(&ex) || + (dynamic_cast(&ex) && _state >= StateClosing))) + { + Warning out(_logger); + out << "connection exception:\n" << ex << '\n' << _desc; + } + } + } + + // + // We must set the new state before we notify requests of any + // exceptions. Otherwise new requests may retry on a connection + // that is not yet marked as closed or closing. + // + setState(state); +} + +void +Ice::ConnectionI::setState(State state) +{ + // + // We don't want to send close connection messages if the endpoint + // only supports oneway transmission from client to server. + // + if(_endpoint->datagram() && state == StateClosing) + { + state = StateClosed; + } + + // + // Skip graceful shutdown if we are destroyed before validation. + // + if(_state <= StateNotValidated && state == StateClosing) + { + state = StateClosed; + } + + if(_state == state) // Don't switch twice. + { + return; + } + + try + { + switch(state) + { + case StateNotInitialized: + { + assert(false); + break; + } + + case StateNotValidated: + { + if(_state != StateNotInitialized) + { + assert(_state == StateClosed); + return; + } + break; + } + + case StateActive: + { + // + // Can only switch from holding or not validated to + // active. + // + if(_state != StateHolding && _state != StateNotValidated) + { + return; + } + _threadPool->_register(ICE_SHARED_FROM_THIS, SocketOperationRead); + break; + } + + case StateHolding: + { + // + // Can only switch from active or not validated to + // holding. + // + if(_state != StateActive && _state != StateNotValidated) + { + return; + } + if(_state == StateActive) + { + _threadPool->unregister(ICE_SHARED_FROM_THIS, SocketOperationRead); + } + break; + } + + case StateClosing: + case StateClosingPending: + { + // + // Can't change back from closing pending. + // + if(_state >= StateClosingPending) + { + return; + } + break; + } + + case StateClosed: + { + if(_state == StateFinished) + { + return; + } + + _batchRequestQueue->destroy(*_exception); + + // + // Don't need to close now for connections so only close the transceiver + // if the selector request it. + // + if(_threadPool->finish(ICE_SHARED_FROM_THIS, false)) + { + _transceiver->close(); + } + break; + } + + case StateFinished: + { + assert(_state == StateClosed); + _communicator = 0; + break; + } + } + } + catch(const Ice::LocalException& ex) + { + Error out(_logger); + out << "unexpected connection exception:\n" << ex << '\n' << _desc; + } + + // + // We only register with the connection monitor if our new state + // is StateActive. Otherwise we unregister with the connection + // monitor, but only if we were registered before, i.e., if our + // old state was StateActive. + // + if(_monitor) + { + if(state == StateActive) + { + if(_acmLastActivity != IceUtil::Time()) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + _monitor->add(ICE_SHARED_FROM_THIS); + } + else if(_state == StateActive) + { + _monitor->remove(ICE_SHARED_FROM_THIS); + } + } + + if(_instance->initializationData().observer) + { + ConnectionState oldState = toConnectionState(_state); + ConnectionState newState = toConnectionState(state); + if(oldState != newState) + { + _observer.attach(_instance->initializationData().observer->getConnectionObserver(initConnectionInfo(), + _endpoint, + newState, + _observer.get())); + } + if(_observer && state == StateClosed && _exception) + { + if(!(dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + dynamic_cast(_exception.get()) || + (dynamic_cast(_exception.get()) && _state >= StateClosing))) + { + _observer->failed(_exception->ice_id()); + } + } + } + _state = state; + + notifyAll(); + + if(_state == StateClosing && _dispatchCount == 0) + { + try + { + initiateShutdown(); + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + } + } +} + +void +Ice::ConnectionI::initiateShutdown() +{ + assert(_state == StateClosing && _dispatchCount == 0); + + if(_shutdownInitiated) + { + return; + } + _shutdownInitiated = true; + + if(!_endpoint->datagram()) + { + // + // Before we shut down, we send a close connection message. + // + OutputStream os(_instance.get(), Ice::currentProtocolEncoding); + os.write(magic[0]); + os.write(magic[1]); + os.write(magic[2]); + os.write(magic[3]); + os.write(currentProtocol); + os.write(currentProtocolEncoding); + os.write(closeConnectionMsg); + os.write(static_cast(1)); // compression status: compression supported but not used. + os.write(headerSize); // Message size. + + OutgoingMessage message(&os, false); + if(sendMessage(message) & AsyncStatusSent) + { + setState(StateClosingPending); + + // + // Notify the transceiver of the graceful connection closure. + // + SocketOperation op = _transceiver->closing(true, *_exception); + if(op) + { + scheduleTimeout(op); + _threadPool->_register(ICE_SHARED_FROM_THIS, op); + } + } + } +} + +void +Ice::ConnectionI::sendHeartbeatNow() +{ + assert(_state == StateActive); + + if(!_endpoint->datagram()) + { + OutputStream os(_instance.get(), Ice::currentProtocolEncoding); + os.write(magic[0]); + os.write(magic[1]); + os.write(magic[2]); + os.write(magic[3]); + os.write(currentProtocol); + os.write(currentProtocolEncoding); + os.write(validateConnectionMsg); + os.write(static_cast(0)); // Compression status (always zero for validate connection). + os.write(headerSize); // Message size. + os.i = os.b.begin(); + try + { + OutgoingMessage message(&os, false); + sendMessage(message); + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); + assert(_exception); + } + } +} + +bool +Ice::ConnectionI::initialize(SocketOperation operation) +{ + SocketOperation s = _transceiver->initialize(_readStream, _writeStream); + if(s != SocketOperationNone) + { + scheduleTimeout(s); + _threadPool->update(ICE_SHARED_FROM_THIS, operation, s); + return false; + } + + // + // Update the connection description once the transceiver is initialized. + // + const_cast(_desc) = _transceiver->toString(); + _initialized = true; + setState(StateNotValidated); + return true; +} + +bool +Ice::ConnectionI::validate(SocketOperation operation) +{ + if(!_endpoint->datagram()) // Datagram connections are always implicitly validated. + { + if(_adapter) // The server side has the active role for connection validation. + { + if(_writeStream.b.empty()) + { + _writeStream.write(magic[0]); + _writeStream.write(magic[1]); + _writeStream.write(magic[2]); + _writeStream.write(magic[3]); + _writeStream.write(currentProtocol); + _writeStream.write(currentProtocolEncoding); + _writeStream.write(validateConnectionMsg); + _writeStream.write(static_cast(0)); // Compression status (always zero for validate connection). + _writeStream.write(headerSize); // Message size. + _writeStream.i = _writeStream.b.begin(); + traceSend(_writeStream, _logger, _traceLevels); + } + + if(_observer) + { + _observer.startWrite(_writeStream); + } + + if(_writeStream.i != _writeStream.b.end()) + { + SocketOperation op = write(_writeStream); + if(op) + { + scheduleTimeout(op); + _threadPool->update(ICE_SHARED_FROM_THIS, operation, op); + return false; + } + } + + if(_observer) + { + _observer.finishWrite(_writeStream); + } + } + else // The client side has the passive role for connection validation. + { + if(_readStream.b.empty()) + { + _readStream.b.resize(headerSize); + _readStream.i = _readStream.b.begin(); + } + + if(_observer) + { + _observer.startRead(_readStream); + } + + if(_readStream.i != _readStream.b.end()) + { + SocketOperation op = read(_readStream); + if(op) + { + scheduleTimeout(op); + _threadPool->update(ICE_SHARED_FROM_THIS, operation, op); + return false; + } + } + + if(_observer) + { + _observer.finishRead(_readStream); + } + + _validated = true; + + assert(_readStream.i == _readStream.b.end()); + _readStream.i = _readStream.b.begin(); + Byte m[4]; + _readStream.read(m[0]); + _readStream.read(m[1]); + _readStream.read(m[2]); + _readStream.read(m[3]); + if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3]) + { + throw BadMagicException(__FILE__, __LINE__, "", Ice::ByteSeq(&m[0], &m[0] + sizeof(magic))); + } + ProtocolVersion pv; + _readStream.read(pv); + checkSupportedProtocol(pv); + EncodingVersion ev; + _readStream.read(ev); + checkSupportedProtocolEncoding(ev); + Byte messageType; + _readStream.read(messageType); + if(messageType != validateConnectionMsg) + { + throw ConnectionNotValidatedException(__FILE__, __LINE__); + } + Byte compress; + _readStream.read(compress); // Ignore compression status for validate connection. + Int size; + _readStream.read(size); + if(size != headerSize) + { + throw IllegalMessageSizeException(__FILE__, __LINE__); + } + traceRecv(_readStream, _logger, _traceLevels); + } + } + + _writeStream.resize(0); + _writeStream.i = _writeStream.b.begin(); + + _readStream.resize(headerSize); + _readStream.i = _readStream.b.begin(); + _readHeader = true; + + if(_instance->traceLevels()->network >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + if(_endpoint->datagram()) + { + out << "starting to " << (_connector ? "send" : "receive") << " " << _endpoint->protocol() << " messages\n"; + out << _transceiver->toDetailedString(); + } + else + { + out << (_connector ? "established" : "accepted") << " " << _endpoint->protocol() << " connection\n"; + out << toString(); + } + } + + return true; +} + +SocketOperation +Ice::ConnectionI::sendNextMessage(vector& callbacks) +{ + if(_sendStreams.empty()) + { + return SocketOperationNone; + } + else if(_state == StateClosingPending && _writeStream.i == _writeStream.b.begin()) + { + // Message wasn't sent, empty the _writeStream, we're not going to send more data. + OutgoingMessage* message = &_sendStreams.front(); + _writeStream.swap(*message->stream); + return SocketOperationNone; + } + + assert(!_writeStream.b.empty() && _writeStream.i == _writeStream.b.end()); + try + { + while(true) + { + // + // Notify the message that it was sent. + // + OutgoingMessage* message = &_sendStreams.front(); + if(message->stream) + { + _writeStream.swap(*message->stream); + if(message->sent()) + { + callbacks.push_back(*message); + } + } + _sendStreams.pop_front(); + + // + // If there's nothing left to send, we're done. + // + if(_sendStreams.empty()) + { + break; + } + + // + // If we are in the closed state or if the close is + // pending, don't continue sending. + // + // This can occur if parseMessage (called before + // sendNextMessage by message()) closes the connection. + // + if(_state >= StateClosingPending) + { + return SocketOperationNone; + } + + // + // Otherwise, prepare the next message stream for writing. + // + message = &_sendStreams.front(); + assert(!message->stream->i); +#ifdef ICE_HAS_BZIP2 + if(message->compress && message->stream->b.size() >= 100) // Only compress messages > 100 bytes. + { + // + // Message compressed. Request compressed response, if any. + // + message->stream->b[9] = 2; + + // + // Do compression. + // + OutputStream stream(_instance.get(), Ice::currentProtocolEncoding); + doCompress(*message->stream, stream); + + traceSend(*message->stream, _logger, _traceLevels); + + message->adopt(&stream); // Adopt the compressed stream. + message->stream->i = message->stream->b.begin(); + } + else + { +#endif + if(message->compress) + { + // + // Message not compressed. Request compressed response, if any. + // + message->stream->b[9] = 1; + } + + // + // No compression, just fill in the message size. + // + Int sz = static_cast(message->stream->b.size()); + const Byte* p = reinterpret_cast(&sz); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), message->stream->b.begin() + 10); +#else + copy(p, p + sizeof(Int), message->stream->b.begin() + 10); +#endif + message->stream->i = message->stream->b.begin(); + traceSend(*message->stream, _logger, _traceLevels); + +#ifdef ICE_HAS_BZIP2 + } +#endif + _writeStream.swap(*message->stream); + + // + // Send the message. + // + if(_observer) + { + _observer.startWrite(_writeStream); + } + assert(_writeStream.i); + if(_writeStream.i != _writeStream.b.end()) + { + SocketOperation op = write(_writeStream); + if(op) + { + return op; + } + } + if(_observer) + { + _observer.finishWrite(_writeStream); + } + } + + // + // If all the messages were sent and we are in the closing state, we schedule + // the close timeout to wait for the peer to close the connection. + // + if(_state == StateClosing && _shutdownInitiated) + { + setState(StateClosingPending); + SocketOperation op = _transceiver->closing(true, *_exception); + if(op) + { + return op; + } + } + } + catch(const Ice::LocalException& ex) + { + setState(StateClosed, ex); + } + return SocketOperationNone; +} + +AsyncStatus +Ice::ConnectionI::sendMessage(OutgoingMessage& message) +{ + assert(_state < StateClosed); + + message.stream->i = 0; // Reset the message stream iterator before starting sending the message. + + if(!_sendStreams.empty()) + { + _sendStreams.push_back(message); + _sendStreams.back().adopt(0); + return AsyncStatusQueued; + } + + // + // Attempt to send the message without blocking. If the send blocks, we register + // the connection with the selector thread. + // + + message.stream->i = message.stream->b.begin(); + SocketOperation op; +#ifdef ICE_HAS_BZIP2 + if(message.compress && message.stream->b.size() >= 100) // Only compress messages larger than 100 bytes. + { + // + // Message compressed. Request compressed response, if any. + // + message.stream->b[9] = 2; + + // + // Do compression. + // + OutputStream stream(_instance.get(), Ice::currentProtocolEncoding); + doCompress(*message.stream, stream); + stream.i = stream.b.begin(); + + traceSend(*message.stream, _logger, _traceLevels); + + // + // Send the message without blocking. + // + if(_observer) + { + _observer.startWrite(stream); + } + op = write(stream); + if(!op) + { + if(_observer) + { + _observer.finishWrite(stream); + } + + AsyncStatus status = AsyncStatusSent; + if(message.sent()) + { + status = static_cast(status | AsyncStatusInvokeSentCallback); + } + if(_acmLastActivity != IceUtil::Time()) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + return status; + } + + _sendStreams.push_back(message); + _sendStreams.back().adopt(&stream); + } + else + { +#endif + if(message.compress) + { + // + // Message not compressed. Request compressed response, if any. + // + message.stream->b[9] = 1; + } + + // + // No compression, just fill in the message size. + // + Int sz = static_cast(message.stream->b.size()); + const Byte* p = reinterpret_cast(&sz); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), message.stream->b.begin() + 10); +#else + copy(p, p + sizeof(Int), message.stream->b.begin() + 10); +#endif + message.stream->i = message.stream->b.begin(); + + traceSend(*message.stream, _logger, _traceLevels); + + // + // Send the message without blocking. + // + if(_observer) + { + _observer.startWrite(*message.stream); + } + op = write(*message.stream); + if(!op) + { + if(_observer) + { + _observer.finishWrite(*message.stream); + } + AsyncStatus status = AsyncStatusSent; + if(message.sent()) + { + status = static_cast(status | AsyncStatusInvokeSentCallback); + } + if(_acmLastActivity != IceUtil::Time()) + { + _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + return status; + } + + _sendStreams.push_back(message); + _sendStreams.back().adopt(0); // Adopt the stream. +#ifdef ICE_HAS_BZIP2 + } +#endif + + _writeStream.swap(*_sendStreams.back().stream); + scheduleTimeout(op); + _threadPool->_register(ICE_SHARED_FROM_THIS, op); + return AsyncStatusQueued; +} + +#ifdef ICE_HAS_BZIP2 +static string +getBZ2Error(int bzError) +{ + if(bzError == BZ_RUN_OK) + { + return ": BZ_RUN_OK"; + } + else if(bzError == BZ_FLUSH_OK) + { + return ": BZ_FLUSH_OK"; + } + else if(bzError == BZ_FINISH_OK) + { + return ": BZ_FINISH_OK"; + } + else if(bzError == BZ_STREAM_END) + { + return ": BZ_STREAM_END"; + } + else if(bzError == BZ_CONFIG_ERROR) + { + return ": BZ_CONFIG_ERROR"; + } + else if(bzError == BZ_SEQUENCE_ERROR) + { + return ": BZ_SEQUENCE_ERROR"; + } + else if(bzError == BZ_PARAM_ERROR) + { + return ": BZ_PARAM_ERROR"; + } + else if(bzError == BZ_MEM_ERROR) + { + return ": BZ_MEM_ERROR"; + } + else if(bzError == BZ_DATA_ERROR) + { + return ": BZ_DATA_ERROR"; + } + else if(bzError == BZ_DATA_ERROR_MAGIC) + { + return ": BZ_DATA_ERROR_MAGIC"; + } + else if(bzError == BZ_IO_ERROR) + { + return ": BZ_IO_ERROR"; + } + else if(bzError == BZ_UNEXPECTED_EOF) + { + return ": BZ_UNEXPECTED_EOF"; + } + else if(bzError == BZ_OUTBUFF_FULL) + { + return ": BZ_OUTBUFF_FULL"; + } + else + { + return ""; + } +} + +void +Ice::ConnectionI::doCompress(OutputStream& uncompressed, OutputStream& compressed) +{ + const Byte* p; + + // + // Compress the message body, but not the header. + // + unsigned int uncompressedLen = static_cast(uncompressed.b.size() - headerSize); + unsigned int compressedLen = static_cast(uncompressedLen * 1.01 + 600); + compressed.b.resize(headerSize + sizeof(Int) + compressedLen); + int bzError = BZ2_bzBuffToBuffCompress(reinterpret_cast(&compressed.b[0]) + headerSize + sizeof(Int), + &compressedLen, + reinterpret_cast(&uncompressed.b[0]) + headerSize, + uncompressedLen, + _compressionLevel, 0, 0); + if(bzError != BZ_OK) + { + throw CompressionException(__FILE__, __LINE__, "BZ2_bzBuffToBuffCompress failed" + getBZ2Error(bzError)); + } + compressed.b.resize(headerSize + sizeof(Int) + compressedLen); + + // + // Write the size of the compressed stream into the header of the + // uncompressed stream. Since the header will be copied, this size + // will also be in the header of the compressed stream. + // + Int compressedSize = static_cast(compressed.b.size()); + p = reinterpret_cast(&compressedSize); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), uncompressed.b.begin() + 10); +#else + copy(p, p + sizeof(Int), uncompressed.b.begin() + 10); +#endif + + // + // Add the size of the uncompressed stream before the message body + // of the compressed stream. + // + Int uncompressedSize = static_cast(uncompressed.b.size()); + p = reinterpret_cast(&uncompressedSize); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), compressed.b.begin() + headerSize); +#else + copy(p, p + sizeof(Int), compressed.b.begin() + headerSize); +#endif + + // + // Copy the header from the uncompressed stream to the compressed one. + // + copy(uncompressed.b.begin(), uncompressed.b.begin() + headerSize, compressed.b.begin()); +} + +void +Ice::ConnectionI::doUncompress(InputStream& compressed, InputStream& uncompressed) +{ + Int uncompressedSize; + compressed.i = compressed.b.begin() + headerSize; + compressed.read(uncompressedSize); + if(uncompressedSize <= headerSize) + { + throw IllegalMessageSizeException(__FILE__, __LINE__); + } + + if(uncompressedSize > static_cast(_messageSizeMax)) + { + Ex::throwMemoryLimitException(__FILE__, __LINE__, static_cast(uncompressedSize), _messageSizeMax); + } + uncompressed.resize(static_cast(uncompressedSize)); + + unsigned int uncompressedLen = static_cast(uncompressedSize - headerSize); + unsigned int compressedLen = static_cast(compressed.b.size() - headerSize - sizeof(Int)); + int bzError = BZ2_bzBuffToBuffDecompress(reinterpret_cast(&uncompressed.b[0]) + headerSize, + &uncompressedLen, + reinterpret_cast(&compressed.b[0]) + headerSize + sizeof(Int), + compressedLen, + 0, 0); + if(bzError != BZ_OK) + { + throw CompressionException(__FILE__, __LINE__, "BZ2_bzBuffToBuffCompress failed" + getBZ2Error(bzError)); + } + + copy(compressed.b.begin(), compressed.b.begin() + headerSize, uncompressed.b.begin()); +} +#endif + +SocketOperation +Ice::ConnectionI::parseMessage(InputStream& stream, Int& invokeNum, Int& requestId, Byte& compress, + ServantManagerPtr& servantManager, ObjectAdapterPtr& adapter, + OutgoingAsyncBasePtr& outAsync, ICE_DELEGATE(HeartbeatCallback)& heartbeatCallback, + int& dispatchCount) +{ + assert(_state > StateNotValidated && _state < StateClosed); + + _readStream.swap(stream); + _readStream.resize(headerSize); + _readStream.i = _readStream.b.begin(); + _readHeader = true; + + assert(stream.i == stream.b.end()); + + try + { + // + // We don't need to check magic and version here. This has + // already been done by the ThreadPool, which provides us + // with the stream. + // + assert(stream.i == stream.b.end()); + stream.i = stream.b.begin() + 8; + Byte messageType; + stream.read(messageType); + stream.read(compress); + + if(compress == 2) + { +#ifdef ICE_HAS_BZIP2 + InputStream ustream(_instance.get(), Ice::currentProtocolEncoding); + doUncompress(stream, ustream); + stream.b.swap(ustream.b); +#else + throw FeatureNotSupportedException(__FILE__, __LINE__, "Cannot uncompress compressed message"); +#endif + } + stream.i = stream.b.begin() + headerSize; + + switch(messageType) + { + case closeConnectionMsg: + { + traceRecv(stream, _logger, _traceLevels); + if(_endpoint->datagram()) + { + if(_warn) + { + Warning out(_logger); + out << "ignoring close connection message for datagram connection:\n" << _desc; + } + } + else + { + setState(StateClosingPending, CloseConnectionException(__FILE__, __LINE__)); + + // + // Notify the transceiver of the graceful connection closure. + // + SocketOperation op = _transceiver->closing(false, *_exception); + if(op) + { + return op; + } + setState(StateClosed); + } + break; + } + + case requestMsg: + { + if(_state >= StateClosing) + { + trace("received request during closing\n(ignored by server, client will retry)", stream, _logger, + _traceLevels); + } + else + { + traceRecv(stream, _logger, _traceLevels); + stream.read(requestId); + invokeNum = 1; + servantManager = _servantManager; + adapter = _adapter; + ++dispatchCount; + } + break; + } + + case requestBatchMsg: + { + if(_state >= StateClosing) + { + trace("received batch request during closing\n(ignored by server, client will retry)", stream, + _logger, _traceLevels); + } + else + { + traceRecv(stream, _logger, _traceLevels); + stream.read(invokeNum); + if(invokeNum < 0) + { + invokeNum = 0; + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + servantManager = _servantManager; + adapter = _adapter; + dispatchCount += invokeNum; + } + break; + } + + case replyMsg: + { + traceRecv(stream, _logger, _traceLevels); + + stream.read(requestId); + + map::iterator q = _asyncRequests.end(); + + if(_asyncRequestsHint != _asyncRequests.end()) + { + if(_asyncRequestsHint->first == requestId) + { + q = _asyncRequestsHint; + } + } + + if(q == _asyncRequests.end()) + { + q = _asyncRequests.find(requestId); + } + + if(q != _asyncRequests.end()) + { + outAsync = q->second; + + if(q == _asyncRequestsHint) + { + _asyncRequests.erase(q++); + _asyncRequestsHint = q; + } + else + { + _asyncRequests.erase(q); + } + + stream.swap(*outAsync->getIs()); + +#if defined(ICE_USE_IOCP) + // + // If we just received the reply of a request which isn't acknowledge as + // sent yet, we queue the reply instead of processing it right away. It + // will be processed once the write callback is invoked for the message. + // + OutgoingMessage* message = _sendStreams.empty() ? 0 : &_sendStreams.front(); + if(message && message->outAsync.get() == outAsync.get()) + { + message->receivedReply = true; + outAsync = 0; + } + else if(outAsync->response()) + { + ++dispatchCount; + } + else + { + outAsync = 0; + } +#else + if(outAsync->response()) + { + ++dispatchCount; + } + else + { + outAsync = 0; + } +#endif + notifyAll(); // Notify threads blocked in close(false) + } + + break; + } + + case validateConnectionMsg: + { + traceRecv(stream, _logger, _traceLevels); + if(_heartbeatCallback) + { + heartbeatCallback = _heartbeatCallback; + ++dispatchCount; + } + break; + } + + default: + { + trace("received unknown message\n(invalid, closing connection)", stream, _logger, _traceLevels); + throw UnknownMessageException(__FILE__, __LINE__); + } + } + } + catch(const LocalException& ex) + { + if(_endpoint->datagram()) + { + if(_warn) + { + Warning out(_logger); + out << "datagram connection exception:\n" << ex << '\n' << _desc; + } + } + else + { + setState(StateClosed, ex); + } + } + + return _state == StateHolding ? SocketOperationNone : SocketOperationRead; +} + +void +Ice::ConnectionI::invokeAll(InputStream& stream, Int invokeNum, Int requestId, Byte compress, + const ServantManagerPtr& servantManager, const ObjectAdapterPtr& adapter) +{ + // + // Note: In contrast to other private or protected methods, this + // operation must be called *without* the mutex locked. + // + + try + { + while(invokeNum > 0) + { + // + // Prepare the invocation. + // + bool response = !_endpoint->datagram() && requestId != 0; + assert(!response || invokeNum == 1); + + Incoming in(_instance.get(), this, this, adapter, response, compress, requestId); + + // + // Dispatch the invocation. + // + in.invoke(servantManager, &stream); + + --invokeNum; + } + + stream.clear(); + } + catch(const LocalException& ex) + { + invokeException(requestId, ex, invokeNum, false); // Fatal invocation exception + } +} + +void +Ice::ConnectionI::scheduleTimeout(SocketOperation status) +{ + int timeout; + if(_state < StateActive) + { + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideConnectTimeout) + { + timeout = defaultsAndOverrides->overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint->timeout(); + } + } + else if(_state < StateClosingPending) + { + if(_readHeader) // No timeout for reading the header. + { + status = static_cast(status & ~SocketOperationRead); + } + timeout = _endpoint->timeout(); + } + else + { + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideCloseTimeout) + { + timeout = defaultsAndOverrides->overrideCloseTimeoutValue; + } + else + { + timeout = _endpoint->timeout(); + } + } + + if(timeout < 0) + { + return; + } + + try + { + if(status & IceInternal::SocketOperationRead) + { + if(_readTimeoutScheduled) + { + _timer->cancel(_readTimeout); + } + _timer->schedule(_readTimeout, IceUtil::Time::milliSeconds(timeout)); + _readTimeoutScheduled = true; + } + if(status & (IceInternal::SocketOperationWrite | IceInternal::SocketOperationConnect)) + { + if(_writeTimeoutScheduled) + { + _timer->cancel(_writeTimeout); + } + _timer->schedule(_writeTimeout, IceUtil::Time::milliSeconds(timeout)); + _writeTimeoutScheduled = true; + } + } + catch(const IceUtil::Exception&) + { + assert(false); + } +} + +void +Ice::ConnectionI::unscheduleTimeout(SocketOperation status) +{ + if((status & IceInternal::SocketOperationRead) && _readTimeoutScheduled) + { + _timer->cancel(_readTimeout); + _readTimeoutScheduled = false; + } + if((status & (IceInternal::SocketOperationWrite | IceInternal::SocketOperationConnect)) && + _writeTimeoutScheduled) + { + _timer->cancel(_writeTimeout); + _writeTimeoutScheduled = false; + } +} + +Ice::ConnectionInfoPtr +Ice::ConnectionI::initConnectionInfo() const +{ + if(_state > StateNotInitialized && _info) // Update the connection information until it's initialized + { + return _info; + } + + try + { + _info = _transceiver->getInfo(); + } + catch(const Ice::LocalException&) + { + _info = ICE_MAKE_SHARED(ConnectionInfo); + } + + Ice::ConnectionInfoPtr info = _info; + while(info) + { + info->connectionId = _endpoint->connectionId(); + info->incoming = _connector == 0; + info->adapterName = _adapter ? _adapter->getName() : string(); + info = info->underlying; + } + return _info; +} + +ConnectionState +ConnectionI::toConnectionState(State state) const +{ + return connectionStateMap[static_cast(state)]; +} + +SocketOperation +ConnectionI::read(Buffer& buf) +{ + Buffer::Container::iterator start = buf.i; + SocketOperation op = _transceiver->read(buf); + if(_instance->traceLevels()->network >= 3 && buf.i != start) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "received "; + if(_endpoint->datagram()) + { + out << buf.b.size(); + } + else + { + out << (buf.i - start) << " of " << (buf.b.end() - start); + } + out << " bytes via " << _endpoint->protocol() << "\n" << toString(); + } + return op; +} + +SocketOperation +ConnectionI::write(Buffer& buf) +{ + Buffer::Container::iterator start = buf.i; + SocketOperation op = _transceiver->write(buf); + if(_instance->traceLevels()->network >= 3 && buf.i != start) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "sent " << (buf.i - start); + if(!_endpoint->datagram()) + { + out << " of " << (buf.b.end() - start); + } + out << " bytes via " << _endpoint->protocol() << "\n" << toString(); + } + return op; +} + +void +ConnectionI::reap() +{ + if(_monitor) + { + _monitor->reap(ICE_SHARED_FROM_THIS); + } + if(_observer) + { + _observer.detach(); + } +} diff --git a/Sources/IceCpp/ConnectionInfo.cpp b/Sources/IceCpp/ConnectionInfo.cpp new file mode 100644 index 0000000..9481998 --- /dev/null +++ b/Sources/IceCpp/ConnectionInfo.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICEIAP_API_EXPORTS +# define ICEIAP_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +IceIAP::ConnectionInfo::~ConnectionInfo() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +IceIAP::ConnectionInfo::~ConnectionInfo() +{ +} + +/// \cond INTERNAL +ICEIAP_API ::Ice::LocalObject* IceIAP::upCast(ConnectionInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ConnectionRequestHandler.cpp b/Sources/IceCpp/ConnectionRequestHandler.cpp new file mode 100644 index 0000000..cb5055f --- /dev/null +++ b/Sources/IceCpp/ConnectionRequestHandler.cpp @@ -0,0 +1,73 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace IceInternal; + +ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference, + const Ice::ConnectionIPtr& connection, + bool compress) : + RequestHandler(reference), + _connection(connection), + _compress(compress) +{ +} + +RequestHandlerPtr +ConnectionRequestHandler::update(const RequestHandlerPtr& previousHandler, const RequestHandlerPtr& newHandler) +{ + assert(previousHandler); + try + { + if(previousHandler.get() == this) + { + return newHandler; + } + else if(previousHandler->getConnection() == _connection) + { + // + // If both request handlers point to the same connection, we also + // update the request handler. See bug ICE-5489 for reasons why + // this can be useful. + // + return newHandler; + } + } + catch(const Ice::Exception&) + { + // Ignore. + } + return ICE_SHARED_FROM_THIS; +} + +AsyncStatus +ConnectionRequestHandler::sendAsyncRequest(const ProxyOutgoingAsyncBasePtr& out) +{ + return out->invokeRemote(_connection, _compress, _response); +} + +void +ConnectionRequestHandler::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, const Ice::LocalException& ex) +{ + _connection->asyncRequestCanceled(outAsync, ex); +} + +Ice::ConnectionIPtr +ConnectionRequestHandler::getConnection() +{ + return _connection; +} + +Ice::ConnectionIPtr +ConnectionRequestHandler::waitForConnection() +{ + return _connection; +} diff --git a/Sources/IceCpp/Connector.cpp b/Sources/IceCpp/Connector.cpp new file mode 100644 index 0000000..0d9739d --- /dev/null +++ b/Sources/IceCpp/Connector.cpp @@ -0,0 +1,16 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Connector::~Connector() +{ + // Out of line to avoid weak vtable +} + +IceUtil::Shared* IceInternal::upCast(Connector* p) { return p; } diff --git a/Sources/IceCpp/ConsoleUtil.cpp b/Sources/IceCpp/ConsoleUtil.cpp new file mode 100644 index 0000000..462a074 --- /dev/null +++ b/Sources/IceCpp/ConsoleUtil.cpp @@ -0,0 +1,157 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace IceUtilInternal; +using namespace std; + +#if defined(_WIN32) +namespace +{ + +IceUtil::Mutex* consoleMutex = 0; +ConsoleUtil* consoleUtil = 0; + +class Init +{ +public: + + Init() + { + consoleMutex = new IceUtil::Mutex; + } + + ~Init() + { + // + // We leak consoleUtil object to ensure that is available + // during static destruction. + // + //delete consoleUtil; + //consoleUtil = 0; + delete consoleMutex; + consoleMutex = 0; + } +}; + +Init init; + +} + +const ConsoleUtil& +IceUtilInternal::getConsoleUtil() +{ + IceUtilInternal::MutexPtrLock sync(consoleMutex); + if(consoleUtil == 0) + { + consoleUtil = new ConsoleUtil(); + } + return *consoleUtil; +} + +ConsoleOut IceUtilInternal::consoleOut; +ConsoleErr IceUtilInternal::consoleErr; + +ConsoleUtil::ConsoleUtil() : + _converter(IceUtil::getProcessStringConverter()), + _consoleConverter(IceUtil::createWindowsStringConverter(GetConsoleOutputCP())) +{ +} + +string +ConsoleUtil::toConsoleEncoding(const string& message) const +{ + try + { + // Convert message to UTF-8 + string u8s = nativeToUTF8(message, _converter); + + // Then from UTF-8 to console CP + string consoleString; + _consoleConverter->fromUTF8(reinterpret_cast (u8s.data()), + reinterpret_cast(u8s.data() + u8s.size()), + consoleString); + + return consoleString; + } + catch(const IceUtil::IllegalConversionException&) + { + // + // If there is a problem with the encoding conversions we just + // return the original message without encoding conversions. + // + return message; + } +} + +void +ConsoleUtil::output(const string& message) const +{ + // + // Use fprintf_s to avoid encoding conversion when stderr is connected + // to Windows console. + // + fprintf_s(stdout, "%s", toConsoleEncoding(message).c_str()); +} + +void +ConsoleUtil::error(const string& message) const +{ + // + // Use fprintf_s to avoid encoding conversion when stderr is connected + // to Windows console. + // + fprintf_s(stderr, "%s", toConsoleEncoding(message).c_str()); +} + +ConsoleOut& +IceUtilInternal::endl(ConsoleOut& out) +{ + fprintf_s(stdout, "\n"); + fflush(stdout); + return out; +} + +ConsoleOut& +IceUtilInternal::flush(ConsoleOut& out) +{ + fflush(stdout); + return out; +} + +ConsoleOut& +ConsoleOut::operator<<(ConsoleOut& (*pf)(ConsoleOut&)) +{ + pf(*this); + return *this; +} + +ConsoleErr& +IceUtilInternal::endl(ConsoleErr& err) +{ + fprintf_s(stderr, "\n"); + fflush(stderr); + return err; +} + +ConsoleErr& +IceUtilInternal::flush(ConsoleErr& err) +{ + fflush(stderr); + return err; +} + +ConsoleErr& +ConsoleErr::operator<<(ConsoleErr& (*pf)(ConsoleErr&)) +{ + pf(*this); + return *this; +} +#else +std::ostream& IceUtilInternal::consoleOut = cout; +std::ostream& IceUtilInternal::consoleErr = cerr; +#endif diff --git a/Sources/IceCpp/ConvertUTF.cpp b/Sources/IceCpp/ConvertUTF.cpp new file mode 100644 index 0000000..6beed68 --- /dev/null +++ b/Sources/IceCpp/ConvertUTF.cpp @@ -0,0 +1,472 @@ +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Source code file. + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Sept 2001: fixed const & error conditions per + mods suggested by S. Parent & A. Lillich. + June 2002: Tim Dodd added detection and handling of incomplete + source sequences, enhanced error detection, added casts + to eliminate compiler warnings. + July 2003: slight mods to back out aggressive FFFE detection. + Jan 2004: updated switches in from-UTF8 conversions. + Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. + + See the header file "ConvertUTF.h" for complete documentation. + +------------------------------------------------------------------------ */ + +#include + +#ifndef ICE_HAS_CODECVT_UTF8 +// +// It's better to exclude the file from the build, but it's not always +// easy to do. +// + +#include + +#ifdef CVTUTF_DEBUG +#include +#endif + +using namespace IceUtil; + +#ifdef __GNUC__ +//# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wold-style-cast" +#endif + +namespace IceUtilInternal +{ + +const int halfShift = 10; /* used for shifting by 10 bits */ + +const UTF32 halfBase = 0x0010000UL; +const UTF32 halfMask = 0x3FFUL; + +#define UNI_SUR_HIGH_START (UTF32)0xD800 +#define UNI_SUR_HIGH_END (UTF32)0xDBFF +#define UNI_SUR_LOW_START (UTF32)0xDC00 +#define UNI_SUR_LOW_END (UTF32)0xDFFF +// #define false 0 +// #define true 1 + +/* --------------------------------------------------------------------- */ + +/* + * Index into the table below with the first byte of a UTF-8 sequence to + * get the number of trailing bytes that are supposed to follow it. + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is + * left as-is for anyone who may want to do such conversion, which was + * allowed in earlier algorithms. + */ +const char trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +/* + * Magic values subtracted from a buffer value during UTF8 conversion. + * This table contains as many values as there might be trailing bytes + * in a UTF-8 sequence. + */ +const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; + +/* + * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed + * into the first byte, depending on how many bytes follow. There are + * as many entries in this table as there are UTF-8 sequence types. + * (I.e., one byte sequence, two byte... etc.). Remember that sequencs + * for *legal* UTF-8 will be 4 or fewer bytes total. + */ +const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +/* --------------------------------------------------------------------- */ + +/* The interface converts a whole buffer to avoid function-call overhead. + * Constants have been gathered. Loops & conditionals have been removed as + * much as possible for efficiency, in favor of drop-through switches. + * (See "Note A" at the bottom of the file for equivalent code.) + * If your compiler supports it, the "isLegalUTF8" call can be turned + * into an inline function. + */ + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF16toUTF8 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF16* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { + /* If the 16 bits following the high surrogate are in the source buffer... */ + if (source < sourceEnd) { + UTF32 ch2 = *source; + /* If it's a low surrogate, convert to UTF32. */ + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++source; + } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else { /* We don't have the 16 bits following the high surrogate. */ + --source; /* return to the high surrogate */ + result = sourceExhausted; + break; + } + } else if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* Figure out how many bytes the result will require */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; + } else { bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) { + source = oldSource; /* Back up source pointer! */ + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Utility routine to tell whether a sequence of bytes is legal UTF-8. + * This must be called with the length pre-determined by the first byte. + * If not calling this from ConvertUTF8to*, then the length can be set by: + * length = trailingBytesForUTF8[*source]+1; + * and the sequence is illegal right away if there aren't that many bytes + * available. + * If presented with a length > 4, this returns false. The Unicode + * definition of UTF-8 goes up to 4-byte sequences. + */ + +Boolean isLegalUTF8(const UTF8 *source, int length) { + UTF8 a; + const UTF8 *srcptr = source+length; + switch (length) { + default: return false; + /* Everything else falls through when "true"... */ + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 2: if ((a = (*--srcptr)) > 0xBF) return false; + + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: if (a < 0xA0) return false; break; + case 0xED: if (a > 0x9F) return false; break; + case 0xF0: if (a < 0x90) return false; break; + case 0xF4: if (a > 0x8F) return false; break; + default: if (a < 0x80) return false; + } + + case 1: if (*source >= 0x80 && *source < 0xC2) return false; + } + if (*source > 0xF4) return false; + return true; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF8toUTF16 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF8* source = *sourceStart; + UTF16* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (! isLegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up source pointer! */ + result = targetExhausted; break; + } + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = (UTF16)ch; /* normal case */ + } + } else if (ch > UNI_MAX_UTF16) { + if (flags == strictConversion) { + result = sourceIllegal; + source -= (extraBytesToRead+1); /* return to the start */ + break; /* Bail out; shouldn't continue */ + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up source pointer! */ + result = targetExhausted; break; + } + ch -= halfBase; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF32toUTF8 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF32* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + ch = *source++; + if (flags == strictConversion ) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* + * Figure out how many bytes the result will require. Turn any + * illegally large UTF32 things (> Plane 17) into replacement chars. + */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; + } else { bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + result = sourceIllegal; + } + + target += bytesToWrite; + if (target > targetEnd) { + --source; /* Back up source pointer! */ + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF8toUTF32 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF8* source = *sourceStart; + UTF32* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (! isLegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; + case 4: ch += *source++; ch <<= 6; + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up the source pointer! */ + result = targetExhausted; break; + } + if (ch <= UNI_MAX_LEGAL_UTF32) { + /* + * UTF-16 surrogate values are illegal in UTF-32, and anything + * over Plane 17 (> 0x10FFFF) is illegal. + */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = ch; + } + } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ + result = sourceIllegal; + *target++ = UNI_REPLACEMENT_CHAR; + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- + + Note A. + The fall-through switches in UTF-8 reading code save a + temp variable, some decrements & conditionals. The switches + are equivalent to the following loop: + { + int tmpBytesToRead = extraBytesToRead+1; + do { + ch += *source++; + --tmpBytesToRead; + if (tmpBytesToRead) ch <<= 6; + } while (tmpBytesToRead > 0); + } + In UTF-8 writing code, the switches on "bytesToWrite" are + similarly unrolled loops. + + --------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------- */ + +/* + * Exported function to return whether a UTF-8 sequence is legal or not. + * This is not used here; it's just exported. + */ +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { + if(source == sourceEnd) { + return true; + } + while(true) { + int length = trailingBytesForUTF8[*source]+1; + // Is buffer big enough to contain character? + if (source+length > sourceEnd) { + return false; + } + // Is character legal UTF8? + if(!isLegalUTF8(source, length)) { + return false; + } + // Are we at end of buffer? + source += length; + if(source == sourceEnd) { + return true; + } + } +} +} + +#endif diff --git a/Sources/IceCpp/CountDownLatch.cpp b/Sources/IceCpp/CountDownLatch.cpp new file mode 100644 index 0000000..221e2a3 --- /dev/null +++ b/Sources/IceCpp/CountDownLatch.cpp @@ -0,0 +1,171 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +IceUtilInternal::CountDownLatch::CountDownLatch(int count) : + _count(count) +{ + if(count < 0) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "count must be greather than 0"); + } + +#ifdef _WIN32 + _event = CreateEvent(0, TRUE, FALSE, 0); + if(_event == 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +#else + int rc = pthread_mutex_init(&_mutex, 0); + if(rc != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } + + rc = pthread_cond_init(&_cond, 0); + if(rc != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } +#endif +} + +IceUtilInternal::CountDownLatch::~CountDownLatch() +{ +#ifdef _WIN32 + CloseHandle(_event); +#else +# ifndef NDEBUG + int rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); + rc = pthread_cond_destroy(&_cond); + assert(rc == 0); +# else + pthread_mutex_destroy(&_mutex); + pthread_cond_destroy(&_cond); +# endif +#endif +} + +void +IceUtilInternal::CountDownLatch::await() const +{ +#ifdef _WIN32 + while(InterlockedExchangeAdd(&_count, 0) > 0) + { + DWORD rc = WaitForSingleObject(_event, INFINITE); + assert(rc == WAIT_OBJECT_0 || rc == WAIT_FAILED); + + if(rc == WAIT_FAILED) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + } +#else + lock(); + while(_count > 0) + { + int rc = pthread_cond_wait(&_cond, &_mutex); + if(rc != 0) + { + pthread_mutex_unlock(&_mutex); + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + unlock(); + +#endif +} + +void +IceUtilInternal::CountDownLatch::countDown() +{ +#ifdef _WIN32 + if(InterlockedDecrement(&_count) == 0) + { + if(SetEvent(_event) == 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + } +#else + bool broadcast = false; + + lock(); + if(_count > 0 && --_count == 0) + { + broadcast = true; + } +#if defined(__APPLE__) + // + // On macOS we do the broadcast with the mutex held. This seems to + // be necessary to prevent the broadcast call to hang (spinning in + // an infinite loop). + // + if(broadcast) + { + int rc = pthread_cond_broadcast(&_cond); + if(rc != 0) + { + pthread_mutex_unlock(&_mutex); + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + unlock(); + +#else + unlock(); + + if(broadcast) + { + int rc = pthread_cond_broadcast(&_cond); + if(rc != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } + } +#endif + +#endif +} + +int +IceUtilInternal::CountDownLatch::getCount() const +{ +#ifdef _WIN32 + int count = InterlockedExchangeAdd(&_count, 0); + return count > 0 ? count : 0; +#else + lock(); + int result = _count; + unlock(); + return result; +#endif +} + +#ifndef _WIN32 +void +IceUtilInternal::CountDownLatch::lock() const +{ + int rc = pthread_mutex_lock(&_mutex); + if(rc != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +void +IceUtilInternal::CountDownLatch::unlock() const +{ + int rc = pthread_mutex_unlock(&_mutex); + if(rc != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +#endif diff --git a/Sources/IceCpp/CtrlCHandler.cpp b/Sources/IceCpp/CtrlCHandler.cpp new file mode 100644 index 0000000..eae9ce1 --- /dev/null +++ b/Sources/IceCpp/CtrlCHandler.cpp @@ -0,0 +1,259 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifdef __sun +# define _POSIX_PTHREAD_SEMANTICS +#endif + +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +using namespace std; +using namespace IceUtil; + +namespace +{ + +CtrlCHandlerCallback _callback = ICE_NULLPTR; + +const CtrlCHandler* _handler = 0; + +IceUtil::Mutex* globalMutex = 0; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +} + +CtrlCHandlerException::CtrlCHandlerException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +string +CtrlCHandlerException::ice_id() const +{ + return "::IceUtil::CtrlCHandlerException"; +} + +#ifndef ICE_CPP11_MAPPING +CtrlCHandlerException* +CtrlCHandlerException::ice_clone() const +{ + return new CtrlCHandlerException(*this); +} +#endif + +CtrlCHandlerCallback +CtrlCHandler::setCallback(CtrlCHandlerCallback callback) +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + CtrlCHandlerCallback oldCallback = _callback; + _callback = callback; + return oldCallback; +} + +CtrlCHandlerCallback +CtrlCHandler::getCallback() const +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + return _callback; +} + +#ifdef _WIN32 + +static BOOL WINAPI handlerRoutine(DWORD dwCtrlType) +{ + CtrlCHandlerCallback callback; + { + IceUtilInternal::MutexPtrLock lock(globalMutex); + if(!_handler) // The handler is destroyed. + { + return FALSE; + } + callback = _callback; + } + if(callback) + { + callback(dwCtrlType); + } + return TRUE; +} + +CtrlCHandler::CtrlCHandler(CtrlCHandlerCallback callback) +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + bool handler = _handler != 0; + + if(handler) + { + throw CtrlCHandlerException(__FILE__, __LINE__); + } + else + { + _callback = callback; + _handler = this; + lock.release(); + + SetConsoleCtrlHandler(handlerRoutine, TRUE); + } +} + +CtrlCHandler::~CtrlCHandler() +{ + SetConsoleCtrlHandler(handlerRoutine, FALSE); + { + IceUtilInternal::MutexPtrLock lock(globalMutex); + _handler = 0; + _callback = ICE_NULLPTR; + } +} + +#else + +extern "C" +{ + +static void* +sigwaitThread(void*) +{ + sigset_t ctrlCLikeSignals; + sigemptyset(&ctrlCLikeSignals); + sigaddset(&ctrlCLikeSignals, SIGHUP); + sigaddset(&ctrlCLikeSignals, SIGINT); + sigaddset(&ctrlCLikeSignals, SIGTERM); + + // + // Run until the handler is destroyed (_handler == 0) + // + for(;;) + { + int signal = 0; + int rc = sigwait(&ctrlCLikeSignals, &signal); + if(rc == EINTR) + { + // + // Some sigwait() implementations incorrectly return EINTR + // when interrupted by an unblocked caught signal + // + continue; + } + assert(rc == 0); + + CtrlCHandlerCallback callback; + { + IceUtilInternal::MutexPtrLock lock(globalMutex); + if(!_handler) // The handler is destroyed. + { + return 0; + } + callback = _callback; + } + + if(callback) + { + callback(signal); + } + } + return 0; +} + +} + +namespace +{ + +pthread_t _tid; + +} + +CtrlCHandler::CtrlCHandler(CtrlCHandlerCallback callback) +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + bool handler = _handler != 0; + + if(handler) + { + throw CtrlCHandlerException(__FILE__, __LINE__); + } + else + { + _callback = callback; + _handler = this; + + lock.release(); + + // We block these CTRL+C like signals in the main thread, + // and by default all other threads will inherit this signal + // mask. + + sigset_t ctrlCLikeSignals; + sigemptyset(&ctrlCLikeSignals); + sigaddset(&ctrlCLikeSignals, SIGHUP); + sigaddset(&ctrlCLikeSignals, SIGINT); + sigaddset(&ctrlCLikeSignals, SIGTERM); + +#ifndef NDEBUG + int rc = pthread_sigmask(SIG_BLOCK, &ctrlCLikeSignals, 0); + assert(rc == 0); + + // Joinable thread + rc = pthread_create(&_tid, 0, sigwaitThread, 0); + assert(rc == 0); +#else + pthread_sigmask(SIG_BLOCK, &ctrlCLikeSignals, 0); + + // Joinable thread + pthread_create(&_tid, 0, sigwaitThread, 0); +#endif + } +} + +CtrlCHandler::~CtrlCHandler() +{ + // + // Clear the handler, the sigwaitThread will exit if _handler is null + // + { + IceUtilInternal::MutexPtrLock lock(globalMutex); + _handler = 0; + _callback = ICE_NULLPTR; + } + + // + // Signal the sigwaitThread and join it. + // + void* status = 0; +#ifndef NDEBUG + int rc = pthread_kill(_tid, SIGTERM); + assert(rc == 0); + rc = pthread_join(_tid, &status); + assert(rc == 0); +#else + pthread_kill(_tid, SIGTERM); + pthread_join(_tid, &status); +#endif +} + +#endif diff --git a/Sources/IceCpp/Current.cpp b/Sources/IceCpp/Current.cpp new file mode 100644 index 0000000..d71af96 --- /dev/null +++ b/Sources/IceCpp/Current.cpp @@ -0,0 +1,62 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Current.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/DefaultsAndOverrides.cpp b/Sources/IceCpp/DefaultsAndOverrides.cpp new file mode 100644 index 0000000..56fa938 --- /dev/null +++ b/Sources/IceCpp/DefaultsAndOverrides.cpp @@ -0,0 +1,159 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(DefaultsAndOverrides* p) { return p; } + +IceInternal::DefaultsAndOverrides::DefaultsAndOverrides(const PropertiesPtr& properties, const LoggerPtr& logger) : + overrideTimeout(false), + overrideTimeoutValue(-1), + overrideConnectTimeout(false), + overrideConnectTimeoutValue(-1), + overrideCloseTimeout(false), + overrideCloseTimeoutValue(-1), + overrideCompress(false), + overrideCompressValue(false), + overrideSecure(false), + overrideSecureValue(false) +{ + const_cast(defaultProtocol) = properties->getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + + const_cast(defaultHost) = properties->getProperty("Ice.Default.Host"); + + string value; + + value = properties->getProperty("Ice.Default.SourceAddress"); + if(!value.empty()) + { + const_cast(defaultSourceAddress) = getNumericAddress(value); + if(!isAddressValid(defaultSourceAddress)) + { + throw InitializationException(__FILE__, __LINE__, "invalid IP address set for Ice.Default.SourceAddress: `" + + value + "'"); + } + } + + value = properties->getProperty("Ice.Override.Timeout"); + if(!value.empty()) + { + const_cast(overrideTimeout) = true; + const_cast(overrideTimeoutValue) = properties->getPropertyAsInt("Ice.Override.Timeout"); + if(overrideTimeoutValue < 1 && overrideTimeoutValue != -1) + { + const_cast(overrideTimeoutValue) = -1; + Warning out(logger); + out << "invalid value for Ice.Override.Timeout `" << properties->getProperty("Ice.Override.Timeout") + << "': defaulting to -1"; + } + } + + value = properties->getProperty("Ice.Override.ConnectTimeout"); + if(!value.empty()) + { + const_cast(overrideConnectTimeout) = true; + const_cast(overrideConnectTimeoutValue) = properties->getPropertyAsInt("Ice.Override.ConnectTimeout"); + if(overrideConnectTimeoutValue < 1 && overrideConnectTimeoutValue != -1) + { + const_cast(overrideConnectTimeoutValue) = -1; + Warning out(logger); + out << "invalid value for Ice.Override.ConnectTimeout `" + << properties->getProperty("Ice.Override.ConnectTimeout") << "': defaulting to -1"; + } + } + + value = properties->getProperty("Ice.Override.CloseTimeout"); + if(!value.empty()) + { + const_cast(overrideCloseTimeout) = true; + const_cast(overrideCloseTimeoutValue) = properties->getPropertyAsInt("Ice.Override.CloseTimeout"); + if(overrideCloseTimeoutValue < 1 && overrideCloseTimeoutValue != -1) + { + const_cast(overrideCloseTimeoutValue) = -1; + Warning out(logger); + out << "invalid value for Ice.Override.CloseTimeout `" + << properties->getProperty("Ice.Override.CloseTimeout") << "': defaulting to -1"; + } + } + + value = properties->getProperty("Ice.Override.Compress"); + if(!value.empty()) + { + const_cast(overrideCompress) = true; + const_cast(overrideCompressValue) = properties->getPropertyAsInt("Ice.Override.Compress") > 0; + } + + value = properties->getProperty("Ice.Override.Secure"); + if(!value.empty()) + { + const_cast(overrideSecure) = true; + const_cast(overrideSecureValue) = properties->getPropertyAsInt("Ice.Override.Secure") > 0; + } + + const_cast(defaultCollocationOptimization) = + properties->getPropertyAsIntWithDefault("Ice.Default.CollocationOptimized", 1) > 0; + + value = properties->getPropertyWithDefault("Ice.Default.EndpointSelection", "Random"); + if(value == "Random") + { + defaultEndpointSelection = ICE_ENUM(EndpointSelectionType, Random); + } + else if(value == "Ordered") + { + defaultEndpointSelection = ICE_ENUM(EndpointSelectionType, Ordered); + } + else + { + throw EndpointSelectionTypeParseException(__FILE__, __LINE__, "illegal value `" + value + + "'; expected `Random' or `Ordered'"); + } + + const_cast(defaultTimeout) = + properties->getPropertyAsIntWithDefault("Ice.Default.Timeout", 60000); + if(defaultTimeout < 1 && defaultTimeout != -1) + { + const_cast(defaultTimeout) = 60000; + Warning out(logger); + out << "invalid value for Ice.Default.Timeout `" << properties->getProperty("Ice.Default.Timeout") + << "': defaulting to 60000"; + } + + const_cast(defaultInvocationTimeout) = + properties->getPropertyAsIntWithDefault("Ice.Default.InvocationTimeout", -1); + if(defaultInvocationTimeout < 1 && defaultInvocationTimeout != -1 && defaultInvocationTimeout != -2) + { + const_cast(defaultInvocationTimeout) = -1; + Warning out(logger); + out << "invalid value for Ice.Default.InvocationTimeout `" + << properties->getProperty("Ice.Default.InvocationTimeout") << "': defaulting to -1"; + } + + const_cast(defaultLocatorCacheTimeout) = + properties->getPropertyAsIntWithDefault("Ice.Default.LocatorCacheTimeout", -1); + if(defaultLocatorCacheTimeout < -1) + { + const_cast(defaultLocatorCacheTimeout) = -1; + Warning out(logger); + out << "invalid value for Ice.Default.LocatorCacheTimeout `" + << properties->getProperty("Ice.Default.LocatorCacheTimeout") << "': defaulting to -1"; + } + + const_cast(defaultPreferSecure) = + properties->getPropertyAsIntWithDefault("Ice.Default.PreferSecure", 0) > 0; + + value = properties->getPropertyWithDefault("Ice.Default.EncodingVersion", encodingVersionToString(currentEncoding)); + defaultEncoding = stringToEncodingVersion(value); + checkSupportedEncoding(defaultEncoding); + + bool slicedFormat = properties->getPropertyAsIntWithDefault("Ice.Default.SlicedFormat", 0) > 0; + const_cast(defaultFormat) = slicedFormat ? + ICE_ENUM(FormatType, SlicedFormat) : ICE_ENUM(FormatType, CompactFormat); +} diff --git a/Sources/IceCpp/DispatchInterceptor.cpp b/Sources/IceCpp/DispatchInterceptor.cpp new file mode 100644 index 0000000..78e7931 --- /dev/null +++ b/Sources/IceCpp/DispatchInterceptor.cpp @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace Ice; +using namespace IceInternal; + +bool +Ice::DispatchInterceptor::_iceDispatch(IceInternal::Incoming& in, const Current& /*current*/) +{ + try + { + IncomingRequest request(in); + return dispatch(request); + } + catch(const ResponseSentException&) + { + return false; + } + catch(const std::exception&) + { + // + // If the input parameters weren't read, make sure we skip them here. It's needed to read the + // encoding version used by the client to eventually marshal the user exception. It's also needed + // if we dispatch a batch oneway request to read the next batch request. + // + if(in.getCurrent().encoding.major == 0 && in.getCurrent().encoding.minor == 0) + { + in.skipReadParams(); + } + throw; + } +} diff --git a/Sources/IceCpp/DynamicLibrary.cpp b/Sources/IceCpp/DynamicLibrary.cpp new file mode 100644 index 0000000..286ef39 --- /dev/null +++ b/Sources/IceCpp/DynamicLibrary.cpp @@ -0,0 +1,284 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +#if defined(ICE_CPP11) && defined(__GNUC__) && (__GNUC__ < 6) && defined(__GLIBCXX__) +# define ICE_LIBSUFFIX "++11" +#endif + +using namespace Ice; +using namespace IceInternal; +using namespace std; + +IceUtil::Shared* IceInternal::upCast(DynamicLibrary* p) { return p; } +IceUtil::Shared* IceInternal::upCast(DynamicLibraryList* p) { return p; } + +IceInternal::DynamicLibrary::DynamicLibrary() : + _hnd(0) +{ +} + +IceInternal::DynamicLibrary::~DynamicLibrary() +{ + /* + * Closing the library here can cause a crash at program exit if + * the application holds references to library resources in global + * or static variables. Instead, we let the process discard the + * library. + * + if(_hnd != 0) + { +#ifdef _WIN32 + FreeLibrary(_hnd); +#else + dlclose(_hnd); +#endif + } + */ +} + +IceInternal::DynamicLibrary::symbol_type +IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIceVersion) +{ + string::size_type colon = entryPoint.rfind(':'); + +#ifdef _WIN32 + const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if(colon == 1 && driveLetters.find(entryPoint[0]) != string::npos && + (entryPoint[2] == '\\' || entryPoint[2] == '/')) + { + // + // The only colon we found is in the drive specification, as in "C:\MyDir". + // This means the function name is missing. + // + colon = string::npos; + } +#endif + + if(colon == string::npos || colon == entryPoint.size() - 1) + { + _err = "invalid entry point format `" + entryPoint + "'"; + return 0; + } + + string libSpec = entryPoint.substr(0, colon); + string funcName = entryPoint.substr(colon + 1); + string libPath, libName, version, debug; + +#ifdef _WIN32 + string::size_type separator = libSpec.find_last_of("/\\"); +#else + string::size_type separator = libSpec.rfind('/'); +#endif + if(separator != string::npos) + { + libPath = libSpec.substr(0, separator + 1); + libSpec = libSpec.substr(separator + 1); + } + + string::size_type comma = libSpec.find(','); + if(comma == string::npos) + { + libName = libSpec; +# if defined(ICE_CPP11_MAPPING) && !defined(_WIN32) + libName += "++11"; +# endif + if(useIceVersion) + { + int majorVersion = (ICE_INT_VERSION / 10000); + int minorVersion = (ICE_INT_VERSION / 100) - majorVersion * 100; + int patchVersion = ICE_INT_VERSION % 100; + ostringstream os; + os << majorVersion * 10 + minorVersion; + if(patchVersion >= 60) + { + os << 'b' << (patchVersion - 60); + } + else if(patchVersion >= 50) + { + os << 'a' << (patchVersion - 50); + } + version = os.str(); + } + } + else + { + if(comma == libSpec.size() - 1) + { + _err = "invalid entry point format `" + entryPoint + "'"; + return 0; + } + libName = libSpec.substr(0, comma); +# if defined(ICE_CPP11_MAPPING) && !defined(_WIN32) + libName += "++11"; +# endif + version = libSpec.substr(comma + 1); + } + + string lib = libPath; + +#ifdef _WIN32 + lib += libName; + lib += version; + +# ifdef ICE_CPP11_MAPPING + lib += "++11"; +# endif + +# if defined(_DEBUG) && !defined(__MINGW32__) + lib += 'd'; +# endif + +# ifdef COMPSUFFIX + lib += COMPSUFFIX; +# endif + + lib += ".dll"; +#elif defined(__APPLE__) + lib += "lib" + libName; + if(!version.empty()) + { + lib += "." + version; + } +#elif defined(__hpux) + lib += "lib" + libName; + if(!version.empty()) + { + lib += "." + version; + } + else + { + lib += ".sl"; + } +#elif defined(_AIX) + lib += "lib" + libName + ".a(lib" + libName + ".so"; + if(!version.empty()) + { + lib += "." + version; + } + lib += ")"; +#else + lib += "lib" + libName + ".so"; + if(!version.empty()) + { + lib += "." + version; + } +#endif + +#ifdef __APPLE__ + // + // On macOS fallback to .so and .bundle extensions, if the default + // .dylib fails. + // + if(!load(lib + ".dylib")) + { + string errMsg = _err; + if(!load(lib + ".so")) + { + errMsg += "; " + _err; + if(!load(lib + ".bundle")) + { + _err = errMsg + "; " + _err; + return 0; + } + } + _err = ""; + } +#else + if(!load(lib)) + { + return 0; + } +#endif + + return getSymbol(funcName); +} + +bool +IceInternal::DynamicLibrary::load(const string& lib) +{ + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // +#if defined(_WIN32) + _hnd = LoadLibraryW(stringToWstring(lib, getProcessStringConverter()).c_str()); +#else + int flags = RTLD_NOW | RTLD_GLOBAL; +#ifdef _AIX + flags |= RTLD_MEMBER; +#endif + + _hnd = dlopen(lib.c_str(), flags); +#endif + if(_hnd == 0) + { + // + // Remember the most recent error in _err. + // +#if defined(_WIN32) + _err = "LoadLibraryW on `" + lib + "' failed with `" + IceUtilInternal::lastErrorToString() + "'"; +#else + const char* err = dlerror(); + if(err) + { + _err = err; + } +#endif + } + + return _hnd != 0; +} + +IceInternal::DynamicLibrary::symbol_type +IceInternal::DynamicLibrary::getSymbol(const string& name) +{ + assert(_hnd != 0); +#ifdef _WIN32 + symbol_type result = GetProcAddress(_hnd, name.c_str()); +#else + symbol_type result = dlsym(_hnd, name.c_str()); +#endif + + if(result == 0) + { + // + // Remember the most recent error in _err. + // +#ifdef _WIN32 + _err = "GetProcAddress for `" + name + "' failed with `" + IceUtilInternal::lastErrorToString() + "'"; +#else + const char* err = dlerror(); + if(err) + { + _err = err; + } +#endif + } + return result; +} + +const string& +IceInternal::DynamicLibrary::getErrorMessage() const +{ + return _err; +} + +IceInternal::DynamicLibraryList::~DynamicLibraryList() +{ + // Out of line to avoid weak vtable +} + +void +IceInternal::DynamicLibraryList::add(const DynamicLibraryPtr& library) +{ + _libraries.push_back(library); +} diff --git a/Sources/IceCpp/Endpoint.cpp b/Sources/IceCpp/Endpoint.cpp new file mode 100644 index 0000000..c8aed2f --- /dev/null +++ b/Sources/IceCpp/Endpoint.cpp @@ -0,0 +1,147 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Endpoint.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::EndpointInfo::~EndpointInfo() +{ +} + +Ice::Endpoint::~Endpoint() +{ +} + +Ice::IPEndpointInfo::~IPEndpointInfo() +{ +} + +Ice::TCPEndpointInfo::~TCPEndpointInfo() +{ +} + +Ice::UDPEndpointInfo::~UDPEndpointInfo() +{ +} + +Ice::WSEndpointInfo::~WSEndpointInfo() +{ +} + +Ice::OpaqueEndpointInfo::~OpaqueEndpointInfo() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::EndpointInfo::~EndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(EndpointInfo* p) { return p; } +/// \endcond + +Ice::Endpoint::~Endpoint() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Endpoint* p) { return p; } +/// \endcond + +Ice::IPEndpointInfo::~IPEndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(IPEndpointInfo* p) { return p; } +/// \endcond + +Ice::TCPEndpointInfo::~TCPEndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(TCPEndpointInfo* p) { return p; } +/// \endcond + +Ice::UDPEndpointInfo::~UDPEndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(UDPEndpointInfo* p) { return p; } +/// \endcond + +Ice::WSEndpointInfo::~WSEndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(WSEndpointInfo* p) { return p; } +/// \endcond + +Ice::OpaqueEndpointInfo::~OpaqueEndpointInfo() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(OpaqueEndpointInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/EndpointF.cpp b/Sources/IceCpp/EndpointF.cpp new file mode 100644 index 0000000..da489f8 --- /dev/null +++ b/Sources/IceCpp/EndpointF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/EndpointFactory.cpp b/Sources/IceCpp/EndpointFactory.cpp new file mode 100644 index 0000000..4d4f394 --- /dev/null +++ b/Sources/IceCpp/EndpointFactory.cpp @@ -0,0 +1,189 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(EndpointFactory* p) { return p; } + +IceInternal::EndpointFactory::EndpointFactory() +{ +} + +IceInternal::EndpointFactory::~EndpointFactory() +{ +} + +void +IceInternal::EndpointFactory::initialize() +{ + // Nothing to do, can be overriden by specialization to finish initialization. +} + +IceInternal::EndpointFactoryPlugin::EndpointFactoryPlugin(const CommunicatorPtr& communicator, + const EndpointFactoryPtr& factory) +{ + assert(communicator); + getInstance(communicator)->endpointFactoryManager()->add(factory); +} + +void +IceInternal::EndpointFactoryPlugin::initialize() +{ +} + +void +IceInternal::EndpointFactoryPlugin::destroy() +{ +} + +IceInternal::EndpointFactoryWithUnderlying::EndpointFactoryWithUnderlying(const ProtocolInstancePtr& instance, + Short type) : + _instance(instance), _type(type) +{ +} + +void +IceInternal::EndpointFactoryWithUnderlying::initialize() +{ + // + // Get the endpoint factory for the underlying type and clone it with + // our protocol instance. + // + EndpointFactoryPtr factory = _instance->getEndpointFactory(_type); + if(factory) + { + _underlying = factory->clone(_instance); + _underlying->initialize(); + } +} + +Short +IceInternal::EndpointFactoryWithUnderlying::type() const +{ + return _instance->type(); +} + +string +IceInternal::EndpointFactoryWithUnderlying::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceInternal::EndpointFactoryWithUnderlying::create(vector& args, bool oaEndpoint) const +{ + if(!_underlying) + { + return 0; // Can't create an endpoint without underlying factory. + } + return createWithUnderlying(_underlying->create(args, oaEndpoint), args, oaEndpoint); +} + +EndpointIPtr +IceInternal::EndpointFactoryWithUnderlying::read(InputStream* s) const +{ + if(!_underlying) + { + return 0; // Can't create an endpoint without underlying factory. + } + return readWithUnderlying(_underlying->read(s), s); +} + +void +IceInternal::EndpointFactoryWithUnderlying::destroy() +{ + if(_underlying) + { + _underlying->destroy(); + } + _instance = 0; +} + +EndpointFactoryPtr +IceInternal::EndpointFactoryWithUnderlying::clone(const ProtocolInstancePtr& instance) const +{ + return cloneWithUnderlying(instance, _type); +} + +IceInternal::UnderlyingEndpointFactory::UnderlyingEndpointFactory(const ProtocolInstancePtr& instance, + Short type, + Short underlying) : + _instance(instance), _type(type), _underlying(underlying) +{ +} + +void +IceInternal::UnderlyingEndpointFactory::initialize() +{ + // + // Get the endpoint factory of the given endpoint type. If it's a factory that + // delegates to an underlying endpoint, clone it and instruct it to delegate to + // our underlying factory. + // + EndpointFactoryPtr factory = _instance->getEndpointFactory(_type); + if(factory) + { + EndpointFactoryWithUnderlying* f = dynamic_cast(factory.get()); + if(f) + { + _factory = f->cloneWithUnderlying(_instance, _underlying); + _factory->initialize(); + } + } +} + +Short +IceInternal::UnderlyingEndpointFactory::type() const +{ + return _instance->type(); +} + +string +IceInternal::UnderlyingEndpointFactory::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceInternal::UnderlyingEndpointFactory::create(vector& args, bool oaEndpoint) const +{ + if(!_factory) + { + return 0; + } + return _factory->create(args, oaEndpoint); +} + +EndpointIPtr +IceInternal::UnderlyingEndpointFactory::read(InputStream* s) const +{ + if(!_factory) + { + return 0; + } + return _factory->read(s); +} + +void +IceInternal::UnderlyingEndpointFactory::destroy() +{ + if(_factory) + { + _factory->destroy(); + } + _instance = 0; +} + +EndpointFactoryPtr +IceInternal::UnderlyingEndpointFactory::clone(const ProtocolInstancePtr& instance) const +{ + return new UnderlyingEndpointFactory(instance, _type, _underlying); +} diff --git a/Sources/IceCpp/EndpointFactoryManager.cpp b/Sources/IceCpp/EndpointFactoryManager.cpp new file mode 100644 index 0000000..0c9ed3c --- /dev/null +++ b/Sources/IceCpp/EndpointFactoryManager.cpp @@ -0,0 +1,213 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(EndpointFactoryManager* p) { return p; } + +IceInternal::EndpointFactoryManager::EndpointFactoryManager(const InstancePtr& instance) + : _instance(instance) +{ +} + +void +IceInternal::EndpointFactoryManager::initialize() const +{ + for(vector::size_type i = 0; i < _factories.size(); i++) + { + _factories[i]->initialize(); + } +} + +void +IceInternal::EndpointFactoryManager::add(const EndpointFactoryPtr& factory) +{ + IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? + + // + // TODO: Optimize with a map? + // + for(vector::size_type i = 0; i < _factories.size(); i++) + { + if(_factories[i]->type() == factory->type()) + { + assert(false); // TODO: Exception? + } + } + _factories.push_back(factory); +} + +EndpointFactoryPtr +IceInternal::EndpointFactoryManager::get(Short type) const +{ + IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? + + // + // TODO: Optimize with a map? + // + for(vector::size_type i = 0; i < _factories.size(); i++) + { + if(_factories[i]->type() == type) + { + return _factories[i]; + } + } + return ICE_NULLPTR; +} + +EndpointIPtr +IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint) const +{ + vector v; + bool b = IceUtilInternal::splitString(str, " \t\n\r", v); + if(!b) + { + throw EndpointParseException(__FILE__, __LINE__, "mismatched quote"); + } + + if(v.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "value has no non-whitespace characters"); + } + + string protocol = v.front(); + v.erase(v.begin()); + + if(protocol == "default") + { + protocol = _instance->defaultsAndOverrides()->defaultProtocol; + } + + EndpointFactoryPtr factory; + { + IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? + + // + // TODO: Optimize with a map? + // + for(vector::size_type i = 0; i < _factories.size(); i++) + { + if(_factories[i]->protocol() == protocol) + { + factory = _factories[i]; + } + } + } + + if(factory) + { +#if 1 + EndpointIPtr e = factory->create(v, oaEndpoint); + if(!v.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unrecognized argument `" + v.front() + + "' in endpoint `" + str + "'"); + } + return e; +#else + // Code below left in place for debugging. + + EndpointIPtr e = factory->create(str.substr(end), oaEndpoint); + OutputStream bs(_instance.get(), Ice::currentProtocolEncoding); + e->streamWrite(&bs); + bs.i = bs.b.begin(); + short type; + bs.read(type); + EndpointIPtr ue = new IceInternal::OpaqueEndpointI(type, &bs); + consoleErr << "Normal: " << e->toString() << endl; + consoleErr << "Opaque: " << ue->toString() << endl; + return e; +#endif + } + + // + // If the stringified endpoint is opaque, create an unknown endpoint, + // then see whether the type matches one of the known endpoints. + // + if(protocol == "opaque") + { + EndpointIPtr ue = ICE_MAKE_SHARED(OpaqueEndpointI, v); + if(!v.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unrecognized argument `" + v.front() + "' in endpoint `" + + str + "'"); + } + factory = get(ue->type()); + if(factory) + { + // + // Make a temporary stream, write the opaque endpoint data into the stream, + // and ask the factory to read the endpoint data from that stream to create + // the actual endpoint. + // + OutputStream bs(_instance.get(), Ice::currentProtocolEncoding); + bs.write(ue->type()); + ue->streamWrite(&bs); + InputStream is(bs.instance(), bs.getEncoding(), bs); + short type; + is.read(type); + is.startEncapsulation(); + EndpointIPtr e = factory->read(&is); + is.endEncapsulation(); + return e; + } + return ue; // Endpoint is opaque, but we don't have a factory for its type. + } + + return ICE_NULLPTR; +} + +EndpointIPtr +IceInternal::EndpointFactoryManager::read(InputStream* s) const +{ + Short type; + s->read(type); + + EndpointFactoryPtr factory = get(type); + EndpointIPtr e; + + s->startEncapsulation(); + + if(factory) + { + e = factory->read(s); + } + // + // If the factory failed to read the endpoint, return an opaque endpoint. This can + // occur if for example the factory delegates to another factory and this factory + // isn't available. In this case, the factory needs to make sure the stream position + // is preserved for reading the opaque endpoint. + // + if(!e) + { + e = ICE_MAKE_SHARED(OpaqueEndpointI, type, s); + } + + s->endEncapsulation(); + + return e; +} + +void +IceInternal::EndpointFactoryManager::destroy() +{ + for(vector::size_type i = 0; i < _factories.size(); i++) + { + _factories[i]->destroy(); + } + _factories.clear(); +} diff --git a/Sources/IceCpp/EndpointI.cpp b/Sources/IceCpp/EndpointI.cpp new file mode 100644 index 0000000..1c46219 --- /dev/null +++ b/Sources/IceCpp/EndpointI.cpp @@ -0,0 +1,98 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(EndpointI* p) { return p; } +IceUtil::Shared* IceInternal::upCast(EndpointI_connectors* p) { return p; } +#endif + +IceInternal::EndpointI_connectors::~EndpointI_connectors() +{ + // Out of line to avoid weak vtable +} + +void +IceInternal::EndpointI::streamWrite(Ice::OutputStream* s) const +{ + s->startEncapsulation(); + streamWriteImpl(s); + s->endEncapsulation(); +} + +string +IceInternal::EndpointI::toString() const ICE_NOEXCEPT +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + return protocol() + options(); +} + +void +IceInternal::EndpointI::initWithOptions(vector& args) +{ + vector unknown; + + ostringstream ostr; + ostr << '`' << protocol() << " "; + for(vector::iterator p = args.begin(); p != args.end(); ++p) + { + if(p->find_first_of(" \t\n\r") != string::npos) + { + ostr << " \"" << *p << "\""; + } + else + { + ostr << " " << *p; + } + } + ostr << "'"; + const string str = ostr.str(); + + for(vector::size_type n = 0; n < args.size(); ++n) + { + string option = args[n]; + if(option.length() < 2 || option[0] != '-') + { + unknown.push_back(option); + continue; + } + + string argument; + if(n + 1 < args.size() && args[n + 1][0] != '-') + { + argument = args[++n]; + } + + if(!checkOption(option, argument, str)) + { + unknown.push_back(option); + if(!argument.empty()) + { + unknown.push_back(argument); + } + } + } + + // + // Replace argument vector with only those we didn't recognize. + // + args = unknown; +} + +bool +IceInternal::EndpointI::checkOption(const string&, const string&, const string&) +{ + // Must be overriden to check for options. + return false; +} diff --git a/Sources/IceCpp/EndpointInfo.cpp b/Sources/IceCpp/EndpointInfo.cpp new file mode 100644 index 0000000..27a6cf1 --- /dev/null +++ b/Sources/IceCpp/EndpointInfo.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICEIAP_API_EXPORTS +# define ICEIAP_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +IceIAP::EndpointInfo::~EndpointInfo() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +IceIAP::EndpointInfo::~EndpointInfo() +{ +} + +/// \cond INTERNAL +ICEIAP_API ::Ice::LocalObject* IceIAP::upCast(EndpointInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/EndpointTypes.cpp b/Sources/IceCpp/EndpointTypes.cpp new file mode 100644 index 0000000..5ee7da4 --- /dev/null +++ b/Sources/IceCpp/EndpointTypes.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointTypes.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#else // C++98 mapping + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/EventHandler.cpp b/Sources/IceCpp/EventHandler.cpp new file mode 100644 index 0000000..96e56d8 --- /dev/null +++ b/Sources/IceCpp/EventHandler.cpp @@ -0,0 +1,32 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(EventHandler* p) { return p; } +#endif + +IceInternal::EventHandler::EventHandler() : +#if defined(ICE_USE_IOCP) + _pending(SocketOperationNone), + _started(SocketOperationNone), + _completed(SocketOperationNone), + _finish(false), +#else + _disabled(SocketOperationNone), +#endif + _ready(SocketOperationNone), + _registered(SocketOperationNone) +{ +} + +IceInternal::EventHandler::~EventHandler() +{ +} diff --git a/Sources/IceCpp/Exception.cpp b/Sources/IceCpp/Exception.cpp new file mode 100644 index 0000000..b758abe --- /dev/null +++ b/Sources/IceCpp/Exception.cpp @@ -0,0 +1,818 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +inline string +socketErrorToString(int error) +{ + if(error == 0) + { + return "unknown error"; + } + return IceUtilInternal::errorToString(error); +} + +}; + +namespace IceInternal +{ + +namespace Ex +{ + +void +throwUOE(const string& expectedType, const ValuePtr& v) +{ + // + // If the object is an unknown sliced object, we didn't find an + // value factory, in this case raise a NoValueFactoryException + // instead. + // + UnknownSlicedValue* usv = dynamic_cast(v.get()); + if(usv) + { + throw NoValueFactoryException(__FILE__, __LINE__, "", usv->ice_id()); + } + + string type = v->ice_id(); + throw Ice::UnexpectedObjectException(__FILE__, __LINE__, + "expected element of type `" + expectedType + "' but received `" + + type + "'", type, expectedType); +} + +void +throwMemoryLimitException(const char* file, int line, size_t requested, size_t maximum) +{ + ostringstream s; + s << "requested " << requested << " bytes, maximum allowed is " << maximum << " bytes (see Ice.MessageSizeMax)"; + throw Ice::MemoryLimitException(file, line, s.str()); +} + +void +throwMarshalException(const char* file, int line, const string& reason) +{ + throw Ice::MarshalException(file, line, reason); +} + +} +} + +namespace +{ + +const string userException_ids[] = +{ + "::Ice::UserException" +}; + +} + +const std::string& +Ice::UserException::ice_staticId() +{ + return userException_ids[0]; +} + +#ifdef ICE_CPP11_MAPPING +unique_ptr +Ice::UserException::ice_clone() const +{ + return unique_ptr(static_cast(ice_cloneImpl())); +} +#endif + +Ice::SlicedDataPtr +Ice::UserException::ice_getSlicedData() const +{ + return ICE_NULLPTR; +} + +void +Ice::UserException::_write(::Ice::OutputStream* os) const +{ + os->startException(0); + _writeImpl(os); + os->endException(); +} + +void +Ice::UserException::_read(::Ice::InputStream* is) +{ + is->startException(); + _readImpl(is); + is->endException(false); +} + +bool +Ice::UserException::_usesClasses() const +{ + return false; +} + +Ice::LocalException::LocalException(const char* file, int line) : + Exception(file, line) +{ +} + +Ice::LocalException::~LocalException() +#ifndef ICE_CPP11_COMPILER + throw() +#endif +{ + // Out of line to avoid weak vtable +} + +#ifdef ICE_CPP11_MAPPING +unique_ptr +Ice::LocalException::ice_clone() const +{ + return unique_ptr(static_cast(ice_cloneImpl())); +} +#endif + +namespace +{ + +const string localException_ids[] = +{ + "::Ice::LocalException" +}; + +} + +const std::string& +Ice::LocalException::ice_staticId() +{ + return localException_ids[0]; +} + +Ice::SystemException::SystemException(const char* file, int line) : + Exception(file, line) +{ +} + +Ice::SystemException::~SystemException() +#ifndef ICE_CPP11_COMPILER + throw() +#endif +{ +} + +#ifdef ICE_CPP11_MAPPING +unique_ptr +Ice::SystemException::ice_clone() const +{ + return unique_ptr(static_cast(ice_cloneImpl())); +} +#endif + +namespace +{ + +const string systemException_ids[] = +{ + "::Ice::SystemException" +}; + +} + +const std::string& +Ice::SystemException::ice_staticId() +{ + return systemException_ids[0]; +} + +void +Ice::InitializationException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ninitialization exception"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::UnknownException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown exception"; + if(!unknown.empty()) + { + out << ":\n" << unknown; + } +} + +void +Ice::UnknownLocalException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown local exception"; + if(!unknown.empty()) + { + out << ":\n" << unknown; + } +} + +void +Ice::UnknownUserException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown user exception"; + if(!unknown.empty()) + { + out << ":\n" << unknown; + } +} + +void +Ice::VersionMismatchException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nIce library version mismatch"; +} + +void +Ice::CommunicatorDestroyedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ncommunicator object destroyed"; +} + +void +Ice::ObjectAdapterDeactivatedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nobject adapter `" << name << "' deactivated"; +} + +void +Ice::ObjectAdapterIdInUseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nobject adapter with id `" << id << "' is already in use"; +} + +void +Ice::NoEndpointException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nno suitable endpoint available for proxy `" << proxy << "'"; +} + +void +Ice::EndpointParseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nerror while parsing endpoint `" << str << "'"; +} + +void +Ice::EndpointSelectionTypeParseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nerror while parsing endpoint selection type `" << str << "'"; +} + +void +Ice::VersionParseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nerror while parsing version `" << str << "'"; +} + +void +Ice::IdentityParseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nerror while parsing identity `" << str << "'"; +} + +void +Ice::ProxyParseException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nerror while parsing proxy `" << str << "'"; +} + +void +Ice::IllegalIdentityException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nillegal identity: `" << identityToString(id, ICE_ENUM(ToStringMode, Unicode)) << "'"; +} + +void +Ice::IllegalServantException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nillegal servant: `" << reason << "'"; +} + +static void +printFailedRequestData(ostream& out, const RequestFailedException& ex) +{ + out << ":\nidentity: `" << identityToString(ex.id, ICE_ENUM(ToStringMode, Unicode)) << "'"; + out << "\nfacet: " << ex.facet; + out << "\noperation: " << ex.operation; +} + +void +Ice::RequestFailedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nrequest failed"; + printFailedRequestData(out, *this); +} + +void +Ice::ObjectNotExistException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nobject does not exist"; + printFailedRequestData(out, *this); +} + +void +Ice::FacetNotExistException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nfacet does not exist"; + printFailedRequestData(out, *this); +} + +void +Ice::OperationNotExistException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\noperation does not exist"; + printFailedRequestData(out, *this); +} + +void +Ice::SyscallException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + if(error != 0) + { + out << ":\nsyscall exception: " << IceUtilInternal::errorToString(error); + } +} + +void +Ice::SocketException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nsocket exception: " << socketErrorToString(error); +} + +void +Ice::FileException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nfile exception: "; + if(error == 0) + { + out << "couldn't open file"; + } + else + { + out << IceUtilInternal::errorToString(error); + } + if(!path.empty()) + { + out << "\npath: " << path; + } +} + +void +Ice::ConnectFailedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nconnect failed: " << socketErrorToString(error); +} + +void +Ice::ConnectionRefusedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nconnection refused: " << socketErrorToString(error); +} + +void +Ice::ConnectionLostException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nconnection lost: "; + if(error == 0) + { + out << "recv() returned zero"; + } + else + { + out << socketErrorToString(error); + } +} + +void +Ice::DNSException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nDNS error: "; + out << errorToStringDNS(error); + out << "\nhost: " << host; +} + +void +Ice::OperationInterruptedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\noperation interrupted"; +} + +void +Ice::TimeoutException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ntimeout while sending or receiving data"; +} + +void +Ice::ConnectTimeoutException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ntimeout while establishing a connection"; +} + +void +Ice::CloseTimeoutException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ntimeout while closing a connection"; +} + +void +Ice::ConnectionTimeoutException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nconnection has timed out"; +} + +void +Ice::InvocationTimeoutException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ninvocation has timed out"; +} + +void +Ice::InvocationCanceledException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\ninvocation canceled"; +} + +void +Ice::ProtocolException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol exception"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::BadMagicException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown magic number: "; + + ios_base::fmtflags originalFlags = out.flags(); // Save stream state + ostream::char_type originalFill = out.fill(); + + out.flags(ios_base::hex); // Change to hex + out.fill('0'); // Fill with leading zeros + + out << "0x" << setw(2) << static_cast(static_cast(badMagic[0])) << ", "; + out << "0x" << setw(2) << static_cast(static_cast(badMagic[1])) << ", "; + out << "0x" << setw(2) << static_cast(static_cast(badMagic[2])) << ", "; + out << "0x" << setw(2) << static_cast(static_cast(badMagic[3])); + + out.fill(originalFill); // Restore stream state + out.flags(originalFlags); + + if(!reason.empty()) + { + out << "\n" << reason; + } +} + +void +Ice::UnsupportedProtocolException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: unsupported protocol version: " << bad; + out << "\n(can only support protocols compatible with version " << supported << ")"; +} + +void +Ice::UnsupportedEncodingException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nencoding error: unsupported encoding version: " << bad; + out << "\n(can only support encodings compatible with version " << supported << ")"; + if(!reason.empty()) + { + out << "\n" << reason; + } +} + +void +Ice::UnknownMessageException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: unknown message type"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::ConnectionNotValidatedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: received message over unvalidated connection"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::UnknownRequestIdException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: unknown request id"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::UnknownReplyStatusException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: unknown reply status"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::CloseConnectionException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: connection closed"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::ConnectionManuallyClosedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: connection manually closed (" << (graceful ? "gracefully" : "forcefully") << ")"; +} + +void +Ice::IllegalMessageSizeException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: illegal message size"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::CompressionException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: failed to compress or uncompress data"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::DatagramLimitException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: maximum datagram payload size exceeded"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::MarshalException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: error during marshaling or unmarshaling"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::ProxyUnmarshalException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: inconsistent proxy data during unmarshaling"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::UnmarshalOutOfBoundsException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: out of bounds during unmarshaling"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::NoValueFactoryException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: no suitable value factory found for `" << type << "'"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::UnexpectedObjectException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunexpected class instance of type `" << type << + "'; expected instance of type `" << expectedType << "'"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::MemoryLimitException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: memory limit exceeded"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::StringConversionException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: string conversion failed"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::EncapsulationException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nprotocol error: illegal encapsulation"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::PluginInitializationException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nplug-in initialization failed"; + if(!reason.empty()) + { + out << ": " << reason; + } +} + +void +Ice::CollocationOptimizationException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nrequested feature not available with collocation optimization"; +} + +void +Ice::AlreadyRegisteredException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\n" << kindOfObject << " with id `" << id << "' is already registered"; +} + +void +Ice::NotRegisteredException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nno " << kindOfObject << " with id `" << id << "' is registered"; +} + +void +Ice::TwowayOnlyException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\noperation `" << operation << "' can only be invoked as a twoway request"; +} + +void +Ice::CloneNotImplementedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nice_clone() must be implemented in classes derived from abstract base classes"; +} + +void +Ice::FeatureNotSupportedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nfeature `" << unsupportedFeature << "' is not supported"; +} + +void +Ice::SecurityException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nsecurity exception"; + if(!reason.empty()) + { + out << ":\n" << reason; + } +} + +void +Ice::FixedProxyException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nfixed proxy exception"; +} + +void +Ice::ResponseSentException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nresponse sent exception"; +} + +void +Ice::CFNetworkException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nnetwork exception: domain: " << domain << " error: " << error; +} diff --git a/Sources/IceCpp/FacetMap.cpp b/Sources/IceCpp/FacetMap.cpp new file mode 100644 index 0000000..68c709e --- /dev/null +++ b/Sources/IceCpp/FacetMap.cpp @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `FacetMap.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#else // C++98 mapping + +#endif diff --git a/Sources/IceCpp/FactoryTable.cpp b/Sources/IceCpp/FactoryTable.cpp new file mode 100644 index 0000000..7afe0bd --- /dev/null +++ b/Sources/IceCpp/FactoryTable.cpp @@ -0,0 +1,162 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; + +#ifndef ICE_CPP11_MAPPING + +Ice::UserExceptionFactory::~UserExceptionFactory() +{ + // Out of line to avoid weak vtable +} + +#endif + +// +// Add a factory to the exception factory table. +// If the factory is present already, increment its reference count. +// +void +IceInternal::FactoryTable::addExceptionFactory(const string& t, ICE_IN(ICE_DELEGATE(::Ice::UserExceptionFactory)) f) +{ + IceUtil::Mutex::Lock lock(_m); + assert(f); + EFTable::iterator i = _eft.find(t); + if(i == _eft.end()) + { + _eft[t] = EFPair(f, 1); + } + else + { + i->second.second++; + } +} + +// +// Return the exception factory for a given type ID +// +ICE_DELEGATE(::Ice::UserExceptionFactory) +IceInternal::FactoryTable::getExceptionFactory(const string& t) const +{ + IceUtil::Mutex::Lock lock(_m); + EFTable::const_iterator i = _eft.find(t); + return i != _eft.end() ? i->second.first : ICE_DELEGATE(::Ice::UserExceptionFactory)(); +} + +// +// Remove a factory from the exception factory table. If the factory +// is not present, do nothing; otherwise, decrement the factory's +// reference count; if the count drops to zero, remove the factory's +// entry from the table. +// +void +IceInternal::FactoryTable::removeExceptionFactory(const string& t) +{ + IceUtil::Mutex::Lock lock(_m); + EFTable::iterator i = _eft.find(t); + if(i != _eft.end()) + { + if(--i->second.second == 0) + { + _eft.erase(i); + } + } +} + +// +// Add a factory to the value factory table. +// +void +IceInternal::FactoryTable::addValueFactory(const string& t, ICE_IN(ICE_DELEGATE(::Ice::ValueFactory)) f) +{ + IceUtil::Mutex::Lock lock(_m); + assert(f); + VFTable::iterator i = _vft.find(t); + if(i == _vft.end()) + { + _vft[t] = VFPair(f, 1); + } + else + { + i->second.second++; + } +} + +// +// Return the value factory for a given type ID +// +ICE_DELEGATE(::Ice::ValueFactory) +IceInternal::FactoryTable::getValueFactory(const string& t) const +{ + IceUtil::Mutex::Lock lock(_m); + VFTable::const_iterator i = _vft.find(t); + return i != _vft.end() ? i->second.first : ICE_DELEGATE(::Ice::ValueFactory)(); +} + +// +// Remove a factory from the value factory table. If the factory +// is not present, do nothing; otherwise, decrement the factory's +// reference count if the count drops to zero, remove the factory's +// entry from the table. +// +void +IceInternal::FactoryTable::removeValueFactory(const string& t) +{ + IceUtil::Mutex::Lock lock(_m); + VFTable::iterator i = _vft.find(t); + if(i != _vft.end()) + { + if(--i->second.second == 0) + { + _vft.erase(i); + } + } +} + +// +// Add a factory to the value factory table. +// +void +IceInternal::FactoryTable::addTypeId(int compactId, const string& typeId) +{ + IceUtil::Mutex::Lock lock(_m); + assert(!typeId.empty() && compactId >= 0); + TypeIdTable::iterator i = _typeIdTable.find(compactId); + if(i == _typeIdTable.end()) + { + _typeIdTable[compactId] = TypeIdPair(typeId, 1); + } + else + { + i->second.second++; + } +} + +// +// Return the type ID for the given compact ID +// +string +IceInternal::FactoryTable::getTypeId(int compactId) const +{ + IceUtil::Mutex::Lock lock(_m); + TypeIdTable::const_iterator i = _typeIdTable.find(compactId); + return i != _typeIdTable.end() ? i->second.first : string(); +} + +void +IceInternal::FactoryTable::removeTypeId(int compactId) +{ + IceUtil::Mutex::Lock lock(_m); + TypeIdTable::iterator i = _typeIdTable.find(compactId); + if(i != _typeIdTable.end()) + { + if(--i->second.second == 0) + { + _typeIdTable.erase(i); + } + } +} diff --git a/Sources/IceCpp/FactoryTableInit.cpp b/Sources/IceCpp/FactoryTableInit.cpp new file mode 100644 index 0000000..55a7134 --- /dev/null +++ b/Sources/IceCpp/FactoryTableInit.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +namespace IceInternal +{ + +// +// Single global instance of the factory table for non-local +// exceptions and non-abstract classes. +// +ICE_API FactoryTable* factoryTable; + +} + +namespace +{ + +int initCount = 0; // Initialization count +IceUtil::Mutex* initCountMutex = 0; + +class Init +{ +public: + + Init() + { + initCountMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete initCountMutex; + initCountMutex = 0; + } +}; + +Init init; + +} + +// +// This constructor initializes the single global +// IceInternal::factoryTable instance from the outside (if it hasn't +// been initialized yet). The constructor here is triggered by a +// file-static instance of FactoryTable in each slice2cpp-generated +// header file that uses non-local exceptions or non-abstract classes. +// This ensures that IceInternal::factoryTable is always initialized +// before it is used. +// +IceInternal::FactoryTableInit::FactoryTableInit() +{ + IceUtilInternal::MutexPtrLock lock(initCountMutex); + if(0 == initCount++) + { + factoryTable = new FactoryTable; + } +} + +// +// The destructor decrements the reference count and, once the +// count drops to zero, deletes the table. +// +IceInternal::FactoryTableInit::~FactoryTableInit() +{ + IceUtilInternal::MutexPtrLock lock(initCountMutex); + if(0 == --initCount) + { + delete factoryTable; + } +} + +IceInternal::CompactIdInit::CompactIdInit(const char* typeId, int compactId) : + _compactId(compactId) +{ + assert(_compactId >= 0); + factoryTable->addTypeId(_compactId, typeId); +} + +IceInternal::CompactIdInit::~CompactIdInit() +{ + factoryTable->removeTypeId(_compactId); +} diff --git a/Sources/IceCpp/FileUtil.cpp b/Sources/IceCpp/FileUtil.cpp new file mode 100644 index 0000000..2275d1b --- /dev/null +++ b/Sources/IceCpp/FileUtil.cpp @@ -0,0 +1,471 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +# include +#else +# include +# include +#endif + +using namespace std; + +namespace IceUtilInternal +{ +#ifdef _WIN32 +const string pathsep = ";"; +const string separator = "\\"; +#else +const string pathsep = ":"; +const string separator = "/"; +#endif +} + +// +// Determine if path is an absolute path +// +bool +IceUtilInternal::isAbsolutePath(const string& path) +{ + size_t i = 0; + size_t size = path.size(); + + // Skip whitespace + while(i < size && isspace(static_cast(path[i]))) + { + ++i; + } + +#ifdef _WIN32 + // We need at least 3 non whitespace character to have + // and absolute path + if(i + 3 > size) + { + return false; + } + + // Check for X:\ path ('\' may have been converted to '/') + if((path[i] >= 'A' && path[i] <= 'Z') || (path[i] >= 'a' && path[i] <= 'z')) + { + return path[i + 1] == ':' && (path[i + 2] == '\\' || path[i + 2] == '/'); + } + + // Check for UNC path + return (path[i] == '\\' && path[i + 1] == '\\') || path[i] == '/'; +#else + if(i >= size) + { + return false; + } + + return path[i] == '/'; +#endif +} + +// +// Determine if a directory exists. +// +bool +IceUtilInternal::directoryExists(const string& path) +{ + IceUtilInternal::structstat st; + if(IceUtilInternal::stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) + { + return false; + } + return true; +} + +// +// Determine if a directory exists and is empty. +// +bool +IceUtilInternal::isEmptyDirectory(const string& path) +{ +#ifdef _WIN32 + return PathIsDirectoryEmptyW(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +#else + struct dirent* d; + DIR* dir = opendir(path.c_str()); + if(dir) + { + bool empty = true; + while((d = readdir(dir))) + { + string name(d->d_name); + if(name != "." && name != "..") + { + empty = false; + break; + } + } + closedir(dir); + return empty; + } + else + { + return false; + } +#endif +} + +// +// Determine if a regular file exists. +// +bool +IceUtilInternal::fileExists(const string& path) +{ + IceUtilInternal::structstat st; + if(IceUtilInternal::stat(path, &st) != 0 || !S_ISREG(st.st_mode)) + { + return false; + } + return true; +} + +FILE* +IceUtilInternal::freopen(const std::string& path, const std::string& mode, FILE* stream) +{ +#ifdef _LARGEFILE64_SOURCE + return freopen64(path.c_str(), mode.c_str(), stream); +#else +# ifdef _WIN32 + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return _wfreopen(stringToWstring(path, converter).c_str(), + stringToWstring(mode, converter).c_str(), stream); +# else + return freopen(path.c_str(), mode.c_str(), stream); +# endif +#endif +} + +#ifdef _WIN32 + +// +// Stat +// +int +IceUtilInternal::stat(const string& path, structstat* buffer) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return _wstat(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str(), buffer); +} + +int +IceUtilInternal::remove(const string& path) +{ + return ::_wremove(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +} + +int +IceUtilInternal::rename(const string& from, const string& to) +{ + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return ::_wrename(stringToWstring(from, converter).c_str(), + stringToWstring(to, converter).c_str()); +} + +int +IceUtilInternal::rmdir(const string& path) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return ::_wrmdir(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +} + +int +IceUtilInternal::mkdir(const string& path, int) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return ::_wmkdir(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +} + +FILE* +IceUtilInternal::fopen(const string& path, const string& mode) +{ + // + // Don't need to use a wide string converter, the wide strings are directly passed + // to Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + return ::_wfopen(stringToWstring(path, converter).c_str(), + stringToWstring(mode, converter).c_str()); +} + +int +IceUtilInternal::open(const string& path, int flags) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + if(flags & _O_CREAT) + { + return ::_wopen(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str(), + flags, _S_IREAD | _S_IWRITE); + } + else + { + return ::_wopen(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str(), flags); + } +} + +int +IceUtilInternal::getcwd(string& cwd) +{ + // + // Don't need to use a wide string converter, the wide string come + // from Windows API. + // + wchar_t cwdbuf[_MAX_PATH]; + if(_wgetcwd(cwdbuf, _MAX_PATH) == ICE_NULLPTR) + { + return -1; + } + cwd = wstringToString(cwdbuf, IceUtil::getProcessStringConverter()); + return 0; +} + +int +IceUtilInternal::unlink(const string& path) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + return _wunlink(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +} + +int +IceUtilInternal::close(int fd) +{ +#ifdef _WIN32 + return _close(fd); +#else + return ::close(fd); +#endif +} + +IceUtilInternal::FileLock::FileLock(const std::string& path) : + _fd(INVALID_HANDLE_VALUE), + _path(path) +{ + // + // Don't need to use a wide string converter, the wide string is directly passed + // to Windows API. + // + _fd = ::CreateFileW(stringToWstring(path, IceUtil::getProcessStringConverter()).c_str(), + GENERIC_WRITE, 0, ICE_NULLPTR, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, ICE_NULLPTR); + _path = path; + + if(_fd == INVALID_HANDLE_VALUE) + { + throw IceUtil::FileLockException(__FILE__, __LINE__, GetLastError(), _path); + } + +#ifdef __MINGW32__ + if(::LockFile(_fd, 0, 0, 0, 0) == 0) + { + throw IceUtil::FileLockException(__FILE__, __LINE__, GetLastError(), _path); + } +#else + OVERLAPPED overlaped; + overlaped.Internal = 0; + overlaped.InternalHigh = 0; + overlaped.Offset = 0; + overlaped.OffsetHigh = 0; + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) + overlaped.hEvent = nullptr; +#else + overlaped.hEvent = 0; +#endif + + if(::LockFileEx(_fd, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlaped) == 0) + { + ::CloseHandle(_fd); + throw IceUtil::FileLockException(__FILE__, __LINE__, GetLastError(), _path); + } +#endif + // + // In Windows implementation we don't write the process pid to the file, as it is + // not possible to read the file from other process while it is locked here. + // +} + +IceUtilInternal::FileLock::~FileLock() +{ + assert(_fd != INVALID_HANDLE_VALUE); + CloseHandle(_fd); + unlink(_path); +} + +#ifndef __MINGW32__ +wstring +IceUtilInternal::streamFilename(const string& filename) +{ + return stringToWstring(filename, IceUtil::getProcessStringConverter()); +} +#endif + +#else + +// +// Stat +// +int +IceUtilInternal::stat(const string& path, structstat* buffer) +{ + return ::stat(path.c_str(), buffer); +} + +int +IceUtilInternal::remove(const string& path) +{ + return ::remove(path.c_str()); +} + +int +IceUtilInternal::rename(const string& from, const string& to) +{ + return ::rename(from.c_str(), to.c_str()); +} + +int +IceUtilInternal::rmdir(const string& path) +{ + return ::rmdir(path.c_str()); +} + +int +IceUtilInternal::mkdir(const string& path, int perm) +{ + return ::mkdir(path.c_str(), static_cast(perm)); +} + +FILE* +IceUtilInternal::fopen(const string& path, const string& mode) +{ + return ::fopen(path.c_str(), mode.c_str()); +} + +int +IceUtilInternal::open(const string& path, int flags) +{ + if(flags & O_CREAT) + { + // By default, create with rw-rw-rw- modified by the user's umask (same as fopen). + return ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + } + else + { + return ::open(path.c_str(), flags); + } +} + +int +IceUtilInternal::getcwd(string& cwd) +{ + char cwdbuf[PATH_MAX]; + if(::getcwd(cwdbuf, PATH_MAX) == ICE_NULLPTR) + { + return -1; + } + cwd = cwdbuf; + return 0; +} + +int +IceUtilInternal::unlink(const string& path) +{ + return ::unlink(path.c_str()); +} + +int +IceUtilInternal::close(int fd) +{ + return ::close(fd); +} + +IceUtilInternal::FileLock::FileLock(const std::string& path) : + _fd(-1), + _path(path) +{ + _fd = ::open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if(_fd < 0) + { + throw IceUtil::FileLockException(__FILE__, __LINE__, errno, _path); + } + + struct ::flock lock; + lock.l_type = F_WRLCK; // Write lock + lock.l_whence = SEEK_SET; // Begining of file + lock.l_start = 0; + lock.l_len = 0; + + // + // F_SETLK tells fcntl to not block if it cannot + // acquire the lock, if the lock cannot be acquired + // it returns -1 without wait. + // + if(::fcntl(_fd, F_SETLK, &lock) == -1) + { + int err = errno; + close(_fd); + throw IceUtil::FileLockException(__FILE__, __LINE__, err, _path); + } + + // + // If there is an error after here, we close the fd, + // to release the lock. + // + + // + // Now that we have acquire an excluxive write lock, + // write the process pid there. + // + ostringstream os; + os << getpid(); + + if(write(_fd, os.str().c_str(), os.str().size()) == -1) + { + int err = errno; + close(_fd); + throw IceUtil::FileLockException(__FILE__, __LINE__, err, _path); + } +} + +IceUtilInternal::FileLock::~FileLock() +{ + assert(_fd > -1); + ::close(_fd); + unlink(_path); +} + +#endif diff --git a/Sources/IceCpp/GCObject.cpp b/Sources/IceCpp/GCObject.cpp new file mode 100644 index 0000000..79b5bff --- /dev/null +++ b/Sources/IceCpp/GCObject.cpp @@ -0,0 +1,442 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#ifndef ICE_CPP11_MAPPING + +#include +#include + +using namespace std; +using namespace IceUtil; +using namespace IceInternal; + +namespace +{ + +typedef ::map GCCountMap; +Mutex* gcMutex = 0; + +class Init +{ +public: + + Init() + { + gcMutex = new Mutex(); + } + + ~Init() + { + delete gcMutex; + gcMutex = 0; + } +}; + +Init init; + +class ClearMembers : public GCVisitor +{ +public: + + virtual bool visit(GCObject*); +}; +ClearMembers clearMembers; + +class DecreaseRefCounts : public GCVisitor +{ +public: + + DecreaseRefCounts(GCCountMap&); + + virtual bool visit(GCObject*); + +private: + + GCCountMap& _counts; +}; + +class RestoreRefCountsIfReachable : public GCVisitor +{ +public: + + RestoreRefCountsIfReachable(GCCountMap&); + + virtual bool visit(GCObject*); + +private: + + GCCountMap& _counts; + bool _reachable; +}; + +class MarkCollectable : public GCVisitor +{ +public: + + MarkCollectable(); + + virtual bool visit(GCObject*); + + void visitNeighbor(GCObject*); + +private: + + int _counter; + map _numbers; + stack _p; + stack _s; + + class VisitNeighbors : public IceInternal::GCVisitor + { + public: + + void setVisitor(MarkCollectable*); + virtual bool visit(GCObject*); + + private: + + MarkCollectable* _visitor; + }; + VisitNeighbors _neighborsVisitor; +}; + +class ClearCollectable : public GCVisitor +{ +public: + + virtual bool visit(GCObject*); +}; + +} + +bool +ClearMembers::visit(GCObject*) +{ + return true; +} + +DecreaseRefCounts::DecreaseRefCounts(GCCountMap& counts) : _counts(counts) +{ +} + +bool +DecreaseRefCounts::visit(GCObject* obj) +{ + // + // Visit the object only once when the object is inserted for + // the first time in the counts map. After, we just decrement + // its reference count. Decrementing the reference counts of + // reachable objects will indicate when a cycle is + // collectable. Collectable objects are those with a reference + // count of zero and for which there's no "reachable" parent + // object (objects with a reference count > 0). + // + GCCountMap::iterator p = _counts.find(obj); + if(p == _counts.end()) + { + _counts.insert(make_pair(obj, obj->_iceGetRefUnsafe() - 1)); + if(obj->__hasFlag(GCObject::Collectable)) + { + obj->_iceGcVisitMembers(*this); + } + } + else + { + --p->second; + } + return false; +} + +RestoreRefCountsIfReachable::RestoreRefCountsIfReachable(GCCountMap& counts) : _counts(counts), _reachable(false) +{ +} + +bool +RestoreRefCountsIfReachable::visit(GCObject* obj) +{ + GCCountMap::iterator p = _counts.find(obj); + if(p == _counts.end()) + { + // + // If the object has been removed from the counts map, + // it's reachable. + // + return false; + } + else if(_reachable) + { + // + // If parent object is reachable, this object is also + // reachable. Remove it from the counts map and also make + // reachable children. + // + _counts.erase(p); + obj->_iceGcVisitMembers(*this); + } + else if(p->second == 0) + { + // + // If the object is collectable, set its count to -1 to + // indicate that it was already visited prevent it from + // being visited again. + // + p->second = -1; + obj->_iceGcVisitMembers(*this); + } + else if(p->second > 0) + { + // + // Object isn't collectable, remove it from the counts map + // and visit its sub-graph to remove children wobjects from + // the counts map since they are also reachable. + // + _counts.erase(p); + + _reachable = true; + obj->_iceGcVisitMembers(*this); + _reachable = false; + } + return false; +} + +MarkCollectable::MarkCollectable() : _counter(0) +{ + _neighborsVisitor.setVisitor(this); +} + +bool +MarkCollectable::visit(GCObject* obj) +{ + // + // Set the collectable flag on the object graph. While setting the + // flag, we also check if the object graph has cycles and mark all the + // objects which are part of a cycle with the CycleMember flag. + // + // We use the path-based strong component algorithm to detect the + // strong components of the graph. + // + + if(obj->__hasFlag(GCObject::Collectable)) + { + return false; + } + obj->__setFlag(GCObject::Collectable); + + _numbers[obj] = ++_counter; + _p.push(obj); + _s.push(obj); + + obj->_iceGcVisitMembers(_neighborsVisitor); + + if(_p.top() == obj) + { + GCObject* o; + do + { + o = _s.top(); + _s.pop(); + o->__setFlag(GCObject::CycleMember); + } + while(o != obj); + _p.pop(); + } + return false; +} + +void +MarkCollectable::visitNeighbor(GCObject* obj) +{ + map::const_iterator p = _numbers.find(obj); + if(p == _numbers.end()) + { + visit(obj); + } + else if(!obj->__hasFlag(GCObject::CycleMember)) + { + while(_numbers[_p.top()] > p->second) + { + _p.pop(); + } + } +} + +void +MarkCollectable::VisitNeighbors::setVisitor(MarkCollectable* visitor) +{ + _visitor = visitor; +} + +bool +MarkCollectable::VisitNeighbors::visit(GCObject* obj) +{ + _visitor->visitNeighbor(obj); + return false; +} + +bool +ClearCollectable::visit(GCObject* obj) +{ + // + // Clear the collectable flag on the object graph. + // + if(obj->__hasFlag(GCObject::Collectable)) + { + obj->__clearFlag(GCObject::Collectable | GCObject::CycleMember); + obj->_iceGcVisitMembers(*this); + } + return false; +} + +// +// Flags constant used for collection of graphs. +// +const unsigned char GCObject::Collectable = 2; +const unsigned char GCObject::CycleMember = 4; +const unsigned char GCObject::Visiting = 8; + +// +// GCObject +// +void +IceInternal::GCObject::__incRef() +{ + IceUtilInternal::MutexPtrLock lock(gcMutex); + ++_ref; +} + +void +IceInternal::GCObject::__decRef() +{ + IceUtilInternal::MutexPtrLock lock(gcMutex); + bool doDelete = false; + assert(_ref > 0); + + // + // Try to collect the object each time its reference count is + // decremented and only if it's part of a cycle. + // + if(_ref > 1 && __hasFlag(CycleMember) && collect(lock)) + { + return; + } + + if(--_ref == 0) + { + doDelete = !__hasFlag(NoDelete); + __setFlag(NoDelete); + } + + lock.release(); + if(doDelete) + { + delete this; + } +} + +int +IceInternal::GCObject::__getRef() const +{ + IceUtilInternal::MutexPtrLock lock(gcMutex); + return _ref; +} + +void +IceInternal::GCObject::__setNoDelete(bool b) +{ + IceUtilInternal::MutexPtrLock lock(gcMutex); + IceUtil::Shared::__setNoDelete(b); +} + +bool +GCObject::_iceGcVisit(GCVisitor& v) +{ + return v.visit(this); +} + +void +GCObject::ice_collectable(bool enable) +{ + IceUtilInternal::MutexPtrLock lock(gcMutex); + if(enable) + { + ClearCollectable().visit(this); + MarkCollectable().visit(this); + } + else + { + ClearCollectable().visit(this); + } +} + +bool +GCObject::collect(IceUtilInternal::MutexPtrLock& lock) +{ + GCCountMap counts; + + // + // Go through the object graph and decrease reference counts for + // all the objects from the graph. Cycles which can be collected + // should lead to objects with a zero reference count. + // + DecreaseRefCounts(counts).visit(this); + assert(counts.find(this) != counts.end()); + if(counts[this] > 0) + { + return false; // Object is still reachable, we're done. + } + + // + // Go the graph again and check for objects which are still + // reachable. If there are any, we restore the reference counts + // for the sub-graph of the reachable object and we remove the + // reachable objects from the counts map. At the end, if the + // counts map is empty, it indicates that this object graph isn't + // collectable yet. + // + RestoreRefCountsIfReachable(counts).visit(this); + if(counts.empty()) + { + return false; + } + + assert(counts.find(this) != counts.end()); // This object must be collectable. + + // + // At this point, we can release the lock. The objects from counts + // are un-reachable from the user code and clearing the members of + // the collectable objects requires acquiring the mutex to + // decrement their reference counts. + // + lock.release(); + + // + // Break all the cyclic reference counts of objects which are + // remaining in the counts map by clearing members. + // + // We first go through the list to mark all the objects as + // non-deletable and we also disable collection for all those + // objects since we already know they are collectable. + // + // After clearing members, we delete all the collectable + // objects. We can't just delete the objects since those objects + // likely point to each other. + // + for(GCCountMap::const_iterator p = counts.begin(); p != counts.end(); ++p) + { + p->first->__setFlag(NoDelete); + p->first->__clearFlag(CycleMember); // Disable cycle collection. + } + for(GCCountMap::const_iterator p = counts.begin(); p != counts.end(); ++p) + { + p->first->_iceGcVisitMembers(clearMembers); + } + for(GCCountMap::const_iterator p = counts.begin(); p != counts.end(); ++p) + { + delete p->first; + } + return true; +} +#endif diff --git a/Sources/IceCpp/HttpParser.cpp b/Sources/IceCpp/HttpParser.cpp new file mode 100644 index 0000000..1553d7e --- /dev/null +++ b/Sources/IceCpp/HttpParser.cpp @@ -0,0 +1,684 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceInternal::WebSocketException::WebSocketException(const string& r) : + reason(r) +{ +} + +IceInternal::HttpParser::HttpParser() : + _type(TypeUnknown), + _versionMajor(0), + _versionMinor(0), + _status(0), + _state(StateInit) +{ +} + +const Ice::Byte* +IceInternal::HttpParser::isCompleteMessage(const Ice::Byte* begin, const Ice::Byte* end) const +{ + const Ice::Byte* p = begin; + + // + // Skip any leading CR-LF characters. + // + while(p < end) + { + char ch = static_cast(*p); + if(ch != '\r' && ch != '\n') + { + break; + } + ++p; + } + + // + // Look for adjacent CR-LF/CR-LF or LF/LF. + // + bool seenFirst = false; + while(p < end) + { + char ch = static_cast(*p++); + if(ch == '\n') + { + if(seenFirst) + { + return p; + } + else + { + seenFirst = true; + } + } + else if(ch != '\r') + { + seenFirst = false; + } + } + + return 0; +} + +bool +IceInternal::HttpParser::parse(const Ice::Byte* begin, const Ice::Byte* end) +{ + const Ice::Byte* p = begin; + const Ice::Byte* start = 0; + const string::value_type CR = '\r'; + const string::value_type LF = '\n'; + + if(_state == StateComplete) + { + _state = StateInit; + } + + while(p != end && _state != StateComplete) + { + char c = static_cast(*p); + + switch(_state) + { + case StateInit: + { + _method.clear(); + _uri.clear(); + _versionMajor = -1; + _versionMinor = -1; + _status = -1; + _reason.clear(); + _headers.clear(); + _state = StateType; + continue; + } + case StateType: + { + if(c == CR || c == LF) + { + break; + } + else if(c == 'H') + { + // + // Could be the start of "HTTP/1.1" or "HEAD". + // + _state = StateTypeCheck; + break; + } + else + { + _state = StateRequest; + continue; + } + } + case StateTypeCheck: + { + if(c == 'T') // Continuing "H_T_TP/1.1" + { + _state = StateResponse; + } + else if(c == 'E') // Expecting "HEAD" + { + _state = StateRequest; + _method.push_back('H'); + _method.push_back('E'); + } + else + { + throw WebSocketException("malformed request or response"); + } + break; + } + case StateRequest: + { + _type = TypeRequest; + _state = StateRequestMethod; + continue; + } + case StateRequestMethod: + { + if(c == ' ' || c == CR || c == LF) + { + _state = StateRequestMethodSP; + continue; + } + _method.push_back(c); + break; + } + case StateRequestMethodSP: + { + if(c == ' ') + { + break; + } + else if(c == CR || c == LF) + { + throw WebSocketException("malformed request"); + } + _state = StateRequestURI; + continue; + } + case StateRequestURI: + { + if(c == ' ' || c == CR || c == LF) + { + _state = StateRequestURISP; + continue; + } + _uri.push_back(c); + break; + } + case StateRequestURISP: + { + if(c == ' ') + { + break; + } + else if(c == CR || c == LF) + { + throw WebSocketException("malformed request"); + } + _state = StateVersion; + continue; + } + case StateRequestLF: + { + if(c != LF) + { + throw WebSocketException("malformed request"); + } + _state = StateHeaderFieldStart; + break; + } + case StateHeaderFieldStart: + { + // + // We've already seen a LF to reach this state. + // + // Another CR or LF indicates the end of the header fields. + // + if(c == CR) + { + _state = StateHeaderFieldEndLF; + break; + } + else if(c == LF) + { + _state = StateComplete; + break; + } + else if(c == ' ') + { + // + // Could be a continuation line. + // + _state = StateHeaderFieldContStart; + break; + } + + _state = StateHeaderFieldNameStart; + continue; + } + case StateHeaderFieldContStart: + { + if(c == ' ') + { + break; + } + + _state = StateHeaderFieldCont; + start = p; + continue; + } + case StateHeaderFieldCont: + { + if(c == CR || c == LF) + { + if(p > start) + { + if(_headerName.empty()) + { + throw WebSocketException("malformed header"); + } + HeaderFields::iterator q = _headers.find(_headerName); + assert(q != _headers.end()); + q->second.second = q->second.second + " " + string(start, p); + _state = c == CR ? StateHeaderFieldLF : StateHeaderFieldStart; + } + else + { + // + // Could mark the end of the header fields. + // + _state = c == CR ? StateHeaderFieldEndLF : StateComplete; + } + } + + break; + } + case StateHeaderFieldNameStart: + { + assert(c != ' '); + start = p; + _headerName.clear(); + _state = StateHeaderFieldName; + continue; + } + case StateHeaderFieldName: + { + if(c == ' ' || c == ':') + { + _state = StateHeaderFieldNameEnd; + continue; + } + else if(c == CR || c == LF) + { + throw WebSocketException("malformed header"); + } + break; + } + case StateHeaderFieldNameEnd: + { + if(_headerName.empty()) + { + _headerName = IceUtilInternal::toLower(string(start, p)); + HeaderFields::iterator q = _headers.find(_headerName); + // + // Add a placeholder entry if necessary. + // + if(q == _headers.end()) + { + _headers[_headerName] = make_pair(string(start, p), ""); + } + } + + if(c == ' ') + { + break; + } + else if(c != ':' || p == start) + { + throw WebSocketException("malformed header"); + } + + _state = StateHeaderFieldValueStart; + break; + } + case StateHeaderFieldValueStart: + { + if(c == ' ') + { + break; + } + + // + // Check for "Name:\r\n" + // + if(c == CR) + { + _state = StateHeaderFieldLF; + break; + } + else if(c == LF) + { + _state = StateHeaderFieldStart; + break; + } + + start = p; + _state = StateHeaderFieldValue; + continue; + } + case StateHeaderFieldValue: + { + if(c == CR || c == LF) + { + _state = StateHeaderFieldValueEnd; + continue; + } + break; + } + case StateHeaderFieldValueEnd: + { + assert(c == CR || c == LF); + if(p > start) + { + HeaderFields::iterator q = _headers.find(_headerName); + if(q == _headers.end()) + { + throw WebSocketException("malformed header"); + } + else if(q->second.second.empty()) + { + q->second.second = string(start, p); + } + else + { + q->second.second = q->second.second + ", " + string(start, p); + } + } + + if(c == CR) + { + _state = StateHeaderFieldLF; + } + else + { + _state = StateHeaderFieldStart; + } + break; + } + case StateHeaderFieldLF: + { + if(c != LF) + { + throw WebSocketException("malformed header"); + } + _state = StateHeaderFieldStart; + break; + } + case StateHeaderFieldEndLF: + { + if(c != LF) + { + throw WebSocketException("malformed header"); + } + _state = StateComplete; + break; + } + case StateVersion: + { + if(c != 'H') + { + throw WebSocketException("malformed version"); + } + _state = StateVersionH; + break; + } + case StateVersionH: + { + if(c != 'T') + { + throw WebSocketException("malformed version"); + } + _state = StateVersionHT; + break; + } + case StateVersionHT: + { + if(c != 'T') + { + throw WebSocketException("malformed version"); + } + _state = StateVersionHTT; + break; + } + case StateVersionHTT: + { + if(c != 'P') + { + throw WebSocketException("malformed version"); + } + _state = StateVersionHTTP; + break; + } + case StateVersionHTTP: + { + if(c != '/') + { + throw WebSocketException("malformed version"); + } + _state = StateVersionMajor; + break; + } + case StateVersionMajor: + { + if(c == '.') + { + if(_versionMajor == -1) + { + throw WebSocketException("malformed version"); + } + _state = StateVersionMinor; + break; + } + else if(c < '0' || c > '9') + { + throw WebSocketException("malformed version"); + } + if(_versionMajor == -1) + { + _versionMajor = 0; + } + _versionMajor *= 10; + _versionMajor += (c - '0'); + break; + } + case StateVersionMinor: + { + if(c == CR) + { + if(_versionMinor == -1 || _type != TypeRequest) + { + throw WebSocketException("malformed version"); + } + _state = StateRequestLF; + break; + } + else if(c == LF) + { + if(_versionMinor == -1 || _type != TypeRequest) + { + throw WebSocketException("malformed version"); + } + _state = StateHeaderFieldStart; + break; + } + else if(c == ' ') + { + if(_versionMinor == -1 || _type != TypeResponse) + { + throw WebSocketException("malformed version"); + } + _state = StateResponseVersionSP; + break; + } + else if(c < '0' || c > '9') + { + throw WebSocketException("malformed version"); + } + if(_versionMinor == -1) + { + _versionMinor = 0; + } + _versionMinor *= 10; + _versionMinor += (c - '0'); + break; + } + case StateResponse: + { + _type = TypeResponse; + _state = StateVersionHT; + continue; + } + case StateResponseVersionSP: + { + if(c == ' ') + { + break; + } + + _state = StateResponseStatus; + continue; + } + case StateResponseStatus: + { + // TODO: Is reason string optional? + if(c == CR) + { + if(_status == -1) + { + throw WebSocketException("malformed response status"); + } + _state = StateResponseLF; + break; + } + else if(c == LF) + { + if(_status == -1) + { + throw WebSocketException("malformed response status"); + } + _state = StateHeaderFieldStart; + break; + } + else if(c == ' ') + { + if(_status == -1) + { + throw WebSocketException("malformed response status"); + } + _state = StateResponseReasonStart; + break; + } + else if(c < '0' || c > '9') + { + throw WebSocketException("malformed response status"); + } + if(_status == -1) + { + _status = 0; + } + _status *= 10; + _status += (c - '0'); + break; + } + case StateResponseReasonStart: + { + // + // Skip leading spaces. + // + if(c == ' ') + { + break; + } + + _state = StateResponseReason; + start = p; + continue; + } + case StateResponseReason: + { + if(c == CR || c == LF) + { + if(p > start) + { + _reason = string(start, p); + } + _state = c == CR ? StateResponseLF : StateHeaderFieldStart; + } + + break; + } + case StateResponseLF: + { + if(c != LF) + { + throw WebSocketException("malformed status line"); + } + _state = StateHeaderFieldStart; + break; + } + case StateComplete: + { + assert(false); // Shouldn't reach + } + } + + ++p; + } + + return _state == StateComplete; +} + +HttpParser::Type +IceInternal::HttpParser::type() const +{ + return _type; +} + +string +IceInternal::HttpParser::method() const +{ + assert(_type == TypeRequest); + return _method; +} + +string +IceInternal::HttpParser::uri() const +{ + assert(_type == TypeRequest); + return _uri; +} + +int +IceInternal::HttpParser::versionMajor() const +{ + return _versionMajor; +} + +int +IceInternal::HttpParser::versionMinor() const +{ + return _versionMinor; +} + +int +IceInternal::HttpParser::status() const +{ + return _status; +} + +string +IceInternal::HttpParser::reason() const +{ + return _reason; +} + +bool +IceInternal::HttpParser::getHeader(const string& name, string& value, bool toLower) const +{ + HeaderFields::const_iterator q = _headers.find(IceUtilInternal::toLower(name)); + if(q != _headers.end()) + { + value = IceUtilInternal::trim(q->second.second); + if(toLower) + { + value = IceUtilInternal::toLower(value); + } + return true; + } + + return false; +} + +map +IceInternal::HttpParser::getHeaders() const +{ + map headers; + for(HeaderFields::const_iterator q = _headers.begin(); q != _headers.end(); ++q) + { + headers.insert(make_pair(q->second.first, IceUtilInternal::trim(q->second.second))); + } + return headers; +} diff --git a/Sources/IceCpp/IPEndpointI.cpp b/Sources/IceCpp/IPEndpointI.cpp new file mode 100644 index 0000000..f5fc057 --- /dev/null +++ b/Sources/IceCpp/IPEndpointI.cpp @@ -0,0 +1,710 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; +using namespace IceInternal; + +namespace +{ + +IceUtil::Mutex* hashMutex = 0; + +class Init +{ +public: + + Init() + { + hashMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete hashMutex; + hashMutex = 0; + } +}; + +Init init; + +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(IPEndpointI* p) { return p; } +#endif +IceUtil::Shared* IceInternal::upCast(EndpointHostResolver* p) { return p; } + +IceInternal::IPEndpointInfoI::IPEndpointInfoI(const EndpointIPtr& endpoint) : _endpoint(endpoint) +{ +} + +IceInternal::IPEndpointInfoI::~IPEndpointInfoI() +{ +} + +Ice::Short +IceInternal::IPEndpointInfoI::type() const ICE_NOEXCEPT +{ + return _endpoint->type(); +} + +bool +IceInternal::IPEndpointInfoI::datagram() const ICE_NOEXCEPT +{ + return _endpoint->datagram(); +} + +bool +IceInternal::IPEndpointInfoI::secure() const ICE_NOEXCEPT +{ + return _endpoint->secure(); +} + +Ice::EndpointInfoPtr +IceInternal::IPEndpointI::getInfo() const ICE_NOEXCEPT +{ + Ice::IPEndpointInfoPtr info = ICE_MAKE_SHARED(IPEndpointInfoI, ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + fillEndpointInfo(info.get()); + return info; +} + +Ice::Short +IceInternal::IPEndpointI::type() const +{ + return _instance->type(); +} + +const string& +IceInternal::IPEndpointI::protocol() const +{ + return _instance->protocol(); +} + +bool +IceInternal::IPEndpointI::secure() const +{ + return _instance->secure(); +} + +void +IceInternal::IPEndpointI::streamWriteImpl(OutputStream* s) const +{ + s->write(_host, false); + s->write(_port); +} + +const string& +IceInternal::IPEndpointI::connectionId() const +{ + return _connectionId; +} + +EndpointIPtr +IceInternal::IPEndpointI::connectionId(const string& connectionId) const +{ + if(connectionId == _connectionId) + { + return ICE_SHARED_FROM_CONST_THIS(IPEndpointI); + } + else + { + return createEndpoint(_host, _port, connectionId); + } +} + +void +IceInternal::IPEndpointI::connectors_async(Ice::EndpointSelectionType selType, const EndpointI_connectorsPtr& cb) const +{ + _instance->resolve(_host, _port, selType, ICE_SHARED_FROM_CONST_THIS(IPEndpointI), cb); +} + +vector +IceInternal::IPEndpointI::expandIfWildcard() const +{ + vector endps; + vector hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport(), false); + if(hosts.empty()) + { + endps.push_back(ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + } + else + { + for(vector::const_iterator p = hosts.begin(); p != hosts.end(); ++p) + { + endps.push_back(createEndpoint(*p, _port, _connectionId)); + } + } + return endps; +} + +vector +IceInternal::IPEndpointI::expandHost(EndpointIPtr& publish) const +{ + // + // If this endpoint has an empty host (wildcard address), don't expand, just return + // this endpoint. + // + if(_host.empty()) + { + vector endpoints; + endpoints.push_back(ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + return endpoints; + } + + // + // If using a fixed port, this endpoint can be used as the published endpoint to + // access the returned endpoints. Otherwise, we'll publish each individual expanded + // endpoint. + // + if(_port > 0) + { + publish = ICE_SHARED_FROM_CONST_THIS(IPEndpointI); + } + + vector
addrs = getAddresses(_host, + _port, + _instance->protocolSupport(), + Ice::ICE_ENUM(EndpointSelectionType, Ordered), + _instance->preferIPv6(), + true); + + vector endpoints; + if(addrs.size() == 1) + { + endpoints.push_back(ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + } + else + { + for(vector
::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + string host; + int port; + addrToAddressAndPort(*p, host, port); + endpoints.push_back(createEndpoint(host, port, _connectionId)); + } + } + return endpoints; +} + +bool +IceInternal::IPEndpointI::equivalent(const EndpointIPtr& endpoint) const +{ + const IPEndpointI* ipEndpointI = dynamic_cast(endpoint.get()); + if(!ipEndpointI) + { + return false; + } + return ipEndpointI->type() == type() && ipEndpointI->_host == _host && ipEndpointI->_port == _port; +} + +Ice::Int +IceInternal::IPEndpointI::hash() const +{ + IceUtilInternal::MutexPtrLock lock(hashMutex); + if(!_hashInitialized) + { + _hashValue = 5381; + hashAdd(_hashValue, type()); + hashInit(_hashValue); + _hashInitialized = true; + } + return _hashValue; +} + +string +IceInternal::IPEndpointI::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + + if(!_host.empty()) + { + s << " -h "; + bool addQuote = _host.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _host; + if(addQuote) + { + s << "\""; + } + } + + s << " -p " << _port; + + if(isAddressValid(_sourceAddr)) + { + const string sourceAddr = inetAddrToString(_sourceAddr); + bool addQuote = sourceAddr.find(':') != string::npos; + s << " --sourceAddress "; + if(addQuote) + { + s << "\""; + } + s << sourceAddr; + if(addQuote) + { + s << "\""; + } + } + + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::IPEndpointI::operator==(const Endpoint& r) const +#else +IceInternal::IPEndpointI::operator==(const LocalObject& r) const +#endif +{ + const IPEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_host != p->_host) + { + return false; + } + + if(_port != p->_port) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + if(compareAddress(_sourceAddr, p->_sourceAddr) != 0) + { + return false; + } + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::IPEndpointI::operator<(const Endpoint& r) const +#else +IceInternal::IPEndpointI::operator<(const LocalObject& r) const +#endif +{ + const IPEndpointI* p = dynamic_cast(&r); + if(!p) + { + const EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(type() < p->type()) + { + return true; + } + else if(p->type() < type()) + { + return false; + } + + if(_host < p->_host) + { + return true; + } + else if(p->_host < _host) + { + return false; + } + + if(_port < p->_port) + { + return true; + } + else if(p->_port < _port) + { + return false; + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + + int rc = compareAddress(_sourceAddr, p->_sourceAddr); + if(rc < 0) + { + return true; + } + else if(rc > 0) + { + return false; + } + + return false; +} + +vector +IceInternal::IPEndpointI::connectors(const vector
& addresses, const NetworkProxyPtr& proxy) const +{ + vector connectors; + for(unsigned int i = 0; i < addresses.size(); ++i) + { + connectors.push_back(createConnector(addresses[i], proxy)); + } + return connectors; +} + +void +IceInternal::IPEndpointI::hashInit(Ice::Int& h) const +{ + hashAdd(h, _host); + hashAdd(h, _port); + hashAdd(h, _connectionId); + if(isAddressValid(_sourceAddr)) + { + hashAdd(h, inetAddrToString(_sourceAddr)); + } +} + +void +IceInternal::IPEndpointI::fillEndpointInfo(Ice::IPEndpointInfo* info) const +{ + info->host = _host; + info->port = _port; + info->sourceAddress = inetAddrToString(_sourceAddr); +} + +void +IceInternal::IPEndpointI::initWithOptions(vector& args, bool oaEndpoint) +{ + EndpointI::initWithOptions(args); + + if(_host.empty()) + { + const_cast(_host) = _instance->defaultHost(); + } + else if(_host == "*") + { + if(oaEndpoint) + { + const_cast(_host) = string(); + } + else + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "`-h *' not valid for proxy endpoint `" + toString() + + "'"); + } + } + + if(isAddressValid(_sourceAddr)) + { + if(oaEndpoint) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, + "`--sourceAddress' not valid for object adapter endpoint `" + toString() + + "'"); + } + } + else if(!oaEndpoint) + { + const_cast(_sourceAddr) = _instance->defaultSourceAddress(); + } +} + +bool +IceInternal::IPEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + if(option == "-h") + { + if(argument.empty()) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "no argument provided for -h option in endpoint " + + endpoint); + } + const_cast(_host) = argument; + } + else if(option == "-p") + { + if(argument.empty()) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "no argument provided for -p option in endpoint " + + endpoint); + } + istringstream p(argument); + if(!(p >> const_cast(_port)) || !p.eof()) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "invalid port value `" + argument + "' in endpoint " + + endpoint); + } + else if(_port < 0 || _port > 65535) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "port value `" + argument + + "' out of range in endpoint " + endpoint); + } + } + else if(option == "--sourceAddress") + { + if(argument.empty()) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, + "no argument provided for --sourceAddress option in endpoint " + + endpoint); + } + const_cast(_sourceAddr) = getNumericAddress(argument); + if(!isAddressValid(_sourceAddr)) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, + "invalid IP address provided for --sourceAddress option in endpoint " + + endpoint); + } + } + else + { + return false; + } + return true; +} + +IceInternal::IPEndpointI::IPEndpointI(const ProtocolInstancePtr& instance, const string& host, int port, + const Address& sourceAddr, const string& connectionId) : + _instance(instance), + _host(host), + _port(port), + _sourceAddr(sourceAddr), + _connectionId(connectionId), + _hashInitialized(false) +{ +} + +IceInternal::IPEndpointI::IPEndpointI(const ProtocolInstancePtr& instance) : + _instance(instance), + _port(0), + _hashInitialized(false) +{ +} + +IceInternal::IPEndpointI::IPEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : + _instance(instance), + _port(0), + _hashInitialized(false) +{ + s->read(const_cast(_host), false); + s->read(const_cast(_port)); +} + +IceInternal::EndpointHostResolver::EndpointHostResolver(const InstancePtr& instance) : + IceUtil::Thread("Ice.HostResolver"), + _instance(instance), + _protocol(instance->protocolSupport()), + _preferIPv6(instance->preferIPv6()), + _destroyed(false) +{ + updateObserver(); +} + +void +IceInternal::EndpointHostResolver::resolve(const string& host, int port, Ice::EndpointSelectionType selType, + const IPEndpointIPtr& endpoint, const EndpointI_connectorsPtr& callback) +{ + // + // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve + // entry and the thread will take care of getting the endpoint addresses. + // + NetworkProxyPtr networkProxy = _instance->networkProxy(); + if(!networkProxy) + { + try + { + vector
addrs = getAddresses(host, port, _protocol, selType, _preferIPv6, false); + if(!addrs.empty()) + { + callback->connectors(endpoint->connectors(addrs, 0)); + return; + } + } + catch(const Ice::LocalException& ex) + { + callback->exception(ex); + return; + } + } + + Lock sync(*this); + assert(!_destroyed); + + ResolveEntry entry; + entry.host = host; + entry.port = port; + entry.selType = selType; + entry.endpoint = endpoint; + entry.callback = callback; + + const CommunicatorObserverPtr& obsv = _instance->initializationData().observer; + if(obsv) + { + entry.observer = obsv->getEndpointLookupObserver(endpoint); + if(entry.observer) + { + entry.observer->attach(); + } + } + + _queue.push_back(entry); + notify(); +} + +void +IceInternal::EndpointHostResolver::destroy() +{ + Lock sync(*this); + assert(!_destroyed); + _destroyed = true; + notify(); +} + +void +IceInternal::EndpointHostResolver::run() +{ + while(true) + { + ResolveEntry r; + ThreadObserverPtr threadObserver; + { + Lock sync(*this); + while(!_destroyed && _queue.empty()) + { + wait(); + } + + if(_destroyed) + { + break; + } + + r = _queue.front(); + _queue.pop_front(); + threadObserver = _observer.get(); + } + + if(threadObserver) + { + threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateIdle), ICE_ENUM(ThreadState, ThreadStateInUseForOther)); + } + + try + { + NetworkProxyPtr networkProxy = _instance->networkProxy(); + ProtocolSupport protocol = _protocol; + if(networkProxy) + { + networkProxy = networkProxy->resolveHost(_protocol); + if(networkProxy) + { + protocol = networkProxy->getProtocolSupport(); + } + } + + vector
addresses = getAddresses(r.host, r.port, protocol, r.selType, _preferIPv6, true); + if(r.observer) + { + r.observer->detach(); + r.observer = 0; + } + + r.callback->connectors(r.endpoint->connectors(addresses, networkProxy)); + + if(threadObserver) + { + threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), + ICE_ENUM(ThreadState, ThreadStateIdle)); + } + + } + catch(const Ice::LocalException& ex) + { + if(threadObserver) + { + threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), + ICE_ENUM(ThreadState, ThreadStateIdle)); + } + if(r.observer) + { + r.observer->failed(ex.ice_id()); + r.observer->detach(); + } + r.callback->exception(ex); + } + } + + for(deque::const_iterator p = _queue.begin(); p != _queue.end(); ++p) + { + Ice::CommunicatorDestroyedException ex(__FILE__, __LINE__); + if(p->observer) + { + p->observer->failed(ex.ice_id()); + p->observer->detach(); + } + p->callback->exception(ex); + } + _queue.clear(); + + if(_observer) + { + _observer.detach(); + } +} + +void +IceInternal::EndpointHostResolver::updateObserver() +{ + Lock sync(*this); + const CommunicatorObserverPtr& obsv = _instance->initializationData().observer; + if(obsv) + { + _observer.attach(obsv->getThreadObserver("Communicator", + name(), + ICE_ENUM(ThreadState, ThreadStateIdle), + _observer.get())); + } +} diff --git a/Sources/IceCpp/IconvStringConverter.cpp b/Sources/IceCpp/IconvStringConverter.cpp new file mode 100644 index 0000000..3babf46 --- /dev/null +++ b/Sources/IceCpp/IconvStringConverter.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#ifndef _WIN32 + +using namespace std; +using namespace Ice; +using namespace IceUtil; + +IconvInitializationException::IconvInitializationException(const char* file, int line, const string& reason) : + ExceptionHelper(file, line), + _reason(reason) +{ +} + +#ifndef ICE_CPP11_COMPILER +IconvInitializationException::~IconvInitializationException() throw() +{ +} +#endif + +void +IconvInitializationException::ice_print(ostream& out) const +{ + IceUtil::Exception::ice_print(out); + out << ": " << _reason; +} + +string +IconvInitializationException::ice_id() const +{ + return "::Ice::IconvInitializationException"; +} + +#ifndef ICE_CPP11_MAPPING +IconvInitializationException* +IconvInitializationException::ice_clone() const +{ + return new IconvInitializationException(*this); +} +#endif + +string +IconvInitializationException::reason() const +{ + return _reason; +} +#endif diff --git a/Sources/IceCpp/Identity.cpp b/Sources/IceCpp/Identity.cpp new file mode 100644 index 0000000..8b16fa5 --- /dev/null +++ b/Sources/IceCpp/Identity.cpp @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Identity.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ImplicitContext.cpp b/Sources/IceCpp/ImplicitContext.cpp new file mode 100644 index 0000000..15aa80d --- /dev/null +++ b/Sources/IceCpp/ImplicitContext.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContext.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ImplicitContext::~ImplicitContext() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ImplicitContext::~ImplicitContext() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ImplicitContext* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ImplicitContextF.cpp b/Sources/IceCpp/ImplicitContextF.cpp new file mode 100644 index 0000000..11eea36 --- /dev/null +++ b/Sources/IceCpp/ImplicitContextF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContextF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ImplicitContextI.cpp b/Sources/IceCpp/ImplicitContextI.cpp new file mode 100644 index 0000000..82cb8b7 --- /dev/null +++ b/Sources/IceCpp/ImplicitContextI.cpp @@ -0,0 +1,655 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; + +namespace +{ + +class SharedImplicitContext : public ImplicitContextI +{ +public: + + virtual Context getContext() const; + virtual void setContext(const Context&); + + virtual bool containsKey(const string&) const; + virtual string get(const string&) const; + virtual string put(const string&, const string&); + virtual string remove(const string&); + + virtual void write(const Context&, ::Ice::OutputStream*) const; + virtual void combine(const Context&, Context&) const; + +private: + Context _context; + IceUtil::Mutex _mutex; +}; + +class PerThreadImplicitContext : public ImplicitContextI +{ +public: + + PerThreadImplicitContext(); + virtual ~PerThreadImplicitContext(); + + virtual Context getContext() const; + virtual void setContext(const Context&); + + virtual bool containsKey(const string&) const; + virtual string get(const string&) const; + virtual string put(const string&, const string&); + virtual string remove(const string&); + + virtual void write(const Context&, ::Ice::OutputStream*) const; + virtual void combine(const Context&, Context&) const; + + struct Slot + { + Slot() : + context(0), + owner(-1) // just to avoid UMR; a random value would work as well + { + } + + Context* context; + long owner; + }; + + // + // Each thread maintains a SlotVector. Each PerThreadImplicitContext instance + // is assigned a slot in this vector. + // + typedef std::vector SlotVector; + + // + // We remember which slot-indices are in use (to be able to reuse indices) + // + typedef std::vector IndexInUse; + static IndexInUse* _indexInUse; + static IceUtil::Mutex* _mutex; + + static long _nextId; + static long _destroyedIds; + static size_t _slotVectors; + +#ifdef _WIN32 + static DWORD _key; +#else + static pthread_key_t _key; +#endif + + static void tryCleanupKey(); // must be called with _mutex locked + +private: + + Context* getThreadContext(bool) const; + void clearThreadContext() const; + + size_t _index; // index in all SlotVector + long _id; // corresponds to owner in the Slot +}; +} + +extern "C" void iceImplicitContextThreadDestructor(void*); + +ImplicitContextIPtr +ImplicitContextI::create(const std::string& kind) +{ + if(kind == "None" || kind == "") + { + return 0; + } + else if(kind == "Shared") + { + return ICE_MAKE_SHARED(SharedImplicitContext); + } + else if(kind == "PerThread") + { + return ICE_MAKE_SHARED(PerThreadImplicitContext); + } + else + { + throw Ice::InitializationException( + __FILE__, __LINE__, + "'" + kind + "' is not a valid value for Ice.ImplicitContext"); + } +} + +#if defined(_WIN32) +void +ImplicitContextI::cleanupThread() +{ + if(PerThreadImplicitContext::_nextId > 0) + { + iceImplicitContextThreadDestructor(TlsGetValue(PerThreadImplicitContext::_key)); + } +} +#endif + +// +// SharedImplicitContext implementation +// + +Context +SharedImplicitContext::getContext() const +{ + IceUtil::Mutex::Lock lock(_mutex); + return _context; +} + +void +SharedImplicitContext::setContext(const Context& newContext) +{ + IceUtil::Mutex::Lock lock(_mutex); + _context = newContext; +} + +bool +SharedImplicitContext::containsKey(const string& k) const +{ + IceUtil::Mutex::Lock lock(_mutex); + Context::const_iterator p = _context.find(k); + return p != _context.end(); +} + +string +SharedImplicitContext::get(const string& k) const +{ + IceUtil::Mutex::Lock lock(_mutex); + Context::const_iterator p = _context.find(k); + if(p == _context.end()) + { + return ""; + } + return p->second; +} + +string +SharedImplicitContext::put(const string& k, const string& v) +{ + IceUtil::Mutex::Lock lock(_mutex); + string& val = _context[k]; + + string oldVal = val; + val = v; + return oldVal; +} + +string +SharedImplicitContext::remove(const string& k) +{ + IceUtil::Mutex::Lock lock(_mutex); + Context::iterator p = _context.find(k); + if(p == _context.end()) + { + return ""; + } + else + { + string oldVal = p->second; + _context.erase(p); + return oldVal; + } +} + +void +SharedImplicitContext::write(const Context& proxyCtx, ::Ice::OutputStream* s) const +{ + IceUtil::Mutex::Lock lock(_mutex); + if(proxyCtx.size() == 0) + { + s->write(_context); + } + else if(_context.size() == 0) + { + lock.release(); + s->write(proxyCtx); + } + else + { + Context combined = proxyCtx; + combined.insert(_context.begin(), _context.end()); + lock.release(); + s->write(combined); + } +} + +void +SharedImplicitContext::combine(const Context& proxyCtx, Context& ctx) const +{ + IceUtil::Mutex::Lock lock(_mutex); + if(proxyCtx.size() == 0) + { + ctx = _context; + } + else if(_context.size() == 0) + { + ctx = proxyCtx; + } + else + { + ctx = proxyCtx; + ctx.insert(_context.begin(), _context.end()); + } +} + +// +// PerThreadImplicitContext implementation +// +long PerThreadImplicitContext::_nextId; +long PerThreadImplicitContext::_destroyedIds; +size_t PerThreadImplicitContext::_slotVectors; +PerThreadImplicitContext::IndexInUse* PerThreadImplicitContext::_indexInUse; +IceUtil::Mutex* PerThreadImplicitContext::_mutex = 0; + +namespace +{ + +class Init +{ +public: + + Init() + { + PerThreadImplicitContext::_mutex = new IceUtil::Mutex; + } + + ~Init() + { + delete PerThreadImplicitContext::_mutex; + PerThreadImplicitContext::_mutex = 0; + } +}; + +Init init; + +} + +# ifdef _WIN32 +DWORD PerThreadImplicitContext::_key; +# else +pthread_key_t PerThreadImplicitContext::_key; +# endif + +PerThreadImplicitContext::PerThreadImplicitContext() +{ + IceUtilInternal::MutexPtrLock lock(_mutex); + _id = _nextId++; + if(_id == 0) + { +# ifdef _WIN32 + _key = TlsAlloc(); + if(_key == TLS_OUT_OF_INDEXES) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +# else + int err = pthread_key_create(&_key, &iceImplicitContextThreadDestructor); + if(err != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, err); + } +# endif + } + + // + // Now grab an index + // + if(_indexInUse == 0) + { + _indexInUse = new IndexInUse(1); + } + size_t i = 0; + while(i < _indexInUse->size() && (*_indexInUse)[i]) + { + i++; + } + + if(i == _indexInUse->size()) + { + _indexInUse->resize(i + 1); + } + (*_indexInUse)[i] = true; + _index = i; +} + +PerThreadImplicitContext::~PerThreadImplicitContext() +{ + IceUtilInternal::MutexPtrLock lock(_mutex); + (*_indexInUse)[_index] = false; + + if(find(_indexInUse->begin(), _indexInUse->end(), true) == _indexInUse->end()) + { + delete _indexInUse; + _indexInUse = 0; + } + + _destroyedIds++; + tryCleanupKey(); +} + +void +PerThreadImplicitContext::tryCleanupKey() +{ + if(_destroyedIds == _nextId && _slotVectors == 0) + { + // + // We can do a full reset + // + _nextId = 0; + _destroyedIds = 0; +# ifdef _WIN32 + TlsFree(_key); +# else + pthread_key_delete(_key); +# endif + } +} + +Context* +PerThreadImplicitContext::getThreadContext(bool allocate) const +{ +# ifdef _WIN32 + SlotVector* sv = static_cast(TlsGetValue(_key)); +# else + SlotVector* sv = static_cast(pthread_getspecific(_key)); +# endif + if(sv == 0) + { + if(!allocate) + { + return 0; + } + + { + IceUtilInternal::MutexPtrLock lock(_mutex); + sv = new SlotVector(_index + 1); + _slotVectors++; + } + +# ifdef _WIN32 + + if(TlsSetValue(_key, sv) == 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +# else + if(int err = pthread_setspecific(_key, sv)) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, err); + } +# endif + } + else + { + if(sv->size() <= _index) + { + if(!allocate) + { + return 0; + } + else + { + sv->resize(_index + 1); + } + } + } + + Slot& slot = (*sv)[_index]; + if(slot.context != 0) + { + if(slot.owner != _id) + { + // + // Reuse the slot from another (dead) communicator + // + slot.context->clear(); + slot.owner = _id; + } + // + // else keep this slot.context + // + } + else + { + if(allocate) + { + slot.context = new Context; + slot.owner = _id; + } + // + // else keep null slot.context + // + } + return slot.context; +} + +void +PerThreadImplicitContext::clearThreadContext() const +{ +# ifdef _WIN32 + SlotVector* sv = static_cast(TlsGetValue(_key)); +# else + SlotVector* sv = static_cast(pthread_getspecific(_key)); +# endif + if(sv != 0 && _index < sv->size()) + { + delete (*sv)[_index].context; + (*sv)[_index].context = 0; + + // + // Trim tailing empty contexts. + // + size_t i = sv->size(); + + bool clear = true; + while(i != 0) + { + i--; + if((*sv)[i].context != 0) + { + clear = false; + break; + } + } + + // + // If we did not find any contexts, delete the SlotVector. + // + if(clear) + { + delete sv; +# ifdef _WIN32 + if(TlsSetValue(_key, 0) == 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +# else + if(int err = pthread_setspecific(_key, 0)) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, err); + } + + { + IceUtilInternal::MutexPtrLock lock(_mutex); + _slotVectors--; + } +# endif + } + else + { + sv->resize(i + 1); + } + } +} + +Context +PerThreadImplicitContext::getContext() const +{ + Context* ctx = getThreadContext(false); + if(ctx == 0) + { + return Context(); + } + else + { + return *ctx; + } +} + +void +PerThreadImplicitContext::setContext(const Context& newContext) +{ + if(newContext.size() == 0) + { + clearThreadContext(); + } + else + { + Context* ctx = getThreadContext(true); + assert(ctx != 0); + *ctx = newContext; + } +} + +bool +PerThreadImplicitContext::containsKey(const string& k) const +{ + const Context* ctx = getThreadContext(false); + if(ctx == 0) + { + return false; + } + Context::const_iterator p = ctx->find(k); + return p != ctx->end(); +} + +string +PerThreadImplicitContext::get(const string& k) const +{ + const Context* ctx = getThreadContext(false); + if(ctx == 0) + { + return ""; + } + Context::const_iterator p = ctx->find(k); + if(p == ctx->end()) + { + return ""; + } + return p->second; +} + +string +PerThreadImplicitContext::put(const string& k, const string& v) +{ + Context* ctx = getThreadContext(true); + + string& val = (*ctx)[k]; + + string oldVal = val; + val = v; + return oldVal; +} + +string +PerThreadImplicitContext::remove(const string& k) +{ + Context* ctx = getThreadContext(false); + if(ctx == 0) + { + return ""; + } + + Context::iterator p = ctx->find(k); + if(p == ctx->end()) + { + return ""; + } + else + { + string oldVal = p->second; + ctx->erase(p); + + if(ctx->size() == 0) + { + clearThreadContext(); + } + return oldVal; + } +} + +void +PerThreadImplicitContext::write(const Context& proxyCtx, ::Ice::OutputStream* s) const +{ + const Context* threadCtx = getThreadContext(false); + + if(threadCtx == 0 || threadCtx->size() == 0) + { + s->write(proxyCtx); + } + else if(proxyCtx.size() == 0) + { + s->write(*threadCtx); + } + else + { + Context combined = proxyCtx; + combined.insert(threadCtx->begin(), threadCtx->end()); + s->write(combined); + } +} + +void +PerThreadImplicitContext::combine(const Context& proxyCtx, Context& ctx) const +{ + const Context* threadCtx = getThreadContext(false); + + if(threadCtx == 0 || threadCtx->size() == 0) + { + ctx = proxyCtx; + } + else if(proxyCtx.size() == 0) + { + ctx = *threadCtx; + } + else + { + ctx = proxyCtx; + ctx.insert(threadCtx->begin(), threadCtx->end()); + } +} + +extern "C" void iceImplicitContextThreadDestructor(void* v) +{ + PerThreadImplicitContext::SlotVector* sv = static_cast(v); + if(sv != 0) + { + // + // Cleanup each slot + // + for(PerThreadImplicitContext::SlotVector::iterator p = sv->begin(); p != sv->end(); ++p) + { + delete p->context; + } + // + // Then the vector + // + delete sv; + + { + IceUtilInternal::MutexPtrLock lock(PerThreadImplicitContext::_mutex); + PerThreadImplicitContext::_slotVectors--; + PerThreadImplicitContext::tryCleanupKey(); + } + } +} diff --git a/Sources/IceCpp/Incoming.cpp b/Sources/IceCpp/Incoming.cpp new file mode 100644 index 0000000..b7cc914 --- /dev/null +++ b/Sources/IceCpp/Incoming.cpp @@ -0,0 +1,795 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; +using namespace IceInternal; + +namespace IceUtilInternal +{ + +extern bool printStackTraces; + +} + +#ifdef ICE_CPP11_MAPPING +Ice::MarshaledResult::MarshaledResult(const Ice::Current& current) : + ostr(make_shared(current.adapter->getCommunicator(), Ice::currentProtocolEncoding)) +{ + ostr->writeBlob(replyHdr, sizeof(replyHdr)); + ostr->write(current.requestId); + ostr->write(replyOK); +} +#endif + +IceInternal::IncomingBase::IncomingBase(Instance* instance, ResponseHandler* responseHandler, + Ice::Connection* connection, const ObjectAdapterPtr& adapter, + bool response, Byte compress, Int requestId) : + _response(response), + _compress(compress), + _format(Ice::ICE_ENUM(FormatType, DefaultFormat)), + _os(instance, Ice::currentProtocolEncoding), + _responseHandler(responseHandler) +{ + _current.adapter = adapter; +#ifdef ICE_CPP11_MAPPING + ::Ice::ConnectionI* conn = dynamic_cast<::Ice::ConnectionI*>(connection); + _current.con = conn ? conn->shared_from_this() : nullptr; +#else + _current.con = connection; +#endif + _current.requestId = requestId; + _current.encoding.major = 0; + _current.encoding.minor = 0; +} + +IceInternal::IncomingBase::IncomingBase(IncomingBase& other) : + IceUtil::noncopyable(), // TODO, remove noncopyable base class + _current(other._current), + _servant(other._servant), + _locator(other._locator), + _cookie(other._cookie), + _response(other._response), + _compress(other._compress), + _format(other._format), + _os(other._os.instance(), Ice::currentProtocolEncoding), + _responseHandler(other._responseHandler), + _interceptorCBs(other._interceptorCBs) +{ + _observer.adopt(other._observer); +} + +OutputStream* +IncomingBase::startWriteParams() +{ + if(!_response) + { + throw MarshalException(__FILE__, __LINE__, "can't marshal out parameters for oneway dispatch"); + } + + assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. + + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyOK); + _os.startEncapsulation(_current.encoding, _format); + return &_os; +} + +void +IncomingBase::endWriteParams() +{ + if(_response) + { + _os.endEncapsulation(); + } +} + +void +IncomingBase::writeEmptyParams() +{ + if(_response) + { + assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyOK); + _os.writeEmptyEncapsulation(_current.encoding); + } +} + +void +IncomingBase::writeParamEncaps(const Byte* v, Ice::Int sz, bool ok) +{ + if(!ok) + { + _observer.userException(); + } + + if(_response) + { + assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(ok ? replyOK : replyUserException); + if(sz == 0) + { + _os.writeEmptyEncapsulation(_current.encoding); + } + else + { + _os.writeEncapsulation(v, sz); + } + } +} + +#ifdef ICE_CPP11_MAPPING +void +IceInternal::IncomingBase::setMarshaledResult(const Ice::MarshaledResult& result) +{ + result.getOutputStream()->swap(_os); +} +#endif + +void +IceInternal::IncomingBase::response(bool amd) +{ + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + + assert(_responseHandler); + if(_response) + { + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } + + _observer.detach(); + _responseHandler = 0; +} + +void +IceInternal::IncomingBase::exception(const std::exception& exc, bool amd) +{ + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + handleException(exc, amd); + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } +} + +void +IceInternal::IncomingBase::exception(const string& msg, bool amd) +{ + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + handleException(msg, amd); + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } +} + +void +IceInternal::IncomingBase::warning(const Exception& ex) const +{ + Warning out(_os.instance()->initializationData().logger); + + ToStringMode toStringMode = _os.instance()->toStringMode(); + + out << "dispatch exception: " << ex; + out << "\nidentity: " << identityToString(_current.id, toStringMode); + out << "\nfacet: "; + out << escapeString(_current.facet, "", toStringMode); + out << "\noperation: " << _current.operation; + + if(_current.con) + { + try + { + for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying) + { + Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); + if(ipConnInfo) + { + out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + break; + } + } + } + catch(const Ice::LocalException&) + { + // Ignore. + } + } +} + +void +IceInternal::IncomingBase::warning(const string& msg) const +{ + Warning out(_os.instance()->initializationData().logger); + ToStringMode toStringMode = _os.instance()->toStringMode(); + + out << "dispatch exception: " << msg; + out << "\nidentity: " << identityToString(_current.id, toStringMode); + out << "\nfacet: " << escapeString(_current.facet, "", toStringMode); + out << "\noperation: " << _current.operation; + + if(_current.con) + { + for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying) + { + Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo); + if(ipConnInfo) + { + out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort; + break; + } + } + } +} + +bool +IceInternal::IncomingBase::servantLocatorFinished(bool amd) +{ + assert(_locator && _servant); + try + { + _locator->finished(_current, _servant, _cookie); + return true; + } + catch(const std::exception& ex) + { + handleException(ex, amd); + } + catch(...) + { + handleException("unknown c++ exception", amd); + } + return false; +} + +void +IceInternal::IncomingBase::handleException(const std::exception& exc, bool amd) +{ + assert(_responseHandler); + + // Reset the stream, it's possible the marshalling of the response failed and left + // the stream in an unknown state. + _os.clear(); + _os.b.clear(); + + if(const SystemException* ex = dynamic_cast(&exc)) + { + if(_responseHandler->systemException(_current.requestId, *ex, amd)) + { + return; + } + } + + if(dynamic_cast(&exc)) + { + RequestFailedException* rfe = + const_cast(dynamic_cast(&exc)); + + if(rfe->id.name.empty()) + { + rfe->id = _current.id; + } + + if(rfe->facet.empty() && !_current.facet.empty()) + { + rfe->facet = _current.facet; + } + + if(rfe->operation.empty() && !_current.operation.empty()) + { + rfe->operation = _current.operation; + } + + if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) + { + warning(*rfe); + } + + if(_observer) + { + _observer.failed(rfe->ice_id()); + } + + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + if(dynamic_cast(rfe)) + { + _os.write(replyObjectNotExist); + } + else if(dynamic_cast(rfe)) + { + _os.write(replyFacetNotExist); + } + else if(dynamic_cast(rfe)) + { + _os.write(replyOperationNotExist); + } + else + { + assert(false); + } + + _os.write(rfe->id); + + // + // For compatibility with the old FacetPath. + // + if(rfe->facet.empty()) + { + _os.write(static_cast(0), static_cast(0)); + } + else + { + _os.write(&rfe->facet, &rfe->facet + 1); + } + + _os.write(rfe->operation, false); + + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + else if(const UserException* uex = dynamic_cast(&exc)) + { + _observer.userException(); + + // + // The operation may have already marshaled a reply; we must overwrite that reply. + // + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyUserException); + _os.startEncapsulation(_current.encoding, _format); + _os.write(*uex); + _os.endEncapsulation(); + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + else if(const Exception* ex = dynamic_cast(&exc)) + { + if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + warning(*ex); + } + + if(_observer) + { + _observer.failed(ex->ice_id()); + } + + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + if(const UnknownLocalException* ule = dynamic_cast(&exc)) + { + _os.write(replyUnknownLocalException); + _os.write(ule->unknown, false); + } + else if(const UnknownUserException* uue = dynamic_cast(&exc)) + { + _os.write(replyUnknownUserException); + _os.write(uue->unknown, false); + } + else if(const UnknownException* ue = dynamic_cast(&exc)) + { + _os.write(replyUnknownException); + _os.write(ue->unknown, false); + } + else if(const LocalException* le = dynamic_cast(&exc)) + { + _os.write(replyUnknownLocalException); + ostringstream str; + str << *le; + if(IceUtilInternal::printStackTraces) + { + str << '\n' << ex->ice_stackTrace(); + } + _os.write(str.str(), false); + } + else if(const UserException* use = dynamic_cast(&exc)) + { + _os.write(replyUnknownUserException); + ostringstream str; + str << *use; + if(IceUtilInternal::printStackTraces) + { + str << '\n' << ex->ice_stackTrace(); + } + _os.write(str.str(), false); + } + else + { + _os.write(replyUnknownException); + ostringstream str; + str << *ex; + if(IceUtilInternal::printStackTraces) + { + str << '\n' << ex->ice_stackTrace(); + } + _os.write(str.str(), false); + } + + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + else + { + if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + warning(string("std::exception: ") + exc.what()); + } + + if(_observer) + { + _observer.failed(typeid(exc).name()); + } + + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyUnknownException); + ostringstream str; + str << "std::exception: " << exc.what(); + _os.write(str.str(), false); + + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + + _observer.detach(); + _responseHandler = 0; +} + +void +IceInternal::IncomingBase::handleException(const string& msg, bool amd) +{ + if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + warning(msg); + } + + assert(_responseHandler); + + // Reset the stream, it's possible the marshalling of the response failed and left + // the stream in an unknown state. + _os.clear(); + _os.b.clear(); + + if(_observer) + { + _observer.failed("unknown"); + } + + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyUnknownException); + string reason = msg; + _os.write(reason, false); + _observer.reply(static_cast(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + + _observer.detach(); + _responseHandler = 0; +} + +IceInternal::Incoming::Incoming(Instance* instance, ResponseHandler* responseHandler, Ice::Connection* connection, + const ObjectAdapterPtr& adapter, bool response, Byte compress, Int requestId) : + IncomingBase(instance, responseHandler, connection, adapter, response, compress, requestId), + _inParamPos(0) +{ +} + +#ifdef ICE_CPP11_MAPPING +void +IceInternal::Incoming::push(function response, function exception) +{ + _interceptorCBs.push_front(make_pair(response, exception)); +} +#else +void +IceInternal::Incoming::push(const Ice::DispatchInterceptorAsyncCallbackPtr& cb) +{ + _interceptorCBs.push_front(cb); +} +#endif + +void +IceInternal::Incoming::pop() +{ + _interceptorCBs.pop_front(); +} + +void +IceInternal::Incoming::startOver() +{ + if(_inParamPos == 0) + { + // + // That's the first startOver, so almost nothing to do + // + _inParamPos = _is->i; + } + else + { + // Reset input stream's position and clear response + if(_inAsync) + { + _inAsync->kill(*this); + _inAsync = 0; + } + _os.clear(); + _os.b.clear(); + + _is->i = _inParamPos; + } +} + +void +IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager, InputStream* stream) +{ + _is = stream; + + InputStream::Container::iterator start = _is->i; + + // + // Read the current. + // + _is->read(_current.id); + + // + // For compatibility with the old FacetPath. + // + string facet; + { + vector facetPath; + _is->read(facetPath); + if(!facetPath.empty()) + { + if(facetPath.size() > 1) + { + throw MarshalException(__FILE__, __LINE__); + } + facet.swap(facetPath[0]); + } + } + _current.facet.swap(facet); + + _is->read(_current.operation, false); + + Byte b; + _is->read(b); + _current.mode = static_cast(b); + + Int sz = _is->readSize(); + while(sz--) + { + pair pr; + _is->read(const_cast(pr.first)); + _is->read(pr.second); + _current.ctx.insert(_current.ctx.end(), pr); + } + + const CommunicatorObserverPtr& obsv = _is->instance()->initializationData().observer; + if(obsv) + { + // Read the parameter encapsulation size. + Ice::Int encapsSize; + _is->read(encapsSize); + _is->i -= 4; + + _observer.attach(obsv->getDispatchObserver(_current, static_cast(_is->i - start + encapsSize))); + } + + // + // Don't put the code above into the try block below. Exceptions + // in the code above are considered fatal, and must propagate to + // the caller of this operation. + // + + if(servantManager) + { + _servant = servantManager->findServant(_current.id, _current.facet); + if(!_servant) + { + _locator = servantManager->findServantLocator(_current.id.category); + if(!_locator && !_current.id.category.empty()) + { + _locator = servantManager->findServantLocator(""); + } + + if(_locator) + { + try + { + _servant = _locator->locate(_current, _cookie); + } + catch(const std::exception& ex) + { + skipReadParams(); // Required for batch requests. + handleException(ex, false); + return; + } + catch(...) + { + skipReadParams(); // Required for batch requests. + handleException("unknown c++ exception", false); + return; + } + } + } + } + + if(!_servant) + { + try + { + if(servantManager && servantManager->hasServant(_current.id)) + { + throw FacetNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation); + } + else + { + throw ObjectNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation); + } + } + catch(const Ice::LocalException& ex) + { + skipReadParams(); // Required for batch requests + handleException(ex, false); + return; + } + } + + try + { + // + // Dispatch in the incoming call + // + _servant->_iceDispatch(*this, _current); + + // + // If the request was not dispatched asynchronously, send the response. + // + if(!_inAsync) + { + response(false); + } + } + catch(const std::exception& ex) + { + if(_inAsync) + { + try + { + _inAsync->kill(*this); + } + catch(const Ice::ResponseSentException&) + { + const Ice::PropertiesPtr properties = _os.instance()->initializationData().properties; + if(properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + if(const IceUtil::Exception* exc = dynamic_cast(&ex)) + { + warning(*exc); + } + else + { + warning(string("std::exception: ") + ex.what()); + } + } + return; + } + } + exception(ex, false); + } + catch(...) + { + if(_inAsync) + { + try + { + _inAsync->kill(*this); + } + catch(const Ice::ResponseSentException&) + { + const Ice::PropertiesPtr properties = _os.instance()->initializationData().properties; + if(properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + warning("unknown c++ exception"); + } + return; + } + } + exception("unknown c++ exception", false); + } +} + +const Current& +IceInternal::IncomingRequest::getCurrent() +{ + return _in.getCurrent(); +} diff --git a/Sources/IceCpp/IncomingAsync.cpp b/Sources/IceCpp/IncomingAsync.cpp new file mode 100644 index 0000000..9841e9e --- /dev/null +++ b/Sources/IceCpp/IncomingAsync.cpp @@ -0,0 +1,230 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(IncomingAsync* p) { return p; } +IceUtil::Shared* Ice::upCast(AMD_Object_ice_invoke* p) { return p; } + +Ice::AMDCallback::~AMDCallback() +{ + // Out of line to avoid weak vtable +} + +Ice::AMD_Object_ice_invoke::~AMD_Object_ice_invoke() +{ + // Out of line to avoid weak vtable +} +#endif + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +} + +IceInternal::IncomingAsync::IncomingAsync(Incoming& in) : + IncomingBase(in), + _responseSent(false), + _responseHandlerCopy(ICE_GET_SHARED_FROM_THIS(_responseHandler)) +{ +#ifndef ICE_CPP11_MAPPING + in.setAsync(this); +#endif +} + +#ifdef ICE_CPP11_MAPPING +shared_ptr +IceInternal::IncomingAsync::create(Incoming& in) +{ + auto async = make_shared(in); + in.setAsync(async); + return async; +} +#endif + +#ifndef ICE_CPP11_MAPPING +void +IceInternal::IncomingAsync::ice_exception(const ::std::exception& exc) +{ + try + { + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) + { + if(!(*p)->exception(exc)) + { + return; + } + } + } + catch(...) + { + return; + } + + checkResponseSent(); + IncomingBase::exception(exc, true); // User thread +} + +void +IceInternal::IncomingAsync::ice_exception() +{ + try + { + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) + { + if(!(*p)->exception()) + { + return; + } + } + } + catch(...) + { + return; + } + + checkResponseSent(); + IncomingBase::exception("unknown c++ exception", true); // User thread +} + +#endif + +void +IceInternal::IncomingAsync::kill(Incoming& in) +{ + checkResponseSent(); + in._observer.adopt(_observer); // Give back the observer to incoming. +} + +void +IceInternal::IncomingAsync::completed() +{ + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) + { + try + { +#ifdef ICE_CPP11_MAPPING + if(p->first && !p->first()) +#else + if(!(*p)->response()) +#endif + { + return; + } + } + catch(...) + { + } + } + + checkResponseSent(); + IncomingBase::response(true); // User thread +} + +#ifdef ICE_CPP11_MAPPING +void +IceInternal::IncomingAsync::completed(exception_ptr ex) +{ + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) + { + try + { + if(p->second && !p->second(ex)) + { + return; + } + } + catch(...) + { + } + } + + checkResponseSent(); + try + { + rethrow_exception(ex); + } + catch(const std::exception& exc) + { + IncomingBase::exception(exc, true); // User thread + } + catch(...) + { + IncomingBase::exception("unknown c++ exception", true); // User thread + } +} +#endif + +void +IceInternal::IncomingAsync::checkResponseSent() +{ + IceUtil::Mutex::Lock sync(*globalMutex); + if(_responseSent) + { + throw ResponseSentException(__FILE__, __LINE__); + } + _responseSent = true; +} + +#ifndef ICE_CPP11_MAPPING +IceAsync::Ice::AMD_Object_ice_invoke::AMD_Object_ice_invoke(Incoming& in) : IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_Object_ice_invoke::ice_response(bool ok, const vector& outEncaps) +{ + if(outEncaps.empty()) + { + writeParamEncaps(0, 0, ok); + } + else + { + writeParamEncaps(&outEncaps[0], static_cast(outEncaps.size()), ok); + } + completed(); +} + +void +IceAsync::Ice::AMD_Object_ice_invoke::ice_response(bool ok, const pair& outEncaps) +{ + writeParamEncaps(outEncaps.first, static_cast(outEncaps.second - outEncaps.first), ok); + completed(); +} +#endif diff --git a/Sources/IceCpp/Initialize.cpp b/Sources/IceCpp/Initialize.cpp new file mode 100644 index 0000000..5fd948b --- /dev/null +++ b/Sources/IceCpp/Initialize.cpp @@ -0,0 +1,654 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; +Ice::LoggerPtr processLogger; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +} + +StringSeq +Ice::argsToStringSeq(int argc, const char* const argv[]) +{ + StringSeq result; + for(int i = 0; i < argc; i++) + { + result.push_back(argv[i]); + } + return result; +} + +#ifdef _WIN32 + +StringSeq +Ice::argsToStringSeq(int /*argc*/, const wchar_t* const argv[]) +{ + // + // Don't need to use a wide string converter argv is expected to + // come from Windows API. + // + const StringConverterPtr converter = getProcessStringConverter(); + StringSeq args; + for(int i = 0; argv[i] != 0; i++) + { + args.push_back(wstringToString(argv[i], converter)); + } + return args; +} + +#endif + +void +Ice::stringSeqToArgs(const StringSeq& args, int& argc, const char* argv[]) +{ + // + // Shift all elements in argv which are present in args to the + // beginning of argv. We record the original value of argc so + // that we can know later if we've shifted the array. + // + const int argcOrig = argc; + int i = 0; + while(i < argc) + { + if(find(args.begin(), args.end(), argv[i]) == args.end()) + { + for(int j = i; j < argc - 1; j++) + { + argv[j] = argv[j + 1]; + } + --argc; + } + else + { + ++i; + } + } + + // + // Make sure that argv[argc] == 0, the ISO C++ standard requires this. + // We can only do this if we've shifted the array, otherwise argv[argc] + // may point to an invalid address. + // + if(argv && argcOrig != argc) + { + argv[argc] = 0; + } +} + +#ifdef _WIN32 +void +Ice::stringSeqToArgs(const StringSeq& args, int& argc, const wchar_t* argv[]) +{ + // + // Don't need to use a wide string converter argv is expected to + // come from Windows API. + // + const StringConverterPtr converter = getProcessStringConverter(); + + // + // Shift all elements in argv which are present in args to the + // beginning of argv. We record the original value of argc so + // that we can know later if we've shifted the array. + // + const int argcOrig = argc; + int i = 0; + while(i < argc) + { + if(find(args.begin(), args.end(), wstringToString(argv[i], converter)) == args.end()) + { + for(int j = i; j < argc - 1; j++) + { + argv[j] = argv[j + 1]; + } + --argc; + } + else + { + ++i; + } + } + + // + // Make sure that argv[argc] == 0, the ISO C++ standard requires this. + // We can only do this if we've shifted the array, otherwise argv[argc] + // may point to an invalid address. + // + if(argv && argcOrig != argc) + { + argv[argc] = 0; + } +} +#endif + +PropertiesPtr +Ice::createProperties() +{ + return ICE_MAKE_SHARED(PropertiesI); +} + +PropertiesPtr +Ice::createProperties(StringSeq& args, const PropertiesPtr& defaults) +{ + return ICE_MAKE_SHARED(PropertiesI, args, defaults); +} + +PropertiesPtr +Ice::createProperties(int& argc, const char* argv[], const PropertiesPtr& defaults) +{ + StringSeq args = argsToStringSeq(argc, argv); + PropertiesPtr properties = createProperties(args, defaults); + stringSeqToArgs(args, argc, argv); + return properties; +} + +#ifdef _WIN32 +PropertiesPtr +Ice::createProperties(int& argc, const wchar_t* argv[], const PropertiesPtr& defaults) +{ + StringSeq args = argsToStringSeq(argc, argv); + PropertiesPtr properties = createProperties(args, defaults); + stringSeqToArgs(args, argc, argv); + return properties; +} +#endif + +#ifdef ICE_CPP11_MAPPING +Ice::ThreadHookPlugin::ThreadHookPlugin(const CommunicatorPtr& communicator, + function threadStart, + function threadStop) +{ + if(communicator == nullptr) + { + throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); + } + + IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); + instance->setThreadHook(std::move(threadStart), std::move(threadStop)); +} +#else +Ice::ThreadHookPlugin::ThreadHookPlugin(const CommunicatorPtr& communicator, const ThreadNotificationPtr& threadHook) +{ + if(communicator == 0) + { + throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); + } + + IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); + instance->setThreadHook(threadHook); +} +#endif +void +Ice::ThreadHookPlugin::initialize() +{ +} + +void +Ice::ThreadHookPlugin::destroy() +{ +} + +namespace +{ + +inline void checkIceVersion(int version) +{ +#ifndef ICE_IGNORE_VERSION + +# if ICE_INT_VERSION % 100 > 50 + // + // Beta version: exact match required + // + if(ICE_INT_VERSION != version) + { + throw VersionMismatchException(__FILE__, __LINE__); + } +# else + + // + // Major and minor version numbers must match. + // + if(ICE_INT_VERSION / 100 != version / 100) + { + throw VersionMismatchException(__FILE__, __LINE__); + } + + // + // Reject beta caller + // + if(version % 100 > 50) + { + throw VersionMismatchException(__FILE__, __LINE__); + } + + // + // The caller's patch level cannot be greater than library's patch level. (Patch level changes are + // backward-compatible, but not forward-compatible.) + // + if(version % 100 > ICE_INT_VERSION % 100) + { + throw VersionMismatchException(__FILE__, __LINE__); + } + +# endif +#endif +} + +} + +Ice::CommunicatorPtr +Ice::initialize(int& argc, const char* argv[], const InitializationData& initializationData, int version) +{ + checkIceVersion(version); + + InitializationData initData = initializationData; + initData.properties = createProperties(argc, argv, initData.properties); + + CommunicatorIPtr communicator = CommunicatorI::create(initData); + communicator->finishSetup(argc, argv); + return communicator; +} + +Ice::CommunicatorPtr +Ice::initialize(int& argc, const char* argv[], ICE_CONFIG_FILE_STRING configFile, int version) +{ + InitializationData initData; + initData.properties = createProperties(); + initData.properties->load(configFile); + return initialize(argc, argv, initData, version); +} + +#ifdef _WIN32 +Ice::CommunicatorPtr +Ice::initialize(int& argc, const wchar_t* argv[], const InitializationData& initializationData, int version) +{ + Ice::StringSeq args = argsToStringSeq(argc, argv); + CommunicatorPtr communicator = initialize(args, initializationData, version); + stringSeqToArgs(args, argc, argv); + return communicator; +} + +Ice::CommunicatorPtr +Ice::initialize(int& argc, const wchar_t* argv[], ICE_CONFIG_FILE_STRING configFile, int version) +{ + InitializationData initData; + initData.properties = createProperties(); + initData.properties->load(configFile); + return initialize(argc, argv, initData, version); +} +#endif + +Ice::CommunicatorPtr +Ice::initialize(StringSeq& args, const InitializationData& initializationData, int version) +{ + IceInternal::ArgVector av(args); + CommunicatorPtr communicator = initialize(av.argc, av.argv, initializationData, version); + args = argsToStringSeq(av.argc, av.argv); + return communicator; +} + +Ice::CommunicatorPtr +Ice::initialize(StringSeq& args, ICE_CONFIG_FILE_STRING configFile, int version) +{ + InitializationData initData; + initData.properties = createProperties(); + initData.properties->load(configFile); + return initialize(args, initData, version); +} + +Ice::CommunicatorPtr +Ice::initialize(const InitializationData& initData, int version) +{ + // + // We can't simply call the other initialize() because this one does NOT read + // the config file, while the other one always does. + // + checkIceVersion(version); + + CommunicatorIPtr communicator = CommunicatorI::create(initData); + int argc = 0; + const char* argv[] = { 0 }; + communicator->finishSetup(argc, argv); + return communicator; +} + +Ice::CommunicatorPtr +Ice::initialize(ICE_CONFIG_FILE_STRING configFile, int version) +{ + InitializationData initData; + initData.properties = createProperties(); + initData.properties->load(configFile); + return initialize(initData, version); +} + +LoggerPtr +Ice::getProcessLogger() +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + + if(processLogger == ICE_NULLPTR) + { + // + // TODO: Would be nice to be able to use process name as prefix by default. + // + processLogger = ICE_MAKE_SHARED(LoggerI, "", "", true); + } + return processLogger; +} + +void +Ice::setProcessLogger(const LoggerPtr& logger) +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + processLogger = logger; +} + +void +Ice::registerPluginFactory(const std::string& name, PluginFactory factory, bool loadOnInitialize) +{ + IceUtilInternal::MutexPtrLock lock(globalMutex); + PluginManagerI::registerPluginFactory(name, factory, loadOnInitialize); +} + +// +// CommunicatorHolder +// + +Ice::CommunicatorHolder::CommunicatorHolder() +{ +} + +#ifdef ICE_CPP11_MAPPING +Ice::CommunicatorHolder::CommunicatorHolder(shared_ptr communicator) : + _communicator(std::move(communicator)) +{ +} + +Ice::CommunicatorHolder& +Ice::CommunicatorHolder::operator=(shared_ptr communicator) +{ + if(_communicator) + { + _communicator->destroy(); + } + _communicator = std::move(communicator); + return *this; +} + +Ice::CommunicatorHolder& +Ice::CommunicatorHolder::operator=(CommunicatorHolder&& other) noexcept +{ + if(_communicator) + { + _communicator->destroy(); + } + _communicator = std::move(other._communicator); + return *this; +} + +#else // C++98 mapping + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, const char* argv[], const InitializationData& initData, + int version) : + _communicator(initialize(argc, argv, initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, char* argv[], const InitializationData& initData, int version) : + _communicator(initialize(argc, argv, initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, const char* argv[], const char* configFile, int version) : + _communicator(initialize(argc, argv, configFile, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, char* argv[], const char* configFile, int version) : + _communicator(initialize(argc, argv, configFile, version)) +{ +} + +# ifdef _WIN32 +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, const wchar_t* argv[], const InitializationData& initData, + int version) : + _communicator(initialize(argc, argv, initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, wchar_t* argv[], const InitializationData& initData, + int version) : + _communicator(initialize(argc, argv, initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, const wchar_t* argv[], const char* configFile, int version) : + _communicator(initialize(argc, argv, configFile, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(int& argc, wchar_t* argv[], const char* configFile, int version) : + _communicator(initialize(argc, argv, configFile, version)) +{ +} +# endif + +Ice::CommunicatorHolder::CommunicatorHolder(StringSeq& args, const InitializationData& initData, int version) : + _communicator(initialize(args, initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(StringSeq& args, const char* configFile, int version) : + _communicator(initialize(args, configFile, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(const InitializationData& initData, int version) : + _communicator(initialize(initData, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(const char* configFile, int version) : + _communicator(initialize(configFile, version)) +{ +} + +Ice::CommunicatorHolder::CommunicatorHolder(const CommunicatorPtr& communicator) : + _communicator(communicator) +{ +} + +Ice::CommunicatorHolder& +Ice::CommunicatorHolder::operator=(const CommunicatorPtr& communicator) +{ + if(_communicator) + { + _communicator->destroy(); + } + _communicator = communicator; + return *this; +} + +#endif + +Ice::CommunicatorHolder::~CommunicatorHolder() +{ + if(_communicator) + { + _communicator->destroy(); + } +} + +Ice::CommunicatorHolder::operator bool() const +{ + return _communicator != ICE_NULLPTR; +} + +const Ice::CommunicatorPtr& +Ice::CommunicatorHolder::communicator() const +{ + return _communicator; +} + +const Ice::CommunicatorPtr& +Ice::CommunicatorHolder::operator->() const +{ + return _communicator; +} + +Ice::CommunicatorPtr +Ice::CommunicatorHolder::release() +{ +#ifdef ICE_CPP11_MAPPING + return std::move(_communicator); +#else + CommunicatorPtr result; + result.swap(_communicator); + return result; +#endif +} + +InstancePtr +IceInternal::getInstance(const CommunicatorPtr& communicator) +{ + CommunicatorIPtr p = ICE_DYNAMIC_CAST(::Ice::CommunicatorI, communicator); + assert(p); + return p->_instance; +} + +IceUtil::TimerPtr +IceInternal::getInstanceTimer(const CommunicatorPtr& communicator) +{ + CommunicatorIPtr p = ICE_DYNAMIC_CAST(::Ice::CommunicatorI, communicator); + assert(p); + return p->_instance->timer(); +} + +Identity +Ice::stringToIdentity(const string& s) +{ + Identity ident; + + // + // Find unescaped separator; note that the string may contain an escaped + // backslash before the separator. + // + string::size_type slash = string::npos; + string::size_type pos = 0; + while((pos = s.find('/', pos)) != string::npos) + { + string::size_type escapes = 0; + while(static_cast(pos - escapes) > 0 && s[pos - escapes - 1] == '\\') + { + escapes++; + } + + // + // We ignore escaped escapes + // + if(escapes % 2 == 0) + { + if(slash == string::npos) + { + slash = pos; + } + else + { + // + // Extra unescaped slash found. + // + throw IdentityParseException(__FILE__, __LINE__, "unescaped '/' in identity `" + s + "'"); + } + } + pos++; + } + + if(slash == string::npos) + { + try + { + ident.name = unescapeString(s, 0, s.size(), "/"); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + throw IdentityParseException(__FILE__, __LINE__, "invalid identity name `" + s + "': " + ex.reason()); + } + } + else + { + try + { + ident.category = unescapeString(s, 0, slash, "/"); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + throw IdentityParseException(__FILE__, __LINE__, "invalid category in identity `" + s + "': " + + ex.reason()); + } + + if(slash + 1 < s.size()) + { + try + { + ident.name = unescapeString(s, slash + 1, s.size(), "/"); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + throw IdentityParseException(__FILE__, __LINE__, "invalid name in identity `" + s + "': " + + ex.reason()); + } + } + } + + return ident; +} + +string +Ice::identityToString(const Identity& ident, ToStringMode toStringMode) +{ + if(ident.category.empty()) + { + return escapeString(ident.name, "/", toStringMode); + } + else + { + return escapeString(ident.category, "/", toStringMode) + '/' + escapeString(ident.name, "/", toStringMode); + } +} diff --git a/Sources/IceCpp/InputStream.cpp b/Sources/IceCpp/InputStream.cpp new file mode 100644 index 0000000..180e6fa --- /dev/null +++ b/Sources/IceCpp/InputStream.cpp @@ -0,0 +1,2741 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_UNALIGNED +# if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64) +# define ICE_UNALIGNED +# endif +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Ice::InputStream::InputStream() +{ + initialize(currentEncoding); +} + +Ice::InputStream::InputStream(const vector& v) : + Buffer(v) +{ + initialize(currentEncoding); +} + +Ice::InputStream::InputStream(const pair& p) : + Buffer(p.first, p.second) +{ + initialize(currentEncoding); +} + +Ice::InputStream::InputStream(Buffer& buf, bool adopt) : + Buffer(buf, adopt) +{ + initialize(currentEncoding); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator) +{ + initialize(communicator); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const vector& v) : + Buffer(v) +{ + initialize(communicator); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const pair& p) : + Buffer(p.first, p.second) +{ + initialize(communicator); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, Buffer& buf, bool adopt) : + Buffer(buf, adopt) +{ + initialize(communicator); +} + +Ice::InputStream::InputStream(const EncodingVersion& encoding) +{ + initialize(encoding); +} + +Ice::InputStream::InputStream(const EncodingVersion& encoding, const vector& v) : + Buffer(v) +{ + initialize(encoding); +} + +Ice::InputStream::InputStream(const EncodingVersion& encoding, const pair& p) : + Buffer(p.first, p.second) +{ + initialize(encoding); +} + +Ice::InputStream::InputStream(const EncodingVersion& encoding, Buffer& buf, bool adopt) : + Buffer(buf, adopt) +{ + initialize(encoding); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding) +{ + initialize(communicator, encoding); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding, + const vector& v) : + Buffer(v) +{ + initialize(communicator, encoding); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding, + const pair& p) : + Buffer(p.first, p.second) +{ + initialize(communicator, encoding); +} + +Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding, + Buffer& buf, bool adopt) : + Buffer(buf, adopt) +{ + initialize(communicator, encoding); +} + +Ice::InputStream::InputStream(Instance* instance, const EncodingVersion& encoding) +{ + initialize(instance, encoding); +} + +Ice::InputStream::InputStream(Instance* instance, const EncodingVersion& encoding, Buffer& buf, bool adopt) : + Buffer(buf, adopt) +{ + initialize(instance, encoding); +} + +void +Ice::InputStream::initialize(const CommunicatorPtr& communicator) +{ + Instance* instance = getInstance(communicator).get(); + initialize(instance, instance->defaultsAndOverrides()->defaultEncoding); +} + +void +Ice::InputStream::initialize(const CommunicatorPtr& communicator, const EncodingVersion& encoding) +{ + initialize(getInstance(communicator).get(), encoding); +} + +void +Ice::InputStream::initialize(Instance* instance, const EncodingVersion& encoding) +{ + initialize(encoding); + + _instance = instance; + +#ifndef ICE_CPP11_MAPPING + _collectObjects = _instance->collectObjects(); +#endif + _traceSlicing = _instance->traceLevels()->slicing > 0; + _classGraphDepthMax = _instance->classGraphDepthMax(); +} + +void +Ice::InputStream::initialize(const EncodingVersion& encoding) +{ + _instance = 0; + _encoding = encoding; + _currentEncaps = 0; +#ifndef ICE_CPP11_MAPPING + _collectObjects = false; +#endif + _traceSlicing = false; + _classGraphDepthMax = 0x7fffffff; + _closure = 0; + _sliceValues = true; + _startSeq = -1; + _minSeqSize = 0; +} + +void +Ice::InputStream::clear() +{ + while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps) + { + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + delete oldEncaps; + } + + _startSeq = -1; + _sliceValues = true; +} + +void +Ice::InputStream::setValueFactoryManager(const ValueFactoryManagerPtr& vfm) +{ + _valueFactoryManager = vfm; +} + +void +Ice::InputStream::setLogger(const LoggerPtr& logger) +{ + _logger = logger; +} + +void +#ifdef ICE_CPP11_MAPPING +Ice::InputStream::setCompactIdResolver(std::function r) +#else +Ice::InputStream::setCompactIdResolver(const CompactIdResolverPtr& r) +#endif +{ + _compactIdResolver = r; +} + +#ifndef ICE_CPP11_MAPPING +void +Ice::InputStream::setCollectObjects(bool on) +{ + _collectObjects = on; +} +#endif + +void +Ice::InputStream::setSliceValues(bool on) +{ + _sliceValues = on; +} + +void +Ice::InputStream::setTraceSlicing(bool on) +{ + _traceSlicing = on; +} + +void +Ice::InputStream::setClassGraphDepthMax(size_t classGraphDepthMax) +{ + if(classGraphDepthMax < 1) + { + _classGraphDepthMax = 0x7fffffff; + } + else + { + _classGraphDepthMax = classGraphDepthMax; + } +} + +void* +Ice::InputStream::getClosure() const +{ + return _closure; +} + +void* +Ice::InputStream::setClosure(void* p) +{ + void* prev = _closure; + _closure = p; + return prev; +} + +void +Ice::InputStream::swap(InputStream& other) +{ + swapBuffer(other); + + std::swap(_instance, other._instance); + std::swap(_encoding, other._encoding); +#ifndef ICE_CPP11_MAPPING + std::swap(_collectObjects, other._collectObjects); +#endif + std::swap(_traceSlicing, other._traceSlicing); + std::swap(_classGraphDepthMax, other._classGraphDepthMax); + std::swap(_closure, other._closure); + std::swap(_sliceValues, other._sliceValues); + + // + // Swap is never called for streams that have encapsulations being read. However, + // encapsulations might still be set in case unmarshaling failed. We just + // reset the encapsulations if there are still some set. + // + resetEncapsulation(); + other.resetEncapsulation(); + + std::swap(_startSeq, other._startSeq); + std::swap(_minSeqSize, other._minSeqSize); + + std::swap(_valueFactoryManager, other._valueFactoryManager); + std::swap(_logger, other._logger); + std::swap(_compactIdResolver, other._compactIdResolver); +} + +void +Ice::InputStream::resetEncapsulation() +{ + while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps) + { + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + delete oldEncaps; + } + + _preAllocatedEncaps.reset(); +} + +Int +Ice::InputStream::getEncapsulationSize() +{ + assert(_currentEncaps); + return _currentEncaps->sz - static_cast(sizeof(Int)) - 2; +} + +EncodingVersion +Ice::InputStream::skipEncapsulation() +{ + Int sz; + read(sz); + if(sz < 6) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + if(i - sizeof(Int) + sz > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + EncodingVersion encoding; + read(encoding.major); + read(encoding.minor); + i += static_cast(sz) - sizeof(Int) - 2; + return encoding; +} + +void +Ice::InputStream::readPendingValues() +{ + if(_currentEncaps && _currentEncaps->decoder) + { + _currentEncaps->decoder->readPendingValues(); + } + else if(getEncoding() == Ice::Encoding_1_0) + { + // + // If using the 1.0 encoding and no instances were read, we + // still read an empty sequence of pending instances if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no instances + // are written we do marshal an empty sequence if marshaled + // data types use classes. + // + skipSize(); + } +} + +Int +Ice::InputStream::readAndCheckSeqSize(int minSize) +{ + Int sz = readSize(); + + if(sz == 0) + { + return sz; + } + + // + // The _startSeq variable points to the start of the sequence for which + // we expect to read at least _minSeqSize bytes from the stream. + // + // If not initialized or if we already read more data than _minSeqSize, + // we reset _startSeq and _minSeqSize for this sequence (possibly a + // top-level sequence or enclosed sequence it doesn't really matter). + // + // Otherwise, we are reading an enclosed sequence and we have to bump + // _minSeqSize by the minimum size that this sequence will require on + // the stream. + // + // The goal of this check is to ensure that when we start un-marshalling + // a new sequence, we check the minimal size of this new sequence against + // the estimated remaining buffer size. This estimatation is based on + // the minimum size of the enclosing sequences, it's _minSeqSize. + // + if(_startSeq == -1 || i > (b.begin() + _startSeq + _minSeqSize)) + { + _startSeq = static_cast(i - b.begin()); + _minSeqSize = sz * minSize; + } + else + { + _minSeqSize += sz * minSize; + } + + // + // If there isn't enough data to read on the stream for the sequence (and + // possibly enclosed sequences), something is wrong with the marshalled + // data: it's claiming having more data that what is possible to read. + // + if(_startSeq + _minSeqSize > static_cast(b.size())) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + return sz; +} + +void +Ice::InputStream::readBlob(vector& v, Int sz) +{ + if(sz > 0) + { + if(b.end() - i < sz) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + vector(i, i + sz).swap(v); + i += sz; + } + else + { + v.clear(); + } +} + +void +Ice::InputStream::read(std::vector& v) +{ + std::pair p; + read(p); + if(p.first != p.second) + { + v.resize(static_cast(p.second - p.first)); + copy(p.first, p.second, v.begin()); + } + else + { + v.clear(); + } +} + +void +Ice::InputStream::read(pair& v) +{ + Int sz = readAndCheckSeqSize(1); + if(sz > 0) + { + v.first = i; + v.second = i + sz; + i += sz; + } + else + { + v.first = v.second = i; + } +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(1); + if(sz > 0) + { + v.resize(static_cast(sz)); + copy(i, i + sz, v.begin()); + i += sz; + } + else + { + v.clear(); + } +} + +namespace +{ + +template +struct ReadBoolHelper +{ + static bool* read(pair& v, Int sz, InputStream::Container::iterator& i) + { + bool* array = new bool[static_cast(sz)]; + for(int idx = 0; idx < sz; ++idx) + { + array[idx] = static_cast(*(i + idx)); + } + v.first = array; + v.second = array + sz; + return array; + } +}; + +template<> +struct ReadBoolHelper<1> +{ + static bool* read(pair& v, Int sz, InputStream::Container::iterator& i) + { + v.first = reinterpret_cast(i); + v.second = reinterpret_cast(i) + sz; + return 0; + } +}; + +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +{ + Int sz = readAndCheckSeqSize(1); + if(sz > 0) + { + auto boolArray = ReadBoolHelper::read(v, sz, i); + if(boolArray) + { + _deleters.push_back([boolArray] { delete[] boolArray; }); + } + i += sz; + } + else + { + v.first = v.second = reinterpret_cast(i); + } +} + +#else +void +Ice::InputStream::read(pair& v, IceUtil::ScopedArray& result) +{ + Int sz = readAndCheckSeqSize(1); + if(sz > 0) + { + result.reset(ReadBoolHelper::read(v, sz, i)); + i += sz; + } + else + { + result.reset(); + v.first = v.second = reinterpret_cast(i); + } +} +#endif + +void +Ice::InputStream::read(Short& v) +{ + if(b.end() - i < static_cast(sizeof(Short))) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Short); +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v) + sizeof(Short) - 1; + *dest-- = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Short))); + if(sz > 0) + { + Container::iterator begin = i; + i += sz * static_cast(sizeof(Short)); + v.resize(static_cast(sz)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&v[0]) + sizeof(Short) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Short); + } +#else + copy(begin, i, reinterpret_cast(&v[0])); +#endif + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +#else +void +Ice::InputStream::read(pair& v, IceUtil::ScopedArray& result) +#endif +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Short))); + if(sz > 0) + { +#ifdef ICE_UNALIGNED + v.first = reinterpret_cast(i); + i += sz * static_cast(sizeof(Short)); + v.second = reinterpret_cast(i); +#else +# ifdef ICE_CPP11_MAPPING + auto result = new short[static_cast(sz)]; + _deleters.push_back([result] { delete[] result; }); + v.first = result; + v.second = result + sz; +# else + result.reset(new Short[static_cast(sz)]); + v.first = result.get(); + v.second = result.get() + sz; +# endif + + Container::iterator begin = i; + i += sz * static_cast(sizeof(Short)); +# ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&result[0]) + sizeof(Short) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Short); + } +# else + copy(begin, i, reinterpret_cast(&result[0])); +# endif +#endif + } + else + { +#ifndef ICE_CPP11_MAPPING + result.reset(); +#endif + v.first = v.second = 0; + } +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Int))); + if(sz > 0) + { + Container::iterator begin = i; + i += sz * static_cast(sizeof(Int)); + v.resize(static_cast(sz)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&v[0]) + sizeof(Int) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Int); + } +#else + copy(begin, i, reinterpret_cast(&v[0])); +#endif + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +#else +void +Ice::InputStream::read(pair& v, ::IceUtil::ScopedArray& result) +#endif +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Int))); + if(sz > 0) + { +#ifdef ICE_UNALIGNED + v.first = reinterpret_cast(i); + i += sz * static_cast(sizeof(Int)); + v.second = reinterpret_cast(i); +#else + +# ifdef ICE_CPP11_MAPPING + auto result = new int[static_cast(sz)]; + _deleters.push_back([result] { delete[] result; }); + v.first = result; + v.second = result + sz; +# else + result.reset(new Int[static_cast(sz)]); + v.first = result.get(); + v.second = result.get() + sz; +# endif + + Container::iterator begin = i; + i += sz * static_cast(sizeof(Int)); +# ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&result[0]) + sizeof(Int) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Int); + } +# else + copy(begin, i, reinterpret_cast(&result[0])); +# endif +#endif + } + else + { +#ifndef ICE_CPP11_MAPPING + result.reset(); +#endif + v.first = v.second = 0; + } +} + +void +Ice::InputStream::read(Long& v) +{ + if(b.end() - i < static_cast(sizeof(Long))) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Long); +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v) + sizeof(Long) - 1; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Long))); + if(sz > 0) + { + Container::iterator begin = i; + i += sz * static_cast(sizeof(Long)); + v.resize(static_cast(sz)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&v[0]) + sizeof(Long) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Long); + } +#else + copy(begin, i, reinterpret_cast(&v[0])); +#endif + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +#else +void +Ice::InputStream::read(pair& v, IceUtil::ScopedArray& result) +#endif +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Long))); + if(sz > 0) + { +#ifdef ICE_UNALIGNED + v.first = reinterpret_cast(i); + i += sz * static_cast(sizeof(Long)); + v.second = reinterpret_cast(i); +#else + +# ifdef ICE_CPP11_MAPPING + auto result = new long long[static_cast(sz)]; + _deleters.push_back([result] { delete[] result; }); + v.first = result; + v.second = result + sz; +# else + result.reset(new Long[static_cast(sz)]); + v.first = result.get(); + v.second = result.get() + sz; +# endif + + Container::iterator begin = i; + i += sz * static_cast(sizeof(Long)); +# ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&result[0]) + sizeof(Long) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Long); + } +# else + copy(begin, i, reinterpret_cast(&result[0])); +# endif +#endif + } + else + { +#ifndef ICE_CPP11_MAPPING + result.reset(); +#endif + v.first = v.second = 0; + } +} + +void +Ice::InputStream::read(Float& v) +{ + if(b.end() - i < static_cast(sizeof(Float))) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Float); +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v) + sizeof(Float) - 1; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Float))); + if(sz > 0) + { + Container::iterator begin = i; + i += sz * static_cast(sizeof(Float)); + v.resize(static_cast(sz)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&v[0]) + sizeof(Float) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Float); + } +#else + copy(begin, i, reinterpret_cast(&v[0])); +#endif + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +#else +void +Ice::InputStream::read(pair& v, IceUtil::ScopedArray& result) +#endif +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Float))); + if(sz > 0) + { +#ifdef ICE_UNALIGNED + v.first = reinterpret_cast(i); + i += sz * static_cast(sizeof(Float)); + v.second = reinterpret_cast(i); +#else + +# ifdef ICE_CPP11_MAPPING + auto result = new float[static_cast(sz)]; + _deleters.push_back([result] { delete[] result; }); + v.first = result; + v.second = result + sz; +# else + result.reset(new Float[static_cast(sz)]); + v.first = result.get(); + v.second = result.get() + sz; +# endif + + Container::iterator begin = i; + i += sz * static_cast(sizeof(Float)); +# ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&result[0]) + sizeof(Float) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Float); + } +# else + copy(begin, i, reinterpret_cast(&result[0])); +# endif +#endif + } + else + { +#ifndef ICE_CPP11_MAPPING + result.reset(); +#endif + v.first = v.second = 0; + } +} + +void +Ice::InputStream::read(Double& v) +{ + if(b.end() - i < static_cast(sizeof(Double))) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Double); +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v) + sizeof(Double) - 1; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::InputStream::read(vector& v) +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Double))); + if(sz > 0) + { + Container::iterator begin = i; + i += sz * static_cast(sizeof(Double)); + v.resize(static_cast(sz)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&v[0]) + sizeof(Double) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Double); + } +#else + copy(begin, i, reinterpret_cast(&v[0])); +#endif + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(pair& v) +#else +void +Ice::InputStream::read(pair& v, IceUtil::ScopedArray& result) +#endif +{ + Int sz = readAndCheckSeqSize(static_cast(sizeof(Double))); + if(sz > 0) + { +#ifdef ICE_UNALIGNED + v.first = reinterpret_cast(i); + i += sz * static_cast(sizeof(Double)); + v.second = reinterpret_cast(i); +#else + +# ifdef ICE_CPP11_MAPPING + auto result = new double[static_cast(sz)]; + _deleters.push_back([result] { delete[] result; }); + v.first = result; + v.second = result + sz; +# else + result.reset(new Double[static_cast(sz)]); + v.first = result.get(); + v.second = result.get() + sz; +# endif + + Container::iterator begin = i; + i += sz * static_cast(sizeof(Double)); +# ifdef ICE_BIG_ENDIAN + const Byte* src = &(*begin); + Byte* dest = reinterpret_cast(&result[0]) + sizeof(Double) - 1; + for(int j = 0 ; j < sz ; ++j) + { + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + dest += 2 * sizeof(Double); + } +# else + copy(begin, i, reinterpret_cast(&result[0])); +# endif +#endif + } + else + { +#ifndef ICE_CPP11_MAPPING + result.reset(); +#endif + v.first = v.second = 0; + } +} + +void +Ice::InputStream::read(std::string& v, bool convert) +{ + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if(!convert || !readConverted(v, sz)) + { + string(reinterpret_cast(&*i), reinterpret_cast(&*i) + sz).swap(v); + } + i += sz; + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +void +Ice::InputStream::read(const char*& vdata, size_t& vsize, bool convert) +{ + int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if(convert == false) + { + vdata = reinterpret_cast(&*i); + vsize = static_cast(sz); + i += sz; + } + else + { + string converted; + if(readConverted(converted, sz)) + { + if(converted.size() <= static_cast(sz)) + { + // + // Write converted string directly into buffer + // + std::memcpy(i, converted.data(), converted.size()); + vdata = reinterpret_cast(&*i); + vsize = converted.size(); + } + else + { + auto holder = new string(std::move(converted)); + _deleters.push_back([holder] { delete holder; }); + vdata = holder->data(); + vsize = holder->size(); + } + } + else + { + vdata = reinterpret_cast(&*i); + vsize = static_cast(sz); + } + i += sz; + } + } + else + { + vdata = 0; + vsize = 0; + } +} + +#else + +void +Ice::InputStream::read(const char*& vdata, size_t& vsize) +{ + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + vdata = reinterpret_cast(&*i); + vsize = static_cast(sz); + i += sz; + } + else + { + vdata = 0; + vsize = 0; + } +} + +void +Ice::InputStream::read(const char*& vdata, size_t& vsize, string& holder) +{ + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if(readConverted(holder, sz)) + { + vdata = holder.data(); + vsize = holder.size(); + } + else + { + vdata = reinterpret_cast(&*i); + vsize = static_cast(sz); + } + i += sz; + } + else + { + holder.clear(); + vdata = 0; + vsize = 0; + } +} +#endif + +bool +Ice::InputStream::readConverted(string& v, int sz) +{ + try + { + bool converted = false; + + // + // NOTE: When using an _instance, we get a const& on the string reference to + // not have to increment unecessarily its reference count. + // + + if(_instance) + { + const StringConverterPtr& stringConverter = _instance->getStringConverter(); + if(stringConverter) + { + stringConverter->fromUTF8(i, i + sz, v); + converted = true; + } + } + else + { + StringConverterPtr stringConverter = getProcessStringConverter(); + if(stringConverter) + { + stringConverter->fromUTF8(i, i + sz, v); + converted = true; + } + } + + return converted; + } + catch(const IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } +} + +void +Ice::InputStream::read(vector& v, bool convert) +{ + Int sz = readAndCheckSeqSize(1); + if(sz > 0) + { + v.resize(static_cast(sz)); + for(size_t j = 0; j < static_cast(sz); ++j) + { + read(v[j], convert); + } + } + else + { + v.clear(); + } +} + +void +Ice::InputStream::read(wstring& v) +{ + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + try + { + if(_instance) + { + const WstringConverterPtr& wstringConverter = _instance->getWstringConverter(); + wstringConverter->fromUTF8(i, i + sz, v); + } + else + { + WstringConverterPtr wstringConverter = getProcessWstringConverter(); + wstringConverter->fromUTF8(i, i + sz, v); + } + + i += sz; + } + catch(const IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } + } + else + { + v.clear(); + } +} + +void +Ice::InputStream::read(vector& v) +{ + size_t sz = static_cast(readAndCheckSeqSize(1)); + if(sz > 0) + { + v.resize(sz); + for(size_t j = 0; j < sz; ++j) + { + read(v[j]); + } + } + else + { + v.clear(); + } +} + +#ifdef ICE_CPP11_MAPPING +shared_ptr +Ice::InputStream::readProxy() +{ + if(!_instance) + { + throw MarshalException(__FILE__, __LINE__, "cannot unmarshal a proxy without a communicator"); + } + + return _instance->proxyFactory()->streamToProxy(this); +} +#else +void +Ice::InputStream::read(ObjectPrx& v) +{ + if(!_instance) + { + throw MarshalException(__FILE__, __LINE__, "cannot unmarshal a proxy without a communicator"); + } + + v = _instance->proxyFactory()->streamToProxy(this); +} +#endif + +Int +Ice::InputStream::readEnum(Int maxValue) +{ + if(getEncoding() == Encoding_1_0) + { + if(maxValue < 127) + { + Byte value; + read(value); + return value; + } + else if(maxValue < 32767) + { + Short value; + read(value); + return value; + } + else + { + Int value; + read(value); + return value; + } + } + else + { + return readSize(); + } +} + +void +Ice::InputStream::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory) +{ + initEncaps(); + _currentEncaps->decoder->throwException(factory); +} + +bool +Ice::InputStream::readOptImpl(Int readTag, OptionalFormat expectedFormat) +{ + if(getEncoding() == Encoding_1_0) + { + return false; // Optional members aren't supported with the 1.0 encoding. + } + + while(true) + { + if(i >= b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + return false; // End of encapsulation also indicates end of optionals. + } + + Byte v; + read(v); + if(v == OPTIONAL_END_MARKER) + { + --i; // Rewind + return false; + } + + OptionalFormat format = static_cast(v & 0x07); // First 3 bits. + Int tag = static_cast(v >> 3); + if(tag == 30) + { + tag = readSize(); + } + + if(tag > readTag) + { + i -= tag < 30 ? 1 : (tag < 255 ? 2 : 6); // Rewind + return false; // No optional data members with the requested tag. + } + else if(tag < readTag) + { + skipOptional(format); // Skip optional data members + } + else + { + if(format != expectedFormat) + { + ostringstream os; + os << "invalid optional data member `" << tag << "': unexpected format"; + throw MarshalException(__FILE__, __LINE__, os.str()); + } + return true; + } + } + return true; // Keep the compiler happy. +} + +void +Ice::InputStream::skipOptional(OptionalFormat type) +{ + switch(type) + { + case ICE_SCOPED_ENUM(OptionalFormat, F1): + { + skip(1); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, F2): + { + skip(2); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, F4): + { + skip(4); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, F8): + { + skip(8); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, Size): + { + skipSize(); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, VSize): + { + skip(static_cast(readSize())); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, FSize): + { + Int sz; + read(sz); + if(sz < 0) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + skip(static_cast(sz)); + break; + } + case ICE_SCOPED_ENUM(OptionalFormat, Class): + { + read(0, 0); + break; + } + } +} + +void +Ice::InputStream::skipOptionals() +{ + // + // Skip remaining un-read optional members. + // + while(true) + { + if(i >= b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + return; // End of encapsulation also indicates end of optionals. + } + + Byte v; + read(v); + if(v == OPTIONAL_END_MARKER) + { + return; + } + + OptionalFormat format = static_cast(v & 0x07); // Read first 3 bits. + if(static_cast(v >> 3) == 30) + { + skipSize(); + } + skipOptional(format); + } +} + +void +Ice::InputStream::throwUnmarshalOutOfBoundsException(const char* file, int line) +{ + throw UnmarshalOutOfBoundsException(file, line); +} + +void +Ice::InputStream::throwEncapsulationException(const char* file, int line) +{ + throw EncapsulationException(file, line); +} + +string +Ice::InputStream::resolveCompactId(int id) const +{ + string type; + +#ifdef ICE_CPP11_MAPPING + function resolver = compactIdResolver(); +#else + CompactIdResolverPtr resolver = compactIdResolver(); +#endif + + if(resolver) + { + try + { +#ifdef ICE_CPP11_MAPPING + type = resolver(id); +#else + type = resolver->resolve(id); +#endif + } + catch(const LocalException&) + { + throw; + } + catch(const std::exception& ex) + { + ostringstream ostr; + ostr << "exception in CompactIdResolver for ID " << id; + string msg = ostr.str(); + string what = ex.what(); + if(!what.empty()) + { + msg += ":\n" + what; + } + throw MarshalException(__FILE__, __LINE__, msg); + } + catch(...) + { + ostringstream ostr; + ostr << "unknown exception in CompactIdResolver for ID " << id; + throw MarshalException(__FILE__, __LINE__, ostr.str()); + } + } + + return type; +} + +void +Ice::InputStream::postUnmarshal(const ValuePtr& v) const +{ + try + { +#ifndef ICE_CPP11_MAPPING + if(_collectObjects) + { + v->ice_collectable(true); + } +#endif + v->ice_postUnmarshal(); + } + catch(const std::exception& ex) + { + if(logger()) + { + Warning out(logger()); + out << "std::exception raised by ice_postUnmarshal:\n" << ex; + } + } + catch(...) + { + if(logger()) + { + Warning out(logger()); + out << "unknown exception raised by ice_postUnmarshal"; + } + } +} + +void +Ice::InputStream::traceSkipSlice(const string& typeId, SliceType sliceType) const +{ + if(_traceSlicing && logger()) + { + traceSlicing(sliceType == ExceptionSlice ? "exception" : "object", typeId, "Slicing", logger()); + } +} + +ValueFactoryManagerPtr +Ice::InputStream::valueFactoryManager() const +{ + if(_valueFactoryManager) + { + return _valueFactoryManager; + } + else if(_instance) + { + return _instance->initializationData().valueFactoryManager; + } + + return 0; +} + +LoggerPtr +Ice::InputStream::logger() const +{ + if(_logger) + { + return _logger; + } + else if(_instance) + { + return _instance->initializationData().logger; + } + + return 0; +} + +#ifdef ICE_CPP11_MAPPING +function +Ice::InputStream::compactIdResolver() const +{ + if(_compactIdResolver) + { + return _compactIdResolver; + } + else if(_instance) + { + return _instance->initializationData().compactIdResolver; + } + + return nullptr; +} +#else +CompactIdResolverPtr +Ice::InputStream::compactIdResolver() const +{ + if(_compactIdResolver) + { + return _compactIdResolver; + } + else if(_instance) + { + return _instance->initializationData().compactIdResolver; + } + + return 0; +} +#endif + +void +Ice::InputStream::initEncaps() +{ + if(!_currentEncaps) // Lazy initialization. + { + _currentEncaps = &_preAllocatedEncaps; + _currentEncaps->encoding = _encoding; + _currentEncaps->sz = static_cast(b.size()); + } + + if(!_currentEncaps->decoder) // Lazy initialization. + { + ValueFactoryManagerPtr vfm = valueFactoryManager(); + if(_currentEncaps->encoding == Encoding_1_0) + { + _currentEncaps->decoder = new EncapsDecoder10(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm); + } + else + { + _currentEncaps->decoder = new EncapsDecoder11(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm); + } + } +} + +Ice::InputStream::EncapsDecoder::~EncapsDecoder() +{ + // Out of line to avoid weak vtable +} + +string +Ice::InputStream::EncapsDecoder::readTypeId(bool isIndex) +{ + if(isIndex) + { + Int index = _stream->readSize(); + TypeIdMap::const_iterator k = _typeIdMap.find(index); + if(k == _typeIdMap.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + return k->second; + } + else + { + string typeId; + _stream->read(typeId, false); + _typeIdMap.insert(make_pair(++_typeIdIndex, typeId)); + return typeId; + } +} + +Ice::ValuePtr +Ice::InputStream::EncapsDecoder::newInstance(const string& typeId) +{ + Ice::ValuePtr v; + + // + // Try to find a factory registered for the specific type. + // +#ifdef ICE_CPP11_MAPPING + function userFactory; + if(_valueFactoryManager) + { + userFactory = _valueFactoryManager->find(typeId); + if(userFactory) + { + v = userFactory(typeId); + } + } +#else + ValueFactoryPtr userFactory; + if(_valueFactoryManager) + { + userFactory = _valueFactoryManager->find(typeId); + if(userFactory) + { + v = userFactory->create(typeId); + } + } +#endif + // + // If that fails, invoke the default factory if one has been registered. + // + if(!v && _valueFactoryManager) + { + userFactory = _valueFactoryManager->find(""); + if(userFactory) + { +#ifdef ICE_CPP11_MAPPING + v = userFactory(typeId); +#else + v = userFactory->create(typeId); +#endif + } + } + + // + // Last chance: check the table of static factories (i.e., + // automatically generated factories for concrete classes). + // + if(!v) + { +#ifdef ICE_CPP11_MAPPING + function of = IceInternal::factoryTable->getValueFactory(typeId); + if(of) + { + v = of(typeId); + assert(v); + } +#else + ValueFactoryPtr of = IceInternal::factoryTable->getValueFactory(typeId); + if(of) + { + v = of->create(typeId); + assert(v); + } +#endif + } + return v; +} + +void +Ice::InputStream::EncapsDecoder::addPatchEntry(Int index, PatchFunc patchFunc, void* patchAddr) +{ + assert(index > 0); + + // + // Check if we already unmarshaled the object. If that's the case, just patch the object smart pointer + // and we're done. A null value indicates we've encountered a cycle and Ice.AllowClassCycles is false. + // + IndexToPtrMap::iterator p = _unmarshaledMap.find(index); + if(p != _unmarshaledMap.end()) + { + if (p->second == ICE_NULLPTR) + { + assert(!_stream->_instance->acceptClassCycles()); + throw MarshalException(__FILE__, __LINE__, "cycle detected during Value unmarshaling"); + } + (*patchFunc)(patchAddr, p->second); + return; + } + + // + // Add a patch entry if the object isn't unmarshaled yet, the + // smart pointer will be patched when the instance is + // unmarshaled. + // + + PatchMap::iterator q = _patchMap.find(index); + if(q == _patchMap.end()) + { + // + // We have no outstanding instances to be patched for this + // index, so make a new entry in the patch map. + // + q = _patchMap.insert(make_pair(index, PatchList())).first; + } + + // + // Append a patch entry for this instance. + // + PatchEntry e; + e.patchFunc = patchFunc; + e.patchAddr = patchAddr; + e.classGraphDepth = _classGraphDepth; + q->second.push_back(e); +} + +void +Ice::InputStream::EncapsDecoder::unmarshal(Int index, const Ice::ValuePtr& v) +{ + // + // Add the object to the map of unmarshaled instances, this must + // be done before reading the instances (for circular references). + // + // If circular references are not allowed we insert null (for cycle detection) and add + // the object to the map once it has been fully unmarshaled. + // + _unmarshaledMap.insert(make_pair(index, _stream->_instance->acceptClassCycles() ? v : Ice::ValuePtr())); + + // + // Read the object. + // + v->_iceRead(_stream); + + // + // Patch all instances now that the object is unmarshaled. + // + PatchMap::iterator patchPos = _patchMap.find(index); + if(patchPos != _patchMap.end()) + { + assert(patchPos->second.size() > 0); + + // + // Patch all pointers that refer to the instance. + // + for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k) + { + (*k->patchFunc)(k->patchAddr, v); + } + + // + // Clear out the patch map for that index -- there is nothing left + // to patch for that index for the time being. + // + _patchMap.erase(patchPos); + } + + if(_valueList.empty() && _patchMap.empty()) + { + _stream->postUnmarshal(v); + } + else + { + _valueList.push_back(v); + + if(_patchMap.empty()) + { + // + // Iterate over the value list and invoke ice_postUnmarshal on + // each value. We must do this after all values have been + // unmarshaled in order to ensure that any value data members + // have been properly patched. + // + for(ValueList::iterator p = _valueList.begin(); p != _valueList.end(); ++p) + { + _stream->postUnmarshal(*p); + } + _valueList.clear(); + } + } + + if(!_stream->_instance->acceptClassCycles()) + { + // This class has been fully unmarshaled without creating any cycles + // It can be added to the map now. + _unmarshaledMap[index] = v; + } +} + +void +Ice::InputStream::EncapsDecoder10::read(PatchFunc patchFunc, void* patchAddr) +{ + assert(patchFunc && patchAddr); + + // + // Object references are encoded as a negative integer in 1.0. + // + Int index; + _stream->read(index); + if(index > 0) + { + throw MarshalException(__FILE__, __LINE__, "invalid object id"); + } + index = -index; + + if(index == 0) + { + // + // Calling the patch function for null instances is necessary for correct functioning of Ice for + // Python and Ruby. + // + ValuePtr nil; + patchFunc(patchAddr, nil); + } + else + { + addPatchEntry(index, patchFunc, patchAddr); + } +} + +void +Ice::InputStream::EncapsDecoder10::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory) +{ + assert(_sliceType == NoSlice); + + // + // User exception with the 1.0 encoding start with a boolean flag + // that indicates whether or not the exception has classes. + // + // This allows reading the pending values even if some part of + // the exception was sliced. + // + bool usesClasses; + _stream->read(usesClasses); + + _sliceType = ExceptionSlice; + _skipFirstSlice = false; + + // + // Read the first slice header. + // + startSlice(); + const string mostDerivedId = _typeId; + ICE_DELEGATE(UserExceptionFactory) exceptionFactory = factory; + while(true) + { + // + // Look for a statically-generated factory for this ID. + // + if(!exceptionFactory) + { + exceptionFactory = factoryTable->getExceptionFactory(_typeId); + } + + // + // We found a factory, we get out of this loop. + // + if(exceptionFactory) + { + // + // Got factory -- ask the factory to instantiate the + // exception, initialize the exception members, and throw + // the exception. + // + try + { +#ifdef ICE_CPP11_MAPPING + exceptionFactory(_typeId); +#else + exceptionFactory->createAndThrow(_typeId); +#endif + } + catch(UserException& ex) + { + ex._read(_stream); + if(usesClasses) + { + readPendingValues(); + } + throw; + + // Never reached. + } + } + + // + // Slice off what we don't understand. + // + skipSlice(); + try + { + startSlice(); + } + catch(UnmarshalOutOfBoundsException& ex) + { + // + // An oversight in the 1.0 encoding means there is no marker to indicate + // the last slice of an exception. As a result, we just try to read the + // next type ID, which raises UnmarshalOutOfBoundsException when the + // input buffer underflows. + // + // Set the reason member to a more helpful message. + // + ex.reason = "unknown exception type `" + mostDerivedId + "'"; + throw; + } + } +} + +void +#ifndef NDEBUG +Ice::InputStream::EncapsDecoder10::startInstance(SliceType sliceType) +#else +Ice::InputStream::EncapsDecoder10::startInstance(SliceType) +#endif +{ + assert(_sliceType == sliceType); + _skipFirstSlice = true; +} + +SlicedDataPtr +Ice::InputStream::EncapsDecoder10::endInstance(bool) +{ + // + // Read the Ice::Value slice. + // + if(_sliceType == ValueSlice) + { + startSlice(); + Int sz = _stream->readSize(); // For compatibility with the old AFM. + if(sz != 0) + { + throw MarshalException(__FILE__, __LINE__, "invalid Object slice"); + } + endSlice(); + } + _sliceType = NoSlice; + return 0; +} + +const std::string& +Ice::InputStream::EncapsDecoder10::startSlice() +{ + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if(_skipFirstSlice) + { + _skipFirstSlice = false; + return _typeId; + } + + // + // For values, first read the type ID boolean which indicates + // whether or not the type ID is encoded as a string or as an + // index. For exceptions, the type ID is always encoded as a + // string. + // + if(_sliceType == ValueSlice) + { + bool isIndex; + _stream->read(isIndex); + _typeId = readTypeId(isIndex); + } + else + { + _stream->read(_typeId, false); + } + + _stream->read(_sliceSize); + if(_sliceSize < 4) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + return _typeId; +} + +void +Ice::InputStream::EncapsDecoder10::endSlice() +{ +} + +void +Ice::InputStream::EncapsDecoder10::skipSlice() +{ + _stream->traceSkipSlice(_typeId, _sliceType); + assert(_sliceSize >= 4); + _stream->skip(static_cast(_sliceSize) - sizeof(Int)); +} + +void +Ice::InputStream::EncapsDecoder10::readPendingValues() +{ + Int num; + do + { + num = _stream->readSize(); + for(Int k = num; k > 0; --k) + { + readInstance(); + } + } + while(num); + + if(!_patchMap.empty()) + { + // + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. + // + throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance"); + } +} + +void +Ice::InputStream::EncapsDecoder10::readInstance() +{ + Int index; + _stream->read(index); + + if(index <= 0) + { + throw MarshalException(__FILE__, __LINE__, "invalid object id"); + } + + _sliceType = ValueSlice; + _skipFirstSlice = false; + + // + // Read the first slice header. + // + startSlice(); + const string mostDerivedId = _typeId; + ValuePtr v; + while(true) + { + // + // For the 1.0 encoding, the type ID for the base Object class + // marks the last slice. + // + if(_typeId == Object::ice_staticId()) + { + throw NoValueFactoryException(__FILE__, __LINE__, "", mostDerivedId); + } + + v = newInstance(_typeId); + + // + // We found a factory, we get out of this loop. + // + if(v) + { + break; + } + + // + // If value slicing is disabled, stop unmarshaling. + // + if(!_sliceValues) + { + throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and value slicing is disabled", + _typeId); + } + + // + // Slice off what we don't understand. + // + skipSlice(); + startSlice(); // Read next Slice header for next iteration. + } + + // + // Compute the biggest class graph depth of this object. To compute this, + // we get the class graph depth of each ancestor from the patch map and + // keep the biggest one. + // + _classGraphDepth = 0; + PatchMap::iterator patchPos = _patchMap.find(index); + if(patchPos != _patchMap.end()) + { + assert(patchPos->second.size() > 0); + for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k) + { + if(k->classGraphDepth > _classGraphDepth) + { + _classGraphDepth = k->classGraphDepth; + } + } + } + + if(++_classGraphDepth > _classGraphDepthMax) + { + throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached"); + } + + // + // Unmarshal the instance and add it to the map of unmarshaled instances. + // + unmarshal(index, v); +} + +void +Ice::InputStream::EncapsDecoder11::read(PatchFunc patchFunc, void* patchAddr) +{ + Int index = _stream->readSize(); + if(index < 0) + { + throw MarshalException(__FILE__, __LINE__, "invalid object id"); + } + else if(index == 0) + { + // + // Calling the patch function for null instances is necessary for correct functioning of Ice for + // Python and Ruby. + // + if(patchFunc) + { + ValuePtr nil; + patchFunc(patchAddr, nil); + } + } + else if(_current && _current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE) + { + // + // When reading an object within a slice and there's an + // indirect object table, always read an indirect reference + // that points to an object from the indirect object table + // marshaled at the end of the Slice. + // + // Maintain a list of indirect references. Note that the + // indirect index starts at 1, so we decrement it by one to + // derive an index into the indirection table that we'll read + // at the end of the slice. + // + if(patchFunc) + { + IndirectPatchEntry e; + e.index = index - 1; + e.patchFunc = patchFunc; + e.patchAddr = patchAddr; + _current->indirectPatchList.push_back(e); + } + } + else + { + readInstance(index, patchFunc, patchAddr); + } +} + +void +Ice::InputStream::EncapsDecoder11::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory) +{ + assert(!_current); + + push(ExceptionSlice); + + // + // Read the first slice header. + // + startSlice(); + const string mostDerivedId = _current->typeId; + ICE_DELEGATE(UserExceptionFactory) exceptionFactory = factory; + while(true) + { + // + // Look for a statically-generated factory for this ID. + // + if(!exceptionFactory) + { + exceptionFactory = factoryTable->getExceptionFactory(_current->typeId); + } + + // + // We found a factory, we get out of this loop. + // + if(exceptionFactory) + { + // + // Got factory -- ask the factory to instantiate the + // exception, initialize the exception members, and throw + // the exception. + // + try + { +#ifdef ICE_CPP11_MAPPING + exceptionFactory(_current->typeId); +#else + exceptionFactory->createAndThrow(_current->typeId); +#endif + } + catch(UserException& ex) + { + ex._read(_stream); + throw; + + // Never reached. + } + } + + // + // Slice off what we don't understand. + // + skipSlice(); + + // + // If this is the last slice, raise an exception and stop un-marshalling. + // + if(_current->sliceFlags & FLAG_IS_LAST_SLICE) + { + throw UnknownUserException(__FILE__, __LINE__, mostDerivedId); + } + + startSlice(); + } +} + +void +#ifndef NDEBUG +Ice::InputStream::EncapsDecoder11::startInstance(SliceType sliceType) +#else +Ice::InputStream::EncapsDecoder11::startInstance(SliceType) +#endif +{ + assert(_current->sliceType == sliceType); + _current->skipFirstSlice = true; +} + +SlicedDataPtr +Ice::InputStream::EncapsDecoder11::endInstance(bool preserve) +{ + SlicedDataPtr slicedData; + if(preserve) + { + slicedData = readSlicedData(); + } + _current->slices.clear(); + _current->indirectionTables.clear(); + _current = _current->previous; + return slicedData; +} + +const std::string& +Ice::InputStream::EncapsDecoder11::startSlice() +{ + // + // If first slice, don't read the header, it was already read in + // readInstance or throwException to find the factory. + // + if(_current->skipFirstSlice) + { + _current->skipFirstSlice = false; + return _current->typeId; + } + + _stream->read(_current->sliceFlags); + + // + // Read the type ID, for value slices the type ID is encoded as a + // string or as an index, for exceptions it's always encoded as a + // string. + // + if(_current->sliceType == ValueSlice) + { + if((_current->sliceFlags & FLAG_HAS_TYPE_ID_COMPACT) == FLAG_HAS_TYPE_ID_COMPACT) // Must be checked first! + { + _current->typeId.clear(); + _current->compactId = _stream->readSize(); + } + else if(_current->sliceFlags & (FLAG_HAS_TYPE_ID_STRING | FLAG_HAS_TYPE_ID_INDEX)) + { + _current->typeId = readTypeId(_current->sliceFlags & FLAG_HAS_TYPE_ID_INDEX); + _current->compactId = -1; + } + else + { + // Only the most derived slice encodes the type ID for the compact format. + _current->typeId.clear(); + _current->compactId = -1; + } + } + else + { + _stream->read(_current->typeId, false); + } + + // + // Read the slice size if necessary. + // + if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE) + { + _stream->read(_current->sliceSize); + if(_current->sliceSize < 4) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + } + else + { + _current->sliceSize = 0; + } + + return _current->typeId; +} + +void +Ice::InputStream::EncapsDecoder11::endSlice() +{ + if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) + { + _stream->skipOptionals(); + } + + // + // Read the indirect object table if one is present. + // + if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE) + { + IndexList indirectionTable(static_cast(_stream->readAndCheckSeqSize(1))); + for(IndexList::iterator p = indirectionTable.begin(); p != indirectionTable.end(); ++p) + { + *p = readInstance(_stream->readSize(), 0, 0); + } + + // + // Sanity checks. If there are optional members, it's possible + // that not all object references were read if they are from + // unknown optional data members. + // + if(indirectionTable.empty()) + { + throw MarshalException(__FILE__, __LINE__, "empty indirection table"); + } + if(_current->indirectPatchList.empty() && !(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)) + { + throw MarshalException(__FILE__, __LINE__, "no references to indirection table"); + } + + // + // Convert indirect references into direct references. + // + IndirectPatchList::iterator p; + for(p = _current->indirectPatchList.begin(); p != _current->indirectPatchList.end(); ++p) + { + assert(p->index >= 0); + if(p->index >= static_cast(indirectionTable.size())) + { + throw MarshalException(__FILE__, __LINE__, "indirection out of range"); + } + addPatchEntry(indirectionTable[static_cast(p->index)], p->patchFunc, p->patchAddr); + } + _current->indirectPatchList.clear(); + } +} + +void +Ice::InputStream::EncapsDecoder11::skipSlice() +{ + _stream->traceSkipSlice(_current->typeId, _current->sliceType); + + Container::iterator start = _stream->i; + + if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE) + { + assert(_current->sliceSize >= 4); + _stream->skip(static_cast(_current->sliceSize) - sizeof(Int)); + } + else + { + if(_current->sliceType == ValueSlice) + { + throw NoValueFactoryException(__FILE__, __LINE__, + "no value factory found and compact format prevents " + "slicing (the sender should use the sliced format instead)", + _current->typeId); + } + else + { + throw UnknownUserException(__FILE__, __LINE__, _current->typeId); + } + } + + // + // Preserve this slice. + // + SliceInfoPtr info = ICE_MAKE_SHARED(SliceInfo); + info->typeId = _current->typeId; + info->compactId = _current->compactId; + info->hasOptionalMembers = _current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS; + info->isLastSlice = _current->sliceFlags & FLAG_IS_LAST_SLICE; + if(info->hasOptionalMembers) + { + // + // Don't include the optional member end marker. It will be re-written by + // endSlice when the sliced data is re-written. + // + vector(start, _stream->i - 1).swap(info->bytes); + } + else + { + vector(start, _stream->i).swap(info->bytes); + } + + _current->indirectionTables.push_back(IndexList()); + + // + // Read the indirect object table. We read the instances or their + // IDs if the instance is a reference to an already un-marhsaled + // object. + // + // The SliceInfo object sequence is initialized only if + // readSlicedData is called. + // + if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE) + { + IndexList& table = _current->indirectionTables.back(); + table.resize(static_cast(_stream->readAndCheckSeqSize(1))); + for(IndexList::iterator p = table.begin(); p != table.end(); ++p) + { + *p = readInstance(_stream->readSize(), 0, 0); + } + } + + _current->slices.push_back(info); +} + +bool +Ice::InputStream::EncapsDecoder11::readOptional(Ice::Int readTag, Ice::OptionalFormat expectedFormat) +{ + if(!_current) + { + return _stream->readOptImpl(readTag, expectedFormat); + } + else if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) + { + return _stream->readOptImpl(readTag, expectedFormat); + } + return false; +} + +Int +Ice::InputStream::EncapsDecoder11::readInstance(Int index, PatchFunc patchFunc, void* patchAddr) +{ + assert(index > 0); + + if(index > 1) + { + if(patchFunc) + { + addPatchEntry(index, patchFunc, patchAddr); + } + return index; + } + + push(ValueSlice); + + // + // Get the object ID before we start reading slices. If some + // slices are skiped, the indirect object table are still read and + // might read other instances. + // + index = ++_valueIdIndex; + + // + // Read the first slice header. + // + startSlice(); + const string mostDerivedId = _current->typeId; + Ice::ValuePtr v; + while(true) + { + if(_current->compactId >= 0) + { + // + // Translate a compact (numeric) type ID into a string type ID. + // + _current->typeId = _stream->resolveCompactId(_current->compactId); + if(_current->typeId.empty()) + { + _current->typeId = IceInternal::factoryTable->getTypeId(_current->compactId); + } + } + + if(!_current->typeId.empty()) + { + v = newInstance(_current->typeId); + + // + // We found a factory, we get out of this loop. + // + if(v) + { + break; + } + } + + // + // If value slicing is disabled, stop unmarshaling. + // + if(!_sliceValues) + { + throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and value slicing is disabled", + _current->typeId); + } + + // + // Slice off what we don't understand. + // + skipSlice(); + + // + // If this is the last slice, keep the object as an opaque UnknownSlicedValue. + // + if(_current->sliceFlags & FLAG_IS_LAST_SLICE) + { + // + // Provide a factory with an opportunity to supply the object. + // We pass the "::Ice::Object" ID to indicate that this is the + // last chance to preserve the object. + // + v = newInstance(Object::ice_staticId()); + if(!v) + { + v = ICE_MAKE_SHARED(UnknownSlicedValue, mostDerivedId); + } + + break; + } + + startSlice(); // Read next Slice header for next iteration. + } + + if(++_classGraphDepth > _classGraphDepthMax) + { + throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached"); + } + + // + // Unmarshal the object. + // + unmarshal(index, v); + + --_classGraphDepth; + + if(!_current && !_patchMap.empty()) + { + // + // If any entries remain in the patch map, the sender has sent an index for an object, but failed + // to supply the object. + // + throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance"); + } + + if(patchFunc) + { + patchFunc(patchAddr, v); + } + return index; +} + +SlicedDataPtr +Ice::InputStream::EncapsDecoder11::readSlicedData() +{ + if(_current->slices.empty()) // No preserved slices. + { + return 0; + } + + // + // The indirectionTables member holds the indirection table for + // each slice in slices. + // + assert(_current->slices.size() == _current->indirectionTables.size()); + for(SliceInfoSeq::size_type n = 0; n < _current->slices.size(); ++n) + { + // + // We use the "instances" list in SliceInfo to hold references + // to the target instances. Note that the instances might not have + // been read yet in the case of a circular reference to an + // enclosing instance. + // + const IndexList& table = _current->indirectionTables[n]; + vector& instances = _current->slices[n]->instances; + instances.resize(table.size()); + IndexList::size_type j = 0; + for(IndexList::const_iterator p = table.begin(); p != table.end(); ++p) + { +#ifdef ICE_CPP11_MAPPING + addPatchEntry(*p, &patchHandle, &instances[j++]); +#else + addPatchEntry(*p, &patchHandle, &instances[j++]); +#endif + } + } + return ICE_MAKE_SHARED(SlicedData, _current->slices); +} diff --git a/Sources/IceCpp/InputUtil.cpp b/Sources/IceCpp/InputUtil.cpp new file mode 100644 index 0000000..52027a5 --- /dev/null +++ b/Sources/IceCpp/InputUtil.cpp @@ -0,0 +1,36 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace IceUtil; + +namespace IceUtilInternal +{ + +Int64 +strToInt64(const char* s, char** endptr, int base) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return _strtoi64(s, endptr, base); +#elif defined(ICE_64) && !defined(_WIN32) + return strtol(s, endptr, base); +#else + return strtoll(s, endptr, base); +#endif +} + +bool +stringToInt64(const string& s, Int64& result) +{ + const char* start = s.c_str(); + char* end = 0; + errno = 0; + result = strToInt64(start, &end, 0); + return (errno == 0 && start != end); +} + +} diff --git a/Sources/IceCpp/Instance.cpp b/Sources/IceCpp/Instance.cpp new file mode 100644 index 0000000..c69f734 --- /dev/null +++ b/Sources/IceCpp/Instance.cpp @@ -0,0 +1,1967 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // For EndpointHostResolver +#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 + +#ifdef __APPLE__ +# include +#endif + +#ifndef _WIN32 +# include +# include + +# include +# include +# include +# include +#endif + +#if defined(__linux__) || defined(__sun) || defined(_AIX) || defined(__GLIBC__) +# include // for initgroups +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace IceUtilInternal +{ + +extern bool nullHandleAbort; +extern bool printStackTraces; + +}; + +namespace +{ + +IceUtil::Mutex* staticMutex = 0; +bool oneOfDone = false; +std::list* instanceList = 0; + +#ifndef _WIN32 +struct sigaction oldAction; +#endif +bool printProcessIdDone = false; +string identForOpenlog; + +// +// Should be called with staticMutex locked +// +size_t instanceCount() +{ + if(instanceList == 0) + { + return 0; + } + else + { + return instanceList->size(); + } +} + +class Init +{ +public: + + Init() + { + staticMutex = new IceUtil::Mutex; + + // + // Although probably not necessary here, we consistently lock + // staticMutex before accessing instanceList + // + IceUtilInternal::MutexPtrLock sync(staticMutex); + instanceList = new std::list; + } + + ~Init() + { + { + IceUtilInternal::MutexPtrLock sync(staticMutex); + int notDestroyedCount = 0; + + for(std::list::const_iterator p = instanceList->begin(); + p != instanceList->end(); ++p) + { + if(!(*p)->destroyed()) + { + notDestroyedCount++; + } + } + + if(notDestroyedCount > 0) + { + consoleErr << "!! " << IceUtil::Time::now().toDateTime() << " error: "; + if(notDestroyedCount == 1) + { + consoleErr << "communicator "; + } + else + { + consoleErr << notDestroyedCount << " communicators "; + } + consoleErr << "not destroyed during global destruction."; + } + + delete instanceList; + instanceList = 0; + } + delete staticMutex; + staticMutex = 0; + } +}; + +Init init; + +// +// Static initializer to register plugins. +// +IceInternal::RegisterPluginsInit initPlugins; + +} + +namespace IceInternal // Required because ObserverUpdaterI is a friend of Instance +{ + +class ObserverUpdaterI : public Ice::Instrumentation::ObserverUpdater +{ +public: + + ObserverUpdaterI(const InstancePtr&); + + virtual void updateConnectionObservers(); + virtual void updateThreadObservers(); + +private: + + const InstancePtr _instance; +}; + +// +// Timer specialization which supports the thread observer +// +class Timer : public IceUtil::Timer +{ +public: + + Timer(int priority) : + IceUtil::Timer(priority), + _hasObserver(0) + { + } + + Timer() : + _hasObserver(0) + { + } + + void updateObserver(const Ice::Instrumentation::CommunicatorObserverPtr&); + +private: + + virtual void runTimerTask(const IceUtil::TimerTaskPtr&); + + IceUtil::Mutex _mutex; + // + // TODO: Replace by std::atomic when it becomes widely + // available. + // + IceUtilInternal::Atomic _hasObserver; + ObserverHelperT _observer; +}; + +} + +void +Timer::updateObserver(const Ice::Instrumentation::CommunicatorObserverPtr& obsv) +{ + IceUtil::Mutex::Lock sync(_mutex); + assert(obsv); + _observer.attach(obsv->getThreadObserver("Communicator", + "Ice.Timer", + Instrumentation::ICE_ENUM(ThreadState, ThreadStateIdle), + _observer.get())); + _hasObserver.exchange(_observer.get() ? 1 : 0); +} + +void +Timer::runTimerTask(const IceUtil::TimerTaskPtr& task) +{ + if(_hasObserver != 0) + { + Ice::Instrumentation::ThreadObserverPtr threadObserver; + { + IceUtil::Mutex::Lock sync(_mutex); + threadObserver = _observer.get(); + } + if(threadObserver) + { + threadObserver->stateChanged(Instrumentation::ICE_ENUM(ThreadState, ThreadStateIdle), + Instrumentation::ICE_ENUM(ThreadState, ThreadStateInUseForOther)); + } + try + { + task->runTimerTask(); + } + catch(...) + { + if(threadObserver) + { + threadObserver->stateChanged(Instrumentation::ICE_ENUM(ThreadState, ThreadStateInUseForOther), + Instrumentation::ICE_ENUM(ThreadState, ThreadStateIdle)); + } + } + if(threadObserver) + { + threadObserver->stateChanged(Instrumentation::ICE_ENUM(ThreadState, ThreadStateInUseForOther), + Instrumentation::ICE_ENUM(ThreadState, ThreadStateIdle)); + } + } + else + { + task->runTimerTask(); + } +} + +IceUtil::Shared* IceInternal::upCast(Instance* p) { return p; } + +IceInternal::ObserverUpdaterI::ObserverUpdaterI(const InstancePtr& instance) : _instance(instance) +{ +} + +void +IceInternal::ObserverUpdaterI::updateConnectionObservers() +{ + _instance->updateConnectionObservers(); +} + +void +IceInternal::ObserverUpdaterI::updateThreadObservers() +{ + _instance->updateThreadObservers(); +} + +bool +IceInternal::Instance::destroyed() const +{ + Lock sync(*this); + return _state == StateDestroyed; +} + +TraceLevelsPtr +IceInternal::Instance::traceLevels() const +{ + // No mutex lock, immutable. + assert(_traceLevels); + return _traceLevels; +} + +DefaultsAndOverridesPtr +IceInternal::Instance::defaultsAndOverrides() const +{ + // No mutex lock, immutable. + assert(_defaultsAndOverrides); + return _defaultsAndOverrides; +} + +RouterManagerPtr +IceInternal::Instance::routerManager() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_routerManager); + return _routerManager; +} + +LocatorManagerPtr +IceInternal::Instance::locatorManager() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_locatorManager); + return _locatorManager; +} + +ReferenceFactoryPtr +IceInternal::Instance::referenceFactory() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_referenceFactory); + return _referenceFactory; +} + +RequestHandlerFactoryPtr +IceInternal::Instance::requestHandlerFactory() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_requestHandlerFactory); + return _requestHandlerFactory; +} + +ProxyFactoryPtr +IceInternal::Instance::proxyFactory() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_proxyFactory); + return _proxyFactory; +} + +OutgoingConnectionFactoryPtr +IceInternal::Instance::outgoingConnectionFactory() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_outgoingConnectionFactory); + return _outgoingConnectionFactory; +} + +ObjectAdapterFactoryPtr +IceInternal::Instance::objectAdapterFactory() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_objectAdapterFactory); + return _objectAdapterFactory; +} + +ProtocolSupport +IceInternal::Instance::protocolSupport() const +{ + return _protocolSupport; +} + +bool +IceInternal::Instance::preferIPv6() const +{ + return _preferIPv6; +} + +NetworkProxyPtr +IceInternal::Instance::networkProxy() const +{ + return _networkProxy; +} + +ThreadPoolPtr +IceInternal::Instance::clientThreadPool() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_clientThreadPool); + return _clientThreadPool; +} + +ThreadPoolPtr +IceInternal::Instance::serverThreadPool() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(!_serverThreadPool) // Lazy initialization. + { + if(_state == StateDestroyInProgress) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + int timeout = _initData.properties->getPropertyAsInt("Ice.ServerIdleTime"); + _serverThreadPool = new ThreadPool(this, "Ice.ThreadPool.Server", timeout); + } + + return _serverThreadPool; +} + +EndpointHostResolverPtr +IceInternal::Instance::endpointHostResolver() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_endpointHostResolver); + return _endpointHostResolver; +} + +RetryQueuePtr +IceInternal::Instance::retryQueue() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_retryQueue); + return _retryQueue; +} + +IceUtil::TimerPtr +IceInternal::Instance::timer() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + assert(_timer); + return _timer; +} + +EndpointFactoryManagerPtr +IceInternal::Instance::endpointFactoryManager() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_endpointFactoryManager); + return _endpointFactoryManager; +} + +DynamicLibraryListPtr +IceInternal::Instance::dynamicLibraryList() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_dynamicLibraryList); + return _dynamicLibraryList; +} + +PluginManagerPtr +IceInternal::Instance::pluginManager() const +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_pluginManager); + return _pluginManager; +} + +const ACMConfig& +IceInternal::Instance::clientACM() const +{ + // No mutex lock, immutable. + return _clientACM; +} + +const ACMConfig& +IceInternal::Instance::serverACM() const +{ + // No mutex lock, immutable. + return _serverACM; +} + +Ice::ObjectPrxPtr +IceInternal::Instance::createAdmin(const ObjectAdapterPtr& adminAdapter, const Identity& adminIdentity) +{ + ObjectAdapterPtr adapter = adminAdapter; + bool createAdapter = !adminAdapter; + + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(adminIdentity.name.empty()) + { + throw Ice::IllegalIdentityException(__FILE__, __LINE__, adminIdentity); + } + + if(_adminAdapter) + { + throw InitializationException(__FILE__, __LINE__, "Admin already created"); + } + + if(!_adminEnabled) + { + throw InitializationException(__FILE__, __LINE__, "Admin is disabled"); + } + + if(createAdapter) + { + if(_initData.properties->getProperty("Ice.Admin.Endpoints") != "") + { + adapter = _objectAdapterFactory->createObjectAdapter("Ice.Admin", 0); + } + else + { + throw InitializationException(__FILE__, __LINE__, "Ice.Admin.Endpoints is not set"); + } + } + + _adminIdentity = adminIdentity; + _adminAdapter = adapter; + addAllAdminFacets(); + sync.release(); + + if(createAdapter) + { + try + { + adapter->activate(); + } + catch(...) + { + // + // We clean it up, even through this error is not recoverable + // (can't call again createAdmin after fixing the problem since all the facets + // in the adapter are lost) + // + adapter->destroy(); + sync.acquire(); + _adminAdapter = 0; + throw; + } + } + setServerProcessProxy(adapter, adminIdentity); + return adapter->createProxy(adminIdentity); +} + +Ice::ObjectPrxPtr +IceInternal::Instance::getAdmin() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(_adminAdapter) + { + return _adminAdapter->createProxy(_adminIdentity); + } + else if(_adminEnabled) + { + ObjectAdapterPtr adapter; + if(_initData.properties->getProperty("Ice.Admin.Endpoints") != "") + { + adapter = _objectAdapterFactory->createObjectAdapter("Ice.Admin", 0); + } + else + { + return 0; + } + + Identity adminIdentity; + adminIdentity.name = "admin"; + adminIdentity.category = _initData.properties->getProperty("Ice.Admin.InstanceName"); + if(adminIdentity.category.empty()) + { + adminIdentity.category = Ice::generateUUID(); + } + + _adminIdentity = adminIdentity; + _adminAdapter = adapter; + addAllAdminFacets(); + sync.release(); + try + { + adapter->activate(); + } + catch(...) + { + // + // We clean it up, even through this error is not recoverable + // (can't call again createAdmin after fixing the problem since all the facets + // in the adapter are lost) + // + adapter->destroy(); + sync.acquire(); + _adminAdapter = 0; + throw; + } + + setServerProcessProxy(adapter, adminIdentity); + return adapter->createProxy(adminIdentity); + } + else + { + return 0; + } +} + +void +IceInternal::Instance::addAllAdminFacets() +{ + // must be called with this locked + + // + // Add all facets to OA + // + FacetMap filteredFacets; + + for(FacetMap::iterator p = _adminFacets.begin(); p != _adminFacets.end(); ++p) + { + if(_adminFacetFilter.empty() || _adminFacetFilter.find(p->first) != _adminFacetFilter.end()) + { + _adminAdapter->addFacet(p->second, _adminIdentity, p->first); + } + else + { + filteredFacets[p->first] = p->second; + } + } + _adminFacets.swap(filteredFacets); +} + +void +IceInternal::Instance::setServerProcessProxy(const ObjectAdapterPtr& adminAdapter, const Identity& adminIdentity) +{ + ObjectPrxPtr admin = adminAdapter->createProxy(adminIdentity); + LocatorPrxPtr locator = adminAdapter->getLocator(); + const string serverId = _initData.properties->getProperty("Ice.Admin.ServerId"); + if(locator && serverId != "") + { + ProcessPrxPtr process = ICE_UNCHECKED_CAST(ProcessPrx, admin->ice_facet("Process")); + try + { + // + // Note that as soon as the process proxy is registered, the communicator might be + // shutdown by a remote client and admin facets might start receiving calls. + // + locator->getRegistry()->setServerProcessProxy(serverId, process); + } + catch(const ServerNotFoundException&) + { + if(_traceLevels->location >= 1) + { + Trace out(_initData.logger, _traceLevels->locationCat); + out << "couldn't register server `" + serverId + "' with the locator registry:\n"; + out << "the server is not known to the locator registry"; + } + + throw InitializationException(__FILE__, __LINE__, "Locator `" + _proxyFactory->proxyToString(locator) + + "' knows nothing about server `" + serverId + "'"); + } + catch(const LocalException& ex) + { + if(_traceLevels->location >= 1) + { + Trace out(_initData.logger, _traceLevels->locationCat); + out << "couldn't register server `" + serverId + "' with the locator registry:\n" << ex; + } + throw; + } + + if(_traceLevels->location >= 1) + { + Trace out(_initData.logger, _traceLevels->locationCat); + out << "registered server `" + serverId + "' with the locator registry"; + } + } +} + +void +IceInternal::Instance::addAdminFacet(const Ice::ObjectPtr& servant, const string& facet) +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(_adminAdapter == 0 || (!_adminFacetFilter.empty() && _adminFacetFilter.find(facet) == _adminFacetFilter.end())) + { + if(_adminFacets.insert(FacetMap::value_type(facet, servant)).second == false) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "facet", facet); + } + } + else + { + _adminAdapter->addFacet(servant, _adminIdentity, facet); + } +} + +Ice::ObjectPtr +IceInternal::Instance::removeAdminFacet(const string& facet) +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + ObjectPtr result; + + if(_adminAdapter == 0 || (!_adminFacetFilter.empty() && _adminFacetFilter.find(facet) == _adminFacetFilter.end())) + { + FacetMap::iterator p = _adminFacets.find(facet); + if(p == _adminFacets.end()) + { + throw NotRegisteredException(__FILE__, __LINE__, "facet", facet); + } + else + { + result = p->second; + _adminFacets.erase(p); + } + } + else + { + result = _adminAdapter->removeFacet(_adminIdentity, facet); + } + + return result; +} + +Ice::ObjectPtr +IceInternal::Instance::findAdminFacet(const string& facet) +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + ObjectPtr result; + + // + // If the _adminAdapter was not yet created, or this facet is filtered out, we check _adminFacets + // + if(!_adminAdapter || (!_adminFacetFilter.empty() && _adminFacetFilter.find(facet) == _adminFacetFilter.end())) + { + FacetMap::iterator p = _adminFacets.find(facet); + if(p != _adminFacets.end()) + { + result = p->second; + } + } + else + { + // Otherwise, just check the _adminAdapter + result = _adminAdapter->findFacet(_adminIdentity, facet); + } + + return result; +} + +FacetMap +IceInternal::Instance::findAllAdminFacets() +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(!_adminAdapter) + { + return _adminFacets; + } + else + { + FacetMap result = _adminAdapter->findAllFacets(_adminIdentity); + if(!_adminFacets.empty()) + { + // Also returns filtered facets + result.insert(_adminFacets.begin(), _adminFacets.end()); + } + return result; + } +} + +void +IceInternal::Instance::setDefaultLocator(const Ice::LocatorPrxPtr& defaultLocator) +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + _referenceFactory = _referenceFactory->setDefaultLocator(defaultLocator); +} + +void +IceInternal::Instance::setDefaultRouter(const Ice::RouterPrxPtr& defaultRouter) +{ + Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + _referenceFactory = _referenceFactory->setDefaultRouter(defaultRouter); +} + +void +IceInternal::Instance::setLogger(const Ice::LoggerPtr& logger) +{ + // + // No locking, as it can only be called during plug-in loading + // + _initData.logger = logger; +} + +#ifdef ICE_CPP11_MAPPING +void +IceInternal::Instance::setThreadHook(function threadStart, function threadStop) +{ + _initData.threadStart = std::move(threadStart); + _initData.threadStop = std::move(threadStop); +} +#else +void +IceInternal::Instance::setThreadHook(const Ice::ThreadNotificationPtr& threadHook) +{ + // + // No locking, as it can only be called during plug-in loading + // + _initData.threadHook = threadHook; +} +#endif + +namespace +{ + +bool logStdErrConvert = true; + +} + +IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const InitializationData& initData) : + _state(StateActive), + _initData(initData), + _messageSizeMax(0), + _batchAutoFlushSize(0), + _classGraphDepthMax(0), + _collectObjects(false), + _toStringMode(ICE_ENUM(ToStringMode, Unicode)), + _acceptClassCycles(false), + _implicitContext(0), + _stringConverter(Ice::getProcessStringConverter()), + _wstringConverter(Ice::getProcessWstringConverter()), + _adminEnabled(false) +{ + try + { + __setNoDelete(true); + { + IceUtilInternal::MutexPtrLock sync(staticMutex); + instanceList->push_back(this); + + if(!_initData.properties) + { + _initData.properties = createProperties(); + } + + if(!oneOfDone) + { + // + // StdOut and StdErr redirection + // + string stdOutFilename = _initData.properties->getProperty("Ice.StdOut"); + string stdErrFilename = _initData.properties->getProperty("Ice.StdErr"); + + if(stdOutFilename != "") + { + FILE* file = IceUtilInternal::freopen(stdOutFilename, "a", stdout); + if(file == 0) + { + throw FileException(__FILE__, __LINE__, getSystemErrno(), stdOutFilename); + } + } + + if(stdErrFilename != "") + { + FILE* file = IceUtilInternal::freopen(stdErrFilename, "a", stderr); + if(file == 0) + { + throw FileException(__FILE__, __LINE__, getSystemErrno(), stdErrFilename); + } + } + + if(_initData.properties->getPropertyAsInt("Ice.NullHandleAbort") > 0) + { + IceUtilInternal::nullHandleAbort = true; + } + +#ifdef NDEBUG + if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 0) > 0) + { + IceUtilInternal::printStackTraces = true; + } +#else + if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1) == 0) + { + IceUtilInternal::printStackTraces = false; + } +#endif + +#ifndef _WIN32 + string newUser = _initData.properties->getProperty("Ice.ChangeUser"); + if(!newUser.empty()) + { + struct passwd pwbuf; + vector buffer(4096); // 4KB initial buffer + struct passwd *pw; + int err; + while((err = getpwnam_r(newUser.c_str(), &pwbuf, &buffer[0], buffer.size(), &pw)) == ERANGE && + buffer.size() < 1024 * 1024) // Limit buffer to 1M + { + buffer.resize(buffer.size() * 2); + } + if(err != 0) + { + throw Ice::SyscallException(__FILE__, __LINE__, err); + } + else if(pw == 0) + { + throw InitializationException(__FILE__, __LINE__, "unknown user account `" + newUser + "'"); + } + + if(setgid(pw->pw_gid) == -1) + { + throw SyscallException(__FILE__, __LINE__, getSystemErrno()); + } + + if(initgroups(pw->pw_name, static_cast(pw->pw_gid)) == -1) + { + throw SyscallException(__FILE__, __LINE__, getSystemErrno()); + } + + if(setuid(pw->pw_uid) == -1) + { + throw SyscallException(__FILE__, __LINE__, getSystemErrno()); + } + } +#endif + oneOfDone = true; + } + + if(instanceCount() == 1) + { +#if defined(_WIN32) + WORD version = MAKEWORD(1, 1); + WSADATA data; + if(WSAStartup(version, &data) != 0) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +#endif + +#ifndef _WIN32 + struct sigaction action; + action.sa_handler = SIG_IGN; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + sigaction(SIGPIPE, &action, &oldAction); + if(_initData.properties->getPropertyAsInt("Ice.UseSyslog") > 0) + { + identForOpenlog = _initData.properties->getProperty("Ice.ProgramName"); + if(identForOpenlog.empty()) + { + identForOpenlog = ""; + } + openlog(identForOpenlog.c_str(), LOG_PID, LOG_USER); + } +#else + logStdErrConvert = + _initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) > 0 && + _initData.properties->getProperty("Ice.StdErr").empty(); +#endif + } + } + + if(!_initData.logger) + { + string logfile = _initData.properties->getProperty("Ice.LogFile"); +#ifndef _WIN32 + if(_initData.properties->getPropertyAsInt("Ice.UseSyslog") > 0) + { + if(!logfile.empty()) + { + throw InitializationException(__FILE__, __LINE__, "Both syslog and file logger cannot be enabled."); + } + + _initData.logger = ICE_MAKE_SHARED(SysLoggerI, + _initData.properties->getProperty("Ice.ProgramName"), + _initData.properties->getPropertyWithDefault("Ice.SyslogFacility", "LOG_USER")); + } + else +#endif + +#ifdef ICE_SWIFT + if(!_initData.logger && _initData.properties->getPropertyAsInt("Ice.UseOSLog") > 0) + { + _initData.logger = ICE_MAKE_SHARED(OSLogLoggerI, + _initData.properties->getProperty("Ice.ProgramName")); + } + else +#endif + +#ifdef ICE_USE_SYSTEMD + if(_initData.properties->getPropertyAsInt("Ice.UseSystemdJournal") > 0) + { + _initData.logger = ICE_MAKE_SHARED(SystemdJournalI, + _initData.properties->getProperty("Ice.ProgramName")); + } + else +#endif + if(!logfile.empty()) + { + Int sz = _initData.properties->getPropertyAsIntWithDefault("Ice.LogFile.SizeMax", 0); + if(sz < 0) + { + sz = 0; + } + _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), + logfile, true, static_cast(sz)); + } + else + { + _initData.logger = getProcessLogger(); + if(ICE_DYNAMIC_CAST(LoggerI, _initData.logger)) + { + _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), "", logStdErrConvert); + } + } + } + + const_cast(_traceLevels) = new TraceLevels(_initData.properties); + + const_cast(_defaultsAndOverrides) = + new DefaultsAndOverrides(_initData.properties, _initData.logger); + + const ACMConfig defaultClientACM(_initData.properties, _initData.logger, "Ice.ACM", ACMConfig(false)); + const ACMConfig defaultServerACM(_initData.properties, _initData.logger, "Ice.ACM", ACMConfig(true)); + + const_cast(_clientACM) = ACMConfig(_initData.properties, + _initData.logger, + "Ice.ACM.Client", + defaultClientACM); + + const_cast(_serverACM) = ACMConfig(_initData.properties, + _initData.logger, + "Ice.ACM.Server", + defaultServerACM); + + { + static const int defaultMessageSizeMax = 1024; + Int num = _initData.properties->getPropertyAsIntWithDefault("Ice.MessageSizeMax", defaultMessageSizeMax); + if(num < 1 || static_cast(num) > static_cast(0x7fffffff / 1024)) + { + const_cast(_messageSizeMax) = static_cast(0x7fffffff); + } + else + { + // Property is in kilobytes, _messageSizeMax in bytes. + const_cast(_messageSizeMax) = static_cast(num) * 1024; + } + } + + if(_initData.properties->getProperty("Ice.BatchAutoFlushSize").empty() && + !_initData.properties->getProperty("Ice.BatchAutoFlush").empty()) + { + if(_initData.properties->getPropertyAsInt("Ice.BatchAutoFlush") > 0) + { + const_cast(_batchAutoFlushSize) = _messageSizeMax; + } + } + else + { + Int num = _initData.properties->getPropertyAsIntWithDefault("Ice.BatchAutoFlushSize", 1024); // 1MB default + if(num < 1) + { + const_cast(_batchAutoFlushSize) = static_cast(num); + } + else if(static_cast(num) > static_cast(0x7fffffff / 1024)) + { + const_cast(_batchAutoFlushSize) = static_cast(0x7fffffff); + } + else + { + // Property is in kilobytes, convert in bytes. + const_cast(_batchAutoFlushSize) = static_cast(num) * 1024; + } + } + + { + static const int defaultValue = 100; + Int num = _initData.properties->getPropertyAsIntWithDefault("Ice.ClassGraphDepthMax", defaultValue); + if(num < 1 || static_cast(num) > static_cast(0x7fffffff)) + { + const_cast(_classGraphDepthMax) = static_cast(0x7fffffff); + } + else + { + const_cast(_classGraphDepthMax) = static_cast(num); + } + } + + const_cast(_collectObjects) = _initData.properties->getPropertyAsInt("Ice.CollectObjects") > 0; + + string toStringModeStr = _initData.properties->getPropertyWithDefault("Ice.ToStringMode", "Unicode"); + if(toStringModeStr == "ASCII") + { + const_cast(_toStringMode) = ICE_ENUM(ToStringMode, ASCII); + } + else if(toStringModeStr == "Compat") + { + const_cast(_toStringMode) = ICE_ENUM(ToStringMode, Compat); + } + else if(toStringModeStr != "Unicode") + { + throw InitializationException(__FILE__, __LINE__, "The value for Ice.ToStringMode must be Unicode, ASCII or Compat"); + } + + const_cast(_acceptClassCycles) = _initData.properties->getPropertyAsInt("Ice.AcceptClassCycles") > 0; + + const_cast(_implicitContext) = + ImplicitContextI::create(_initData.properties->getProperty("Ice.ImplicitContext")); + + _routerManager = new RouterManager; + + _locatorManager = new LocatorManager(_initData.properties); + + _referenceFactory = new ReferenceFactory(this, communicator); + + _requestHandlerFactory = new RequestHandlerFactory(this); + + _proxyFactory = new ProxyFactory(this); + + const bool isIPv6Supported = IceInternal::isIPv6Supported(); + const bool ipv4 = _initData.properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; + const bool ipv6 = _initData.properties->getPropertyAsIntWithDefault("Ice.IPv6", isIPv6Supported ? 1 : 0) > 0; + if(!ipv4 && !ipv6) + { + throw InitializationException(__FILE__, __LINE__, "Both IPV4 and IPv6 support cannot be disabled."); + } + else if(ipv4 && ipv6) + { + _protocolSupport = EnableBoth; + } + else if(ipv4) + { + _protocolSupport = EnableIPv4; + } + else + { + _protocolSupport = EnableIPv6; + } + _preferIPv6 = _initData.properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0; + + _networkProxy = IceInternal::createNetworkProxy(_initData.properties, _protocolSupport); + + _endpointFactoryManager = new EndpointFactoryManager(this); + + _dynamicLibraryList = new DynamicLibraryList; + + _pluginManager = ICE_MAKE_SHARED(PluginManagerI, communicator, _dynamicLibraryList); + + if(!_initData.valueFactoryManager) + { + _initData.valueFactoryManager = ICE_MAKE_SHARED(ValueFactoryManagerI); + } + + _objectFactoryMapHint = _objectFactoryMap.end(); + + _outgoingConnectionFactory = new OutgoingConnectionFactory(communicator, this); + + _objectAdapterFactory = ICE_MAKE_SHARED(ObjectAdapterFactory, this, communicator); + + _retryQueue = new RetryQueue(this); + + __setNoDelete(false); + } + catch(...) + { + { + IceUtilInternal::MutexPtrLock sync(staticMutex); + instanceList->remove(this); + } + destroy(); + __setNoDelete(false); + throw; + } +} + +IceInternal::Instance::~Instance() +{ + assert(_state == StateDestroyed); + assert(!_referenceFactory); + assert(!_proxyFactory); + assert(!_outgoingConnectionFactory); + + assert(!_objectAdapterFactory); + assert(!_clientThreadPool); + assert(!_serverThreadPool); + assert(!_endpointHostResolver); + assert(!_retryQueue); + assert(!_timer); + assert(!_routerManager); + assert(!_locatorManager); + assert(!_endpointFactoryManager); + assert(!_dynamicLibraryList); + assert(!_pluginManager); + + IceUtilInternal::MutexPtrLock sync(staticMutex); + if(instanceList != 0) + { + instanceList->remove(this); + } + if(instanceCount() == 0) + { +#if defined(_WIN32) + WSACleanup(); +#endif + +#ifndef _WIN32 + sigaction(SIGPIPE, &oldAction, 0); + + if(!identForOpenlog.empty()) + { + closelog(); + identForOpenlog.clear(); + } +#endif + } +} + +void +IceInternal::Instance::finishSetup(int& argc, const char* argv[], const Ice::CommunicatorPtr& communicator) +{ + // + // Load plug-ins. + // + assert(!_serverThreadPool); + PluginManagerI* pluginManagerImpl = dynamic_cast(_pluginManager.get()); + assert(pluginManagerImpl); + pluginManagerImpl->loadPlugins(argc, argv); + + // + // Initialize the endpoint factories once all the plugins are loaded. This gives + // the opportunity for the endpoint factories to find underyling factories. + // + _endpointFactoryManager->initialize(); + + // + // Reset _stringConverter and _wstringConverter, in case a plugin changed them + // + _stringConverter = Ice::getProcessStringConverter(); + _wstringConverter = Ice::getProcessWstringConverter(); + + // + // Create Admin facets, if enabled. + // + // Note that any logger-dependent admin facet must be created after we load all plugins, + // since one of these plugins can be a Logger plugin that sets a new logger during loading + // + + if(_initData.properties->getProperty("Ice.Admin.Enabled") == "") + { + _adminEnabled = _initData.properties->getProperty("Ice.Admin.Endpoints") != ""; + } + else + { + _adminEnabled = _initData.properties->getPropertyAsInt("Ice.Admin.Enabled") > 0; + } + + StringSeq facetSeq = _initData.properties->getPropertyAsList("Ice.Admin.Facets"); + if(!facetSeq.empty()) + { + _adminFacetFilter.insert(facetSeq.begin(), facetSeq.end()); + } + + if(_adminEnabled) + { + // + // Process facet + // + const string processFacetName = "Process"; + if(_adminFacetFilter.empty() || _adminFacetFilter.find(processFacetName) != _adminFacetFilter.end()) + { + _adminFacets.insert(make_pair(processFacetName, ICE_MAKE_SHARED(ProcessI, communicator))); + } + + // + // Logger facet + // + const string loggerFacetName = "Logger"; + if(_adminFacetFilter.empty() || _adminFacetFilter.find(loggerFacetName) != _adminFacetFilter.end()) + { + LoggerAdminLoggerPtr logger = createLoggerAdminLogger(_initData.properties, _initData.logger); + setLogger(logger); + _adminFacets.insert(make_pair(loggerFacetName, logger->getFacet())); + } + + // + // Properties facet + // + const string propertiesFacetName = "Properties"; + PropertiesAdminIPtr propsAdmin; + if(_adminFacetFilter.empty() || _adminFacetFilter.find(propertiesFacetName) != _adminFacetFilter.end()) + { + propsAdmin = ICE_MAKE_SHARED(PropertiesAdminI, this); + _adminFacets.insert(make_pair(propertiesFacetName, propsAdmin)); + } + + // + // Metrics facet + // + const string metricsFacetName = "Metrics"; + if(_adminFacetFilter.empty() || _adminFacetFilter.find(metricsFacetName) != _adminFacetFilter.end()) + { + CommunicatorObserverIPtr observer = ICE_MAKE_SHARED(CommunicatorObserverI, _initData); + _initData.observer = observer; + _adminFacets.insert(make_pair(metricsFacetName, observer->getFacet())); + + // + // Make sure the metrics admin facet receives property updates. + // + if(propsAdmin) + { +#ifdef ICE_CPP11_MAPPING + auto metricsAdmin = observer->getFacet(); + propsAdmin->addUpdateCallback( + [metricsAdmin](const PropertyDict& changes) { metricsAdmin->updated(changes); }); +#else + propsAdmin->addUpdateCallback(observer->getFacet()); +#endif + } + } + } + + // + // Set observer updater + // + if(_initData.observer) + { + _initData.observer->setObserverUpdater(ICE_MAKE_SHARED(ObserverUpdaterI, this)); + } + + // + // Create threads. + // + try + { + bool hasPriority = _initData.properties->getProperty("Ice.ThreadPriority") != ""; + int priority = _initData.properties->getPropertyAsInt("Ice.ThreadPriority"); + if(hasPriority) + { + _timer = new Timer(priority); + } + else + { + _timer = new Timer; + } + } + catch(const IceUtil::Exception& ex) + { + Error out(_initData.logger); + out << "cannot create thread for timer:\n" << ex; + throw; + } + + try + { + _endpointHostResolver = new EndpointHostResolver(this); + bool hasPriority = _initData.properties->getProperty("Ice.ThreadPriority") != ""; + int priority = _initData.properties->getPropertyAsInt("Ice.ThreadPriority"); + if(hasPriority) + { + _endpointHostResolver->start(0, priority); + } + else + { + _endpointHostResolver->start(); + } + } + catch(const IceUtil::Exception& ex) + { + Error out(_initData.logger); + out << "cannot create thread for endpoint host resolver:\n" << ex; + throw; + } + + _clientThreadPool = new ThreadPool(this, "Ice.ThreadPool.Client", 0); + + // + // The default router/locator may have been set during the loading of plugins. + // Therefore we make sure it is not already set before checking the property. + // + if(!_referenceFactory->getDefaultRouter()) + { + RouterPrxPtr router = ICE_UNCHECKED_CAST(RouterPrx, _proxyFactory->propertyToProxy("Ice.Default.Router")); + if(router) + { + _referenceFactory = _referenceFactory->setDefaultRouter(router); + } + } + + if(!_referenceFactory->getDefaultLocator()) + { + LocatorPrxPtr locator = ICE_UNCHECKED_CAST(LocatorPrx, _proxyFactory->propertyToProxy("Ice.Default.Locator")); + if(locator) + { + _referenceFactory = _referenceFactory->setDefaultLocator(locator); + } + } + + // + // Show process id if requested (but only once). + // + bool printProcessId = false; + if(!printProcessIdDone && _initData.properties->getPropertyAsInt("Ice.PrintProcessId") > 0) + { + // + // Safe double-check locking (no dependent variable!) + // + IceUtilInternal::MutexPtrLock sync(staticMutex); + printProcessId = !printProcessIdDone; + + // + // We anticipate: we want to print it once, and we don't care when. + // + printProcessIdDone = true; + } + + if(printProcessId) + { +#ifdef _MSC_VER + consoleOut << GetCurrentProcessId() << endl; +#else + consoleOut << getpid() << endl; +#endif + } + + // + // Server thread pool initialization is lazy in serverThreadPool(). + // + + // + // An application can set Ice.InitPlugins=0 if it wants to postpone + // initialization until after it has interacted directly with the + // plug-ins. + // + if(_initData.properties->getPropertyAsIntWithDefault("Ice.InitPlugins", 1) > 0) + { + pluginManagerImpl->initializePlugins(); + } + + // + // This must be done last as this call creates the Ice.Admin object adapter + // and eventually register a process proxy with the Ice locator (allowing + // remote clients to invoke Admin facets as soon as it's registered). + // + // Note: getAdmin here can return 0 and do nothing in the event the + // application set Ice.Admin.Enabled but did not set Ice.Admin.Enpoints + // and one or more of the properties required to create the Admin object. + // + if(_adminEnabled && _initData.properties->getPropertyAsIntWithDefault("Ice.Admin.DelayCreation", 0) <= 0) + { + getAdmin(); + } +} + +void +IceInternal::Instance::destroy() +{ + { + Lock sync(*this); + + // + // If destroy is in progress, wait for it to be done. This is + // necessary in case destroy() is called concurrently by + // multiple threads. + // + while(_state == StateDestroyInProgress) + { + wait(); + } + + if(_state == StateDestroyed) + { + return; + } + _state = StateDestroyInProgress; + } + + // + // Shutdown and destroy all the incoming and outgoing Ice + // connections and wait for the connections to be finished. + // + if(_objectAdapterFactory) + { + _objectAdapterFactory->shutdown(); + } + + if(_outgoingConnectionFactory) + { + _outgoingConnectionFactory->destroy(); + } + + if(_objectAdapterFactory) + { + _objectAdapterFactory->destroy(); + } + + if(_outgoingConnectionFactory) + { + _outgoingConnectionFactory->waitUntilFinished(); + } + + if(_retryQueue) + { + _retryQueue->destroy(); // Must be called before destroying thread pools. + } + + if(_initData.observer) + { + CommunicatorObserverIPtr observer = ICE_DYNAMIC_CAST(CommunicatorObserverI, _initData.observer); + if(observer) + { + observer->destroy(); // Break cyclic reference counts. Don't clear _observer, it's immutable. + } + _initData.observer->setObserverUpdater(0); // Break cyclic reference count. + } + + LoggerAdminLoggerPtr logger = ICE_DYNAMIC_CAST(LoggerAdminLogger, _initData.logger); + if(logger) + { + // + // This only disables the remote logging; we don't set or reset _initData.logger + // + logger->destroy(); + } + + // + // Now, destroy the thread pools. This must be done *only* after + // all the connections are finished (the connections destruction + // can require invoking callbacks with the thread pools). + // + if(_serverThreadPool) + { + _serverThreadPool->destroy(); + } + if(_clientThreadPool) + { + _clientThreadPool->destroy(); + } + if(_endpointHostResolver) + { + _endpointHostResolver->destroy(); + } + if(_timer) + { + _timer->destroy(); + } + + // + // Wait for all the threads to be finished. + // + if(_clientThreadPool) + { + _clientThreadPool->joinWithAllThreads(); + } + if(_serverThreadPool) + { + _serverThreadPool->joinWithAllThreads(); + } + if(_endpointHostResolver) + { + _endpointHostResolver->getThreadControl().join(); + } + +#ifdef ICE_CPP11_COMPILER + for(const auto& p : _objectFactoryMap) + { + p.second->destroy(); + } +#else + for_each(_objectFactoryMap.begin(), _objectFactoryMap.end(), + Ice::secondVoidMemFun(&ObjectFactory::destroy)); +#endif + _objectFactoryMap.clear(); + + if(_routerManager) + { + _routerManager->destroy(); + } + + if(_locatorManager) + { + _locatorManager->destroy(); + } + + if(_endpointFactoryManager) + { + _endpointFactoryManager->destroy(); + } + + if(_initData.properties->getPropertyAsInt("Ice.Warn.UnusedProperties") > 0) + { + set unusedProperties = static_cast(_initData.properties.get())->getUnusedProperties(); + if(unusedProperties.size() != 0) + { + Warning out(_initData.logger); + out << "The following properties were set but never read:"; + for(set::const_iterator p = unusedProperties.begin(); p != unusedProperties.end(); ++p) + { + out << "\n " << *p; + } + } + } + + // + // Destroy last so that a Logger plugin can receive all log/traces before its destruction. + // + if(_pluginManager) + { + _pluginManager->destroy(); + } + + { + Lock sync(*this); + + _objectAdapterFactory = 0; + _outgoingConnectionFactory = 0; + _retryQueue = 0; + + _serverThreadPool = 0; + _clientThreadPool = 0; + _endpointHostResolver = 0; + _timer = 0; + + _referenceFactory = 0; + _requestHandlerFactory = 0; + _proxyFactory = 0; + _routerManager = 0; + _locatorManager = 0; + _endpointFactoryManager = 0; + _pluginManager = 0; + _dynamicLibraryList = 0; + + _adminAdapter = 0; + _adminFacets.clear(); + + _state = StateDestroyed; + notifyAll(); + } +} + +void +IceInternal::Instance::updateConnectionObservers() +{ + try + { + assert(_outgoingConnectionFactory); + _outgoingConnectionFactory->updateConnectionObservers(); + assert(_objectAdapterFactory); + _objectAdapterFactory->updateObservers(&ObjectAdapterI::updateConnectionObservers); + } + catch(const Ice::CommunicatorDestroyedException&) + { + } +} + +void +IceInternal::Instance::updateThreadObservers() +{ + try + { + if(_clientThreadPool) + { + _clientThreadPool->updateObservers(); + } + if(_serverThreadPool) + { + _serverThreadPool->updateObservers(); + } + assert(_objectAdapterFactory); + _objectAdapterFactory->updateObservers(&ObjectAdapterI::updateThreadObservers); + if(_endpointHostResolver) + { + _endpointHostResolver->updateObserver(); + } + if(_timer) + { + _timer->updateObserver(_initData.observer); + } + } + catch(const Ice::CommunicatorDestroyedException&) + { + } +} + +BufSizeWarnInfo +IceInternal::Instance::getBufSizeWarn(Short type) +{ + IceUtil::Mutex::Lock lock(_setBufSizeWarnMutex); + + return getBufSizeWarnInternal(type); +} + +BufSizeWarnInfo +IceInternal::Instance::getBufSizeWarnInternal(Short type) +{ + BufSizeWarnInfo info; + map::iterator p = _setBufSizeWarn.find(type); + if(p == _setBufSizeWarn.end()) + { + info.sndWarn = false; + info.sndSize = -1; + info.rcvWarn = false; + info.rcvSize = -1; + _setBufSizeWarn.insert(make_pair(type, info)); + } + else + { + info = p->second; + } + return info; +} + +void +IceInternal::Instance::setSndBufSizeWarn(Short type, int size) +{ + IceUtil::Mutex::Lock lock(_setBufSizeWarnMutex); + + BufSizeWarnInfo info = getBufSizeWarnInternal(type); + info.sndWarn = true; + info.sndSize = size; + _setBufSizeWarn[type] = info; +} + +void +IceInternal::Instance::setRcvBufSizeWarn(Short type, int size) +{ + IceUtil::Mutex::Lock lock(_setBufSizeWarnMutex); + + BufSizeWarnInfo info = getBufSizeWarnInternal(type); + info.rcvWarn = true; + info.rcvSize = size; + _setBufSizeWarn[type] = info; +} + +void +IceInternal::Instance::addObjectFactory(const Ice::ObjectFactoryPtr& factory, const string& id) +{ + Lock sync(*this); + + // + // Create a ValueFactory wrapper around the given ObjectFactory and register the wrapper + // with the value factory manager. This may raise AlreadyRegisteredException. + // +#ifdef ICE_CPP11_MAPPING + _initData.valueFactoryManager->add([factory](const string& ident) + { + return factory->create(ident); + }, + id); +#else + class ValueFactoryWrapper: public Ice::ValueFactory + { + public: + + ValueFactoryWrapper(const Ice::ObjectFactoryPtr& factory) : _objectFactory(factory) + { + } + + Ice::ValuePtr create(const std::string& id) + { + return _objectFactory->create(id); + } + + private: + + Ice::ObjectFactoryPtr _objectFactory; + }; + + _initData.valueFactoryManager->add(new ValueFactoryWrapper(factory), id); +#endif + + // + // Also record the object factory in our own map. + // + _objectFactoryMapHint = _objectFactoryMap.insert(_objectFactoryMapHint, + pair(id, factory)); +} + +Ice::ObjectFactoryPtr +IceInternal::Instance::findObjectFactory(const string& id) const +{ + Lock sync(*this); + + ObjectFactoryMap& objectfactoryMap = const_cast(_objectFactoryMap); + + ObjectFactoryMap::iterator p = objectfactoryMap.end(); + if(_objectFactoryMapHint != objectfactoryMap.end()) + { + if(_objectFactoryMapHint->first == id) + { + p = _objectFactoryMapHint; + } + } + + if(p == objectfactoryMap.end()) + { + p = objectfactoryMap.find(id); + } + + if(p != objectfactoryMap.end()) + { + _objectFactoryMapHint = p; + return p->second; + } + else + { + return ICE_NULLPTR; + } +} + +IceInternal::ProcessI::ProcessI(const CommunicatorPtr& communicator) : + _communicator(communicator) +{ +} + +void +IceInternal::ProcessI::shutdown(const Current&) +{ + _communicator->shutdown(); +} + +void +#ifdef ICE_CPP11_MAPPING +IceInternal::ProcessI::writeMessage(string message, Int fd, const Current&) +#else +IceInternal::ProcessI::writeMessage(const string& message, Int fd, const Current&) +#endif +{ + switch(fd) + { + case 1: + { + consoleOut << message << endl; + break; + } + case 2: + { + consoleErr << message << endl; + break; + } + } +} diff --git a/Sources/IceCpp/Instrumentation.cpp b/Sources/IceCpp/Instrumentation.cpp new file mode 100644 index 0000000..db90920 --- /dev/null +++ b/Sources/IceCpp/Instrumentation.cpp @@ -0,0 +1,188 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Instrumentation.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::Instrumentation::Observer::~Observer() +{ +} + +Ice::Instrumentation::ThreadObserver::~ThreadObserver() +{ +} + +Ice::Instrumentation::ConnectionObserver::~ConnectionObserver() +{ +} + +Ice::Instrumentation::DispatchObserver::~DispatchObserver() +{ +} + +Ice::Instrumentation::ChildInvocationObserver::~ChildInvocationObserver() +{ +} + +Ice::Instrumentation::RemoteObserver::~RemoteObserver() +{ +} + +Ice::Instrumentation::CollocatedObserver::~CollocatedObserver() +{ +} + +Ice::Instrumentation::InvocationObserver::~InvocationObserver() +{ +} + +Ice::Instrumentation::ObserverUpdater::~ObserverUpdater() +{ +} + +Ice::Instrumentation::CommunicatorObserver::~CommunicatorObserver() +{ +} + +#else // C++98 mapping + +namespace +{ + +namespace +{ + +} + +} + +Ice::Instrumentation::Observer::~Observer() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(Observer* p) { return p; } +/// \endcond + +Ice::Instrumentation::ThreadObserver::~ThreadObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(ThreadObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::ConnectionObserver::~ConnectionObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(ConnectionObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::DispatchObserver::~DispatchObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(DispatchObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::ChildInvocationObserver::~ChildInvocationObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(ChildInvocationObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::RemoteObserver::~RemoteObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(RemoteObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::CollocatedObserver::~CollocatedObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(CollocatedObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::InvocationObserver::~InvocationObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(InvocationObserver* p) { return p; } +/// \endcond + +Ice::Instrumentation::ObserverUpdater::~ObserverUpdater() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(ObserverUpdater* p) { return p; } +/// \endcond + +Ice::Instrumentation::CommunicatorObserver::~CommunicatorObserver() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::Instrumentation::upCast(CommunicatorObserver* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/InstrumentationF.cpp b/Sources/IceCpp/InstrumentationF.cpp new file mode 100644 index 0000000..aa05399 --- /dev/null +++ b/Sources/IceCpp/InstrumentationF.cpp @@ -0,0 +1,66 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `InstrumentationF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +namespace +{ + +} + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/InstrumentationI.cpp b/Sources/IceCpp/InstrumentationI.cpp new file mode 100644 index 0000000..e4ca6fa --- /dev/null +++ b/Sources/IceCpp/InstrumentationI.cpp @@ -0,0 +1,1094 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace Ice::Instrumentation; +using namespace IceMX; + +#ifdef ICE_CPP11_MAPPING +# define ICE_OBJECT_PRX Ice::ObjectPrx +#else +# define ICE_OBJECT_PRX IceProxy::Ice::Object +#endif + +namespace +{ + +int ThreadMetrics::* +getThreadStateMetric(ThreadState s) +{ + switch(s) + { + case ICE_ENUM(ThreadState, ThreadStateIdle): + return 0; + case ICE_ENUM(ThreadState, ThreadStateInUseForIO): + return &ThreadMetrics::inUseForIO; + case ICE_ENUM(ThreadState, ThreadStateInUseForUser): + return &ThreadMetrics::inUseForUser; + case ICE_ENUM(ThreadState, ThreadStateInUseForOther): + return &ThreadMetrics::inUseForOther; + default: + assert(false); + return 0; + } +} + +struct ThreadStateChanged +{ + ThreadStateChanged(ThreadState oldStateP, ThreadState newStateP) : oldState(oldStateP), newState(newStateP) + { + } + + void operator()(const ThreadMetricsPtr& v) + { + if(oldState != ICE_ENUM(ThreadState, ThreadStateIdle)) + { + --(v.get()->*getThreadStateMetric(oldState)); + } + if(newState != ICE_ENUM(ThreadState, ThreadStateIdle)) + { + ++(v.get()->*getThreadStateMetric(newState)); + } + } + + ThreadState oldState; + ThreadState newState; +}; + +IPConnectionInfo* +getIPConnectionInfo(const ConnectionInfoPtr& info) +{ + for(ConnectionInfoPtr p = info; p; p = p->underlying) + { + IPConnectionInfo* ipInfo = dynamic_cast(p.get()); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +class ConnectionHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &ConnectionHelper::getParent); + add("id", &ConnectionHelper::getId); + add("state", &ConnectionHelper::getState); + addConnectionAttributes(*this); + } + }; + static Attributes attributes; + + ConnectionHelper(const ConnectionInfoPtr& con, const EndpointPtr& endpt, ConnectionState state) : + _connectionInfo(con), _endpoint(endpt), _state(state) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + const string& + getId() const + { + if(_id.empty()) + { + ostringstream os; + IPConnectionInfo* info = getIPConnectionInfo(_connectionInfo); + if(info) + { + os << info->localAddress << ':' << info->localPort; + os << " -> "; + os << info->remoteAddress << ':' << info->remotePort; + } + else + { + os << "connection-" << _connectionInfo.get(); + } + if(!_connectionInfo->connectionId.empty()) + { + os << " [" << _connectionInfo->connectionId << "]"; + } + _id = os.str(); + } + return _id; + } + + string + getState() const + { + switch(_state) + { + case ICE_ENUM(ConnectionState, ConnectionStateValidating): + return "validating"; + case ICE_ENUM(ConnectionState, ConnectionStateHolding): + return "holding"; + case ICE_ENUM(ConnectionState, ConnectionStateActive): + return "active"; + case ICE_ENUM(ConnectionState, ConnectionStateClosing): + return "closing"; + case ICE_ENUM(ConnectionState, ConnectionStateClosed): + return "closed"; + default: + assert(false); + return ""; + } + } + + string + getParent() const + { + if(!_connectionInfo->adapterName.empty()) + { + return _connectionInfo->adapterName; + } + else + { + return "Communicator"; + } + } + + const ConnectionInfoPtr& + getConnectionInfo() const + { + return _connectionInfo; + } + + const EndpointPtr& + getEndpoint() const + { + return _endpoint; + } + + const EndpointInfoPtr& + getEndpointInfo() const + { + if(!_endpointInfo) + { + _endpointInfo = _endpoint->getInfo(); + } + return _endpointInfo; + } + +private: + + const ConnectionInfoPtr& _connectionInfo; + const EndpointPtr& _endpoint; + const ConnectionState _state; + mutable string _id; + mutable EndpointInfoPtr _endpointInfo; +}; + +ConnectionHelper::Attributes ConnectionHelper::attributes; + +class DispatchHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &DispatchHelper::getParent); + add("id", &DispatchHelper::getId); + add("connection", &DispatchHelper::getConnection); + + addConnectionAttributes(*this); + + add("operation", &DispatchHelper::getCurrent, &Current::operation); + add("identity", &DispatchHelper::getIdentity); + add("facet", &DispatchHelper::getCurrent, &Current::facet); + add("mode", &DispatchHelper::getMode); + add("requestId", &DispatchHelper::getCurrent, &Current::requestId); + + setDefault(&DispatchHelper::resolve); + } + }; + static Attributes attributes; + + DispatchHelper(const Current& current, int size) : _current(current), _size(size) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + virtual void initMetrics(const DispatchMetricsPtr& v) const + { + v->size += _size; + } + + string resolve(const string& attribute) const + { + if(attribute.compare(0, 8, "context.") == 0) + { + Context::const_iterator p = _current.ctx.find(attribute.substr(8)); + if(p != _current.ctx.end()) + { + return p->second; + } + } + throw invalid_argument(attribute); + } + + string + getMode() const + { + return _current.requestId == 0 ? "oneway" : "twoway"; + } + + const string& + getId() const + { + if(_id.empty()) + { + ostringstream os; + if(!_current.id.category.empty()) + { + os << _current.id.category << '/'; + } + os << _current.id.name << " [" << _current.operation << ']'; + _id = os.str(); + } + return _id; + } + + string + getParent() const + { + return _current.adapter->getName(); + } + + ConnectionInfoPtr + getConnectionInfo() const + { + if(_current.con) + { + return _current.con->getInfo(); + } + return 0; + } + + EndpointPtr + getEndpoint() const + { + if(_current.con) + { + return _current.con->getEndpoint(); + } + return 0; + } + + const ConnectionPtr& + getConnection() const + { + return _current.con; + } + + const EndpointInfoPtr& + getEndpointInfo() const + { + if(_current.con && !_endpointInfo) + { + _endpointInfo = _current.con->getEndpoint()->getInfo(); + } + return _endpointInfo; + } + + const Current& + getCurrent() const + { + return _current; + } + + string + getIdentity() const + { + return _current.adapter->getCommunicator()->identityToString(_current.id); + } + +private: + + const Current& _current; + const int _size; + mutable string _id; + mutable EndpointInfoPtr _endpointInfo; +}; + +DispatchHelper::Attributes DispatchHelper::attributes; + +class InvocationHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &InvocationHelper::getParent); + add("id", &InvocationHelper::getId); + + add("operation", &InvocationHelper::getOperation); + add("identity", &InvocationHelper::getIdentity); + add("facet", &InvocationHelper::getProxy, &ICE_OBJECT_PRX::ice_getFacet); + add("encoding", &InvocationHelper::getProxy, &ICE_OBJECT_PRX::ice_getEncodingVersion); + add("mode", &InvocationHelper::getMode); + add("proxy", &InvocationHelper::getProxy); + + setDefault(&InvocationHelper::resolve); + } + }; + static Attributes attributes; + InvocationHelper(const ObjectPrxPtr& proxy, const string& op, const Context& ctx) : + _proxy(proxy), _operation(op), _context(ctx) + { + } + + string resolve(const string& attribute) const + { + if(attribute.compare(0, 8, "context.") == 0) + { + Context::const_iterator p = _context.find(attribute.substr(8)); + if(p != _context.end()) + { + return p->second; + } + } + throw invalid_argument(attribute); + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + string + getMode() const + { + if(!_proxy) + { + throw invalid_argument("mode"); + } + + if(_proxy->ice_isTwoway()) + { + return "twoway"; + } + else if(_proxy->ice_isOneway()) + { + return "oneway"; + } + else if(_proxy->ice_isBatchOneway()) + { + return "batch-oneway"; + } + else if(_proxy->ice_isDatagram()) + { + return "datagram"; + } + else if(_proxy->ice_isBatchDatagram()) + { + return "batch-datagram"; + } + else + { + throw invalid_argument("mode"); + } + } + + const string& + getId() const + { + if(_id.empty()) + { + ostringstream os; + if(_proxy) + { + try + { + os << _proxy->ice_endpoints(Ice::EndpointSeq())->ice_toString() << " [" << _operation << ']'; + } + catch(const Exception&) + { + // Either a fixed proxy or the communicator is destroyed. + os << _proxy->ice_getCommunicator()->identityToString(_proxy->ice_getIdentity()); + os << " [" << _operation << ']'; + } + } + else + { + os << _operation; + } + _id = os.str(); + } + return _id; + } + + string + getParent() const + { + return "Communicator"; + } + + const ObjectPrxPtr& + getProxy() const + { + return _proxy; + } + + string + getIdentity() const + { + if(_proxy) + { + return _proxy->ice_getCommunicator()->identityToString(_proxy->ice_getIdentity()); + } + else + { + return ""; + } + } + + const string& + getOperation() const + { + return _operation; + } + +private: + + const ObjectPrxPtr& _proxy; + const string& _operation; + const Context& _context; + mutable string _id; +}; + +InvocationHelper::Attributes InvocationHelper::attributes; + +class RemoteInvocationHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &RemoteInvocationHelper::getParent); + add("id", &RemoteInvocationHelper::getId); + add("requestId", &RemoteInvocationHelper::_requestId); + addConnectionAttributes(*this); + } + }; + static Attributes attributes; + + RemoteInvocationHelper(const ConnectionInfoPtr& con, const EndpointPtr& endpt, int requestId, int size) : + _connectionInfo(con), _endpoint(endpt), _requestId(requestId), _size(size) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + virtual void initMetrics(const RemoteMetricsPtr& v) const + { + v->size += _size; + } + + const string& + getId() const + { + if(_id.empty()) + { + _id = _endpoint->toString(); + if(!_connectionInfo->connectionId.empty()) + { + _id += " [" + _connectionInfo->connectionId + "]"; + } + } + return _id; + } + + string + getParent() const + { + if(!_connectionInfo->adapterName.empty()) + { + return _connectionInfo->adapterName; + } + else + { + return "Communicator"; + } + } + + const ConnectionInfoPtr& + getConnectionInfo() const + { + return _connectionInfo; + } + + const EndpointPtr& + getEndpoint() const + { + return _endpoint; + } + + const EndpointInfoPtr& + getEndpointInfo() const + { + if(!_endpointInfo) + { + _endpointInfo = _endpoint->getInfo(); + } + return _endpointInfo; + } + +private: + + const ConnectionInfoPtr& _connectionInfo; + const EndpointPtr& _endpoint; + +protected: + // + // COMPILERFIX: Clang 4.2 reports unused-private-field for the _requestId + // field that is only used in the nested Attributes class. + // + const int _requestId; + +private: + const int _size; + mutable string _id; + mutable EndpointInfoPtr _endpointInfo; +}; + +RemoteInvocationHelper::Attributes RemoteInvocationHelper::attributes; + +class CollocatedInvocationHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &CollocatedInvocationHelper::getParent); + add("id", &CollocatedInvocationHelper::getId); + add("requestId", &CollocatedInvocationHelper::_requestId); + } + }; + static Attributes attributes; + + CollocatedInvocationHelper(const Ice::ObjectAdapterPtr& adapter, int requestId, int size) : + _requestId(requestId), _size(size), _id(adapter->getName()) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + virtual void initMetrics(const CollocatedMetricsPtr& v) const + { + v->size += _size; + } + + const string& + getId() const + { + return _id; + } + + string + getParent() const + { + return "Communicator"; + } + +protected: + // + // COMPILERFIX: Clang 4.2 reports unused-private-field for the _requestId + // field that is only used in the nested Attributes class. + // + const int _requestId; + +private: + + const int _size; + mutable string _id; +}; + +CollocatedInvocationHelper::Attributes CollocatedInvocationHelper::attributes; + +class ThreadHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &ThreadHelper::_parent); + add("id", &ThreadHelper::_id); + } + }; + static Attributes attributes; + + ThreadHelper(const string& parent, const string& id, ThreadState state) : _parent(parent), _id(id), _state(state) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + virtual void initMetrics(const ThreadMetricsPtr& v) const + { + if(_state != ICE_ENUM(ThreadState, ThreadStateIdle)) + { + ++(v.get()->*getThreadStateMetric(_state)); + } + } + +private: + + const string _parent; + const string _id; + const ThreadState _state; +}; + +ThreadHelper::Attributes ThreadHelper::attributes; + +class EndpointHelper : public MetricsHelperT +{ +public: + + class Attributes : public AttributeResolverT + { + public: + + Attributes() + { + add("parent", &EndpointHelper::getParent); + add("id", &EndpointHelper::getId); + addEndpointAttributes(*this); + } + }; + static Attributes attributes; + + EndpointHelper(const EndpointPtr& endpt, const string& id) : _endpoint(endpt), _id(id) + { + } + + EndpointHelper(const EndpointPtr& endpt) : _endpoint(endpt) + { + } + + virtual string operator()(const string& attribute) const + { + return attributes(this, attribute); + } + + const EndpointInfoPtr& + getEndpointInfo() const + { + if(!_endpointInfo) + { + _endpointInfo = _endpoint->getInfo(); + } + return _endpointInfo; + } + + string + getParent() const + { + return "Communicator"; + } + + const string& + getId() const + { + if(_id.empty()) + { + _id = _endpoint->toString(); + } + return _id; + } + + string + getEndpoint() const + { + return _endpoint->toString(); + } + +private: + + const EndpointPtr _endpoint; + mutable string _id; + mutable EndpointInfoPtr _endpointInfo; +}; + +EndpointHelper::Attributes EndpointHelper::attributes; + +} + +void +ConnectionObserverI::sentBytes(Int num) +{ + forEach(add(&ConnectionMetrics::sentBytes, num)); + if(_delegate) + { + _delegate->sentBytes(num); + } +} + +void +ConnectionObserverI::receivedBytes(Int num) +{ + forEach(add(&ConnectionMetrics::receivedBytes, num)); + if(_delegate) + { + _delegate->receivedBytes(num); + } +} + +void +ThreadObserverI::stateChanged(ThreadState oldState, ThreadState newState) +{ + forEach(ThreadStateChanged(oldState, newState)); + if(_delegate) + { + _delegate->stateChanged(oldState, newState); + } + +} + +void +DispatchObserverI::userException() +{ + forEach(inc(&DispatchMetrics::userException)); + if(_delegate) + { + _delegate->userException(); + } +} + +void +DispatchObserverI::reply(Int size) +{ + forEach(add(&DispatchMetrics::replySize, size)); + if(_delegate) + { + _delegate->reply(size); + } +} + +void +RemoteObserverI::reply(Int size) +{ + forEach(add(&RemoteMetrics::replySize, size)); + if(_delegate) + { + _delegate->reply(size); + } +} + +void +CollocatedObserverI::reply(Int size) +{ + forEach(add(&CollocatedMetrics::replySize, size)); + if(_delegate) + { + _delegate->reply(size); + } +} + +void +InvocationObserverI::retried() +{ + forEach(inc(&InvocationMetrics::retry)); + if(_delegate) + { + _delegate->retried(); + } +} + +void +InvocationObserverI::userException() +{ + forEach(inc(&InvocationMetrics::userException)); + if(_delegate) + { + _delegate->userException(); + } +} + +RemoteObserverPtr +InvocationObserverI::getRemoteObserver(const ConnectionInfoPtr& connection, + const EndpointPtr& endpoint, + int requestId, + int size) +{ + try + { + RemoteObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getRemoteObserver(connection, endpoint, requestId, size); + } + return getObserverWithDelegate("Remote", + RemoteInvocationHelper(connection, endpoint, requestId, size), + delegate); + } + catch(const exception&) + { + } + return ICE_NULLPTR; +} + +CollocatedObserverPtr +InvocationObserverI::getCollocatedObserver(const Ice::ObjectAdapterPtr& adapter, int requestId, int size) +{ + try + { + CollocatedObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getCollocatedObserver(adapter, requestId, size); + } + return getObserverWithDelegate("Collocated", + CollocatedInvocationHelper(adapter, requestId, size), + delegate); + } + catch(const exception&) + { + } + return ICE_NULLPTR; +} + +CommunicatorObserverI::CommunicatorObserverI(const InitializationData& initData) : + _metrics(new MetricsAdminI(initData.properties, initData.logger)), + _delegate(initData.observer), + _connections(_metrics, "Connection"), + _dispatch(_metrics, "Dispatch"), + _invocations(_metrics, "Invocation"), + _threads(_metrics, "Thread"), + _connects(_metrics, "ConnectionEstablishment"), + _endpointLookups(_metrics, "EndpointLookup") +{ + _invocations.registerSubMap("Remote", &InvocationMetrics::remotes); + _invocations.registerSubMap("Collocated", &InvocationMetrics::collocated); +} + +void +CommunicatorObserverI::setObserverUpdater(const ObserverUpdaterPtr& updater) +{ + _connections.setUpdater(newUpdater(updater, &ObserverUpdater::updateConnectionObservers)); + _threads.setUpdater(newUpdater(updater, &ObserverUpdater::updateThreadObservers)); + if(_delegate) + { + _delegate->setObserverUpdater(updater); + } +} + +ObserverPtr +CommunicatorObserverI::getConnectionEstablishmentObserver(const EndpointPtr& endpt, const string& connector) +{ + if(_connects.isEnabled()) + { + try + { + ObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getConnectionEstablishmentObserver(endpt, connector); + } + return _connects.getObserverWithDelegate(EndpointHelper(endpt, connector), delegate); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +ObserverPtr +CommunicatorObserverI::getEndpointLookupObserver(const EndpointPtr& endpt) +{ + if(_endpointLookups.isEnabled()) + { + try + { + ObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getEndpointLookupObserver(endpt); + } + return _endpointLookups.getObserverWithDelegate(EndpointHelper(endpt), delegate); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +ConnectionObserverPtr +CommunicatorObserverI::getConnectionObserver(const ConnectionInfoPtr& con, + const EndpointPtr& endpt, + ConnectionState state, + const ConnectionObserverPtr& observer) +{ + if(_connections.isEnabled()) + { + try + { + ConnectionObserverPtr delegate; + ConnectionObserverI* o = dynamic_cast(observer.get()); + if(_delegate) + { + delegate = _delegate->getConnectionObserver(con, endpt, state, o ? o->getDelegate() : observer); + } + return _connections.getObserverWithDelegate(ConnectionHelper(con, endpt, state), delegate, observer); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +ThreadObserverPtr +CommunicatorObserverI::getThreadObserver(const string& parent, + const string& id, + ThreadState state, + const ThreadObserverPtr& observer) +{ + if(_threads.isEnabled()) + { + try + { + ThreadObserverPtr delegate; + ThreadObserverI* o = dynamic_cast(observer.get()); + if(_delegate) + { + delegate = _delegate->getThreadObserver(parent, id, state, o ? o->getDelegate() : observer); + } + return _threads.getObserverWithDelegate(ThreadHelper(parent, id, state), delegate, observer); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +InvocationObserverPtr +CommunicatorObserverI::getInvocationObserver(const ObjectPrxPtr& proxy, const string& op, const Context& ctx) +{ + if(_invocations.isEnabled()) + { + try + { + InvocationObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getInvocationObserver(proxy, op, ctx); + } + return _invocations.getObserverWithDelegate(InvocationHelper(proxy, op, ctx), delegate); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +DispatchObserverPtr +CommunicatorObserverI::getDispatchObserver(const Current& current, int size) +{ + if(_dispatch.isEnabled()) + { + try + { + DispatchObserverPtr delegate; + if(_delegate) + { + delegate = _delegate->getDispatchObserver(current, size); + } + return _dispatch.getObserverWithDelegate(DispatchHelper(current, size), delegate); + } + catch(const exception& ex) + { + Error error(_metrics->getLogger()); + error << "unexpected exception trying to obtain observer:\n" << ex; + } + } + return ICE_NULLPTR; +} + +const IceInternal::MetricsAdminIPtr& +CommunicatorObserverI::getFacet() const +{ + assert(_metrics); + return _metrics; +} + +void +CommunicatorObserverI::destroy() +{ + _connections.destroy(); + _dispatch.destroy(); + _invocations.destroy(); + _threads.destroy(); + _connects.destroy(); + _endpointLookups.destroy(); + + _metrics->destroy(); +} diff --git a/Sources/IceCpp/LocalException.cpp b/Sources/IceCpp/LocalException.cpp new file mode 100644 index 0000000..4a69b96 --- /dev/null +++ b/Sources/IceCpp/LocalException.cpp @@ -0,0 +1,3262 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocalException.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +Ice::InitializationException::~InitializationException() +{ +} + +const ::std::string& +Ice::InitializationException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::InitializationException"; + return typeId; +} + +Ice::PluginInitializationException::~PluginInitializationException() +{ +} + +const ::std::string& +Ice::PluginInitializationException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::PluginInitializationException"; + return typeId; +} + +Ice::CollocationOptimizationException::~CollocationOptimizationException() +{ +} + +const ::std::string& +Ice::CollocationOptimizationException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CollocationOptimizationException"; + return typeId; +} + +Ice::AlreadyRegisteredException::~AlreadyRegisteredException() +{ +} + +const ::std::string& +Ice::AlreadyRegisteredException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::AlreadyRegisteredException"; + return typeId; +} + +Ice::NotRegisteredException::~NotRegisteredException() +{ +} + +const ::std::string& +Ice::NotRegisteredException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::NotRegisteredException"; + return typeId; +} + +Ice::TwowayOnlyException::~TwowayOnlyException() +{ +} + +const ::std::string& +Ice::TwowayOnlyException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::TwowayOnlyException"; + return typeId; +} + +Ice::CloneNotImplementedException::~CloneNotImplementedException() +{ +} + +const ::std::string& +Ice::CloneNotImplementedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CloneNotImplementedException"; + return typeId; +} + +Ice::UnknownException::~UnknownException() +{ +} + +const ::std::string& +Ice::UnknownException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownException"; + return typeId; +} + +Ice::UnknownLocalException::~UnknownLocalException() +{ +} + +const ::std::string& +Ice::UnknownLocalException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownLocalException"; + return typeId; +} + +Ice::UnknownUserException::~UnknownUserException() +{ +} + +const ::std::string& +Ice::UnknownUserException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownUserException"; + return typeId; +} + +Ice::VersionMismatchException::~VersionMismatchException() +{ +} + +const ::std::string& +Ice::VersionMismatchException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::VersionMismatchException"; + return typeId; +} + +Ice::CommunicatorDestroyedException::~CommunicatorDestroyedException() +{ +} + +const ::std::string& +Ice::CommunicatorDestroyedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CommunicatorDestroyedException"; + return typeId; +} + +Ice::ObjectAdapterDeactivatedException::~ObjectAdapterDeactivatedException() +{ +} + +const ::std::string& +Ice::ObjectAdapterDeactivatedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ObjectAdapterDeactivatedException"; + return typeId; +} + +Ice::ObjectAdapterIdInUseException::~ObjectAdapterIdInUseException() +{ +} + +const ::std::string& +Ice::ObjectAdapterIdInUseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ObjectAdapterIdInUseException"; + return typeId; +} + +Ice::NoEndpointException::~NoEndpointException() +{ +} + +const ::std::string& +Ice::NoEndpointException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::NoEndpointException"; + return typeId; +} + +Ice::EndpointParseException::~EndpointParseException() +{ +} + +const ::std::string& +Ice::EndpointParseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::EndpointParseException"; + return typeId; +} + +Ice::EndpointSelectionTypeParseException::~EndpointSelectionTypeParseException() +{ +} + +const ::std::string& +Ice::EndpointSelectionTypeParseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::EndpointSelectionTypeParseException"; + return typeId; +} + +Ice::VersionParseException::~VersionParseException() +{ +} + +const ::std::string& +Ice::VersionParseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::VersionParseException"; + return typeId; +} + +Ice::IdentityParseException::~IdentityParseException() +{ +} + +const ::std::string& +Ice::IdentityParseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::IdentityParseException"; + return typeId; +} + +Ice::ProxyParseException::~ProxyParseException() +{ +} + +const ::std::string& +Ice::ProxyParseException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ProxyParseException"; + return typeId; +} + +Ice::IllegalIdentityException::~IllegalIdentityException() +{ +} + +const ::std::string& +Ice::IllegalIdentityException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::IllegalIdentityException"; + return typeId; +} + +Ice::IllegalServantException::~IllegalServantException() +{ +} + +const ::std::string& +Ice::IllegalServantException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::IllegalServantException"; + return typeId; +} + +Ice::RequestFailedException::~RequestFailedException() +{ +} + +const ::std::string& +Ice::RequestFailedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::RequestFailedException"; + return typeId; +} + +Ice::ObjectNotExistException::~ObjectNotExistException() +{ +} + +const ::std::string& +Ice::ObjectNotExistException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ObjectNotExistException"; + return typeId; +} + +Ice::FacetNotExistException::~FacetNotExistException() +{ +} + +const ::std::string& +Ice::FacetNotExistException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::FacetNotExistException"; + return typeId; +} + +Ice::OperationNotExistException::~OperationNotExistException() +{ +} + +const ::std::string& +Ice::OperationNotExistException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::OperationNotExistException"; + return typeId; +} + +Ice::SyscallException::~SyscallException() +{ +} + +const ::std::string& +Ice::SyscallException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::SyscallException"; + return typeId; +} + +Ice::SocketException::~SocketException() +{ +} + +const ::std::string& +Ice::SocketException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::SocketException"; + return typeId; +} + +Ice::CFNetworkException::~CFNetworkException() +{ +} + +const ::std::string& +Ice::CFNetworkException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CFNetworkException"; + return typeId; +} + +Ice::FileException::~FileException() +{ +} + +const ::std::string& +Ice::FileException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::FileException"; + return typeId; +} + +Ice::ConnectFailedException::~ConnectFailedException() +{ +} + +const ::std::string& +Ice::ConnectFailedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectFailedException"; + return typeId; +} + +Ice::ConnectionRefusedException::~ConnectionRefusedException() +{ +} + +const ::std::string& +Ice::ConnectionRefusedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectionRefusedException"; + return typeId; +} + +Ice::ConnectionLostException::~ConnectionLostException() +{ +} + +const ::std::string& +Ice::ConnectionLostException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectionLostException"; + return typeId; +} + +Ice::DNSException::~DNSException() +{ +} + +const ::std::string& +Ice::DNSException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::DNSException"; + return typeId; +} + +Ice::OperationInterruptedException::~OperationInterruptedException() +{ +} + +const ::std::string& +Ice::OperationInterruptedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::OperationInterruptedException"; + return typeId; +} + +Ice::TimeoutException::~TimeoutException() +{ +} + +const ::std::string& +Ice::TimeoutException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::TimeoutException"; + return typeId; +} + +Ice::ConnectTimeoutException::~ConnectTimeoutException() +{ +} + +const ::std::string& +Ice::ConnectTimeoutException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectTimeoutException"; + return typeId; +} + +Ice::CloseTimeoutException::~CloseTimeoutException() +{ +} + +const ::std::string& +Ice::CloseTimeoutException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CloseTimeoutException"; + return typeId; +} + +Ice::ConnectionTimeoutException::~ConnectionTimeoutException() +{ +} + +const ::std::string& +Ice::ConnectionTimeoutException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectionTimeoutException"; + return typeId; +} + +Ice::InvocationTimeoutException::~InvocationTimeoutException() +{ +} + +const ::std::string& +Ice::InvocationTimeoutException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::InvocationTimeoutException"; + return typeId; +} + +Ice::InvocationCanceledException::~InvocationCanceledException() +{ +} + +const ::std::string& +Ice::InvocationCanceledException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::InvocationCanceledException"; + return typeId; +} + +Ice::ProtocolException::~ProtocolException() +{ +} + +const ::std::string& +Ice::ProtocolException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ProtocolException"; + return typeId; +} + +Ice::BadMagicException::~BadMagicException() +{ +} + +const ::std::string& +Ice::BadMagicException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::BadMagicException"; + return typeId; +} + +Ice::UnsupportedProtocolException::~UnsupportedProtocolException() +{ +} + +const ::std::string& +Ice::UnsupportedProtocolException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnsupportedProtocolException"; + return typeId; +} + +Ice::UnsupportedEncodingException::~UnsupportedEncodingException() +{ +} + +const ::std::string& +Ice::UnsupportedEncodingException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnsupportedEncodingException"; + return typeId; +} + +Ice::UnknownMessageException::~UnknownMessageException() +{ +} + +const ::std::string& +Ice::UnknownMessageException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownMessageException"; + return typeId; +} + +Ice::ConnectionNotValidatedException::~ConnectionNotValidatedException() +{ +} + +const ::std::string& +Ice::ConnectionNotValidatedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectionNotValidatedException"; + return typeId; +} + +Ice::UnknownRequestIdException::~UnknownRequestIdException() +{ +} + +const ::std::string& +Ice::UnknownRequestIdException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownRequestIdException"; + return typeId; +} + +Ice::UnknownReplyStatusException::~UnknownReplyStatusException() +{ +} + +const ::std::string& +Ice::UnknownReplyStatusException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnknownReplyStatusException"; + return typeId; +} + +Ice::CloseConnectionException::~CloseConnectionException() +{ +} + +const ::std::string& +Ice::CloseConnectionException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CloseConnectionException"; + return typeId; +} + +Ice::ConnectionManuallyClosedException::~ConnectionManuallyClosedException() +{ +} + +const ::std::string& +Ice::ConnectionManuallyClosedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ConnectionManuallyClosedException"; + return typeId; +} + +Ice::IllegalMessageSizeException::~IllegalMessageSizeException() +{ +} + +const ::std::string& +Ice::IllegalMessageSizeException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::IllegalMessageSizeException"; + return typeId; +} + +Ice::CompressionException::~CompressionException() +{ +} + +const ::std::string& +Ice::CompressionException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::CompressionException"; + return typeId; +} + +Ice::DatagramLimitException::~DatagramLimitException() +{ +} + +const ::std::string& +Ice::DatagramLimitException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::DatagramLimitException"; + return typeId; +} + +Ice::MarshalException::~MarshalException() +{ +} + +const ::std::string& +Ice::MarshalException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::MarshalException"; + return typeId; +} + +Ice::ProxyUnmarshalException::~ProxyUnmarshalException() +{ +} + +const ::std::string& +Ice::ProxyUnmarshalException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ProxyUnmarshalException"; + return typeId; +} + +Ice::UnmarshalOutOfBoundsException::~UnmarshalOutOfBoundsException() +{ +} + +const ::std::string& +Ice::UnmarshalOutOfBoundsException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnmarshalOutOfBoundsException"; + return typeId; +} + +Ice::NoValueFactoryException::~NoValueFactoryException() +{ +} + +const ::std::string& +Ice::NoValueFactoryException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::NoValueFactoryException"; + return typeId; +} + +Ice::UnexpectedObjectException::~UnexpectedObjectException() +{ +} + +const ::std::string& +Ice::UnexpectedObjectException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::UnexpectedObjectException"; + return typeId; +} + +Ice::MemoryLimitException::~MemoryLimitException() +{ +} + +const ::std::string& +Ice::MemoryLimitException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::MemoryLimitException"; + return typeId; +} + +Ice::StringConversionException::~StringConversionException() +{ +} + +const ::std::string& +Ice::StringConversionException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::StringConversionException"; + return typeId; +} + +Ice::EncapsulationException::~EncapsulationException() +{ +} + +const ::std::string& +Ice::EncapsulationException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::EncapsulationException"; + return typeId; +} + +Ice::FeatureNotSupportedException::~FeatureNotSupportedException() +{ +} + +const ::std::string& +Ice::FeatureNotSupportedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::FeatureNotSupportedException"; + return typeId; +} + +Ice::SecurityException::~SecurityException() +{ +} + +const ::std::string& +Ice::SecurityException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::SecurityException"; + return typeId; +} + +Ice::FixedProxyException::~FixedProxyException() +{ +} + +const ::std::string& +Ice::FixedProxyException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::FixedProxyException"; + return typeId; +} + +Ice::ResponseSentException::~ResponseSentException() +{ +} + +const ::std::string& +Ice::ResponseSentException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ResponseSentException"; + return typeId; +} + +#else // C++98 mapping + +Ice::InitializationException::InitializationException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::InitializationException::InitializationException(const char* file, int line, const ::std::string& reason) : + LocalException(file, line), + reason(reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::InitializationException::~InitializationException() +{ +} +#else +Ice::InitializationException::~InitializationException() throw() +{ +} +#endif + +::std::string +Ice::InitializationException::ice_id() const +{ + return "::Ice::InitializationException"; +} + +Ice::InitializationException* +Ice::InitializationException::ice_clone() const +{ + return new InitializationException(*this); +} + +void +Ice::InitializationException::ice_throw() const +{ + throw *this; +} + +Ice::PluginInitializationException::PluginInitializationException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::PluginInitializationException::PluginInitializationException(const char* file, int line, const ::std::string& reason) : + LocalException(file, line), + reason(reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::PluginInitializationException::~PluginInitializationException() +{ +} +#else +Ice::PluginInitializationException::~PluginInitializationException() throw() +{ +} +#endif + +::std::string +Ice::PluginInitializationException::ice_id() const +{ + return "::Ice::PluginInitializationException"; +} + +Ice::PluginInitializationException* +Ice::PluginInitializationException::ice_clone() const +{ + return new PluginInitializationException(*this); +} + +void +Ice::PluginInitializationException::ice_throw() const +{ + throw *this; +} + +Ice::CollocationOptimizationException::CollocationOptimizationException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CollocationOptimizationException::~CollocationOptimizationException() +{ +} +#else +Ice::CollocationOptimizationException::~CollocationOptimizationException() throw() +{ +} +#endif + +::std::string +Ice::CollocationOptimizationException::ice_id() const +{ + return "::Ice::CollocationOptimizationException"; +} + +Ice::CollocationOptimizationException* +Ice::CollocationOptimizationException::ice_clone() const +{ + return new CollocationOptimizationException(*this); +} + +void +Ice::CollocationOptimizationException::ice_throw() const +{ + throw *this; +} + +Ice::AlreadyRegisteredException::AlreadyRegisteredException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::AlreadyRegisteredException::AlreadyRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id) : + LocalException(file, line), + kindOfObject(kindOfObject), + id(id) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::AlreadyRegisteredException::~AlreadyRegisteredException() +{ +} +#else +Ice::AlreadyRegisteredException::~AlreadyRegisteredException() throw() +{ +} +#endif + +::std::string +Ice::AlreadyRegisteredException::ice_id() const +{ + return "::Ice::AlreadyRegisteredException"; +} + +Ice::AlreadyRegisteredException* +Ice::AlreadyRegisteredException::ice_clone() const +{ + return new AlreadyRegisteredException(*this); +} + +void +Ice::AlreadyRegisteredException::ice_throw() const +{ + throw *this; +} + +Ice::NotRegisteredException::NotRegisteredException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::NotRegisteredException::NotRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id) : + LocalException(file, line), + kindOfObject(kindOfObject), + id(id) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::NotRegisteredException::~NotRegisteredException() +{ +} +#else +Ice::NotRegisteredException::~NotRegisteredException() throw() +{ +} +#endif + +::std::string +Ice::NotRegisteredException::ice_id() const +{ + return "::Ice::NotRegisteredException"; +} + +Ice::NotRegisteredException* +Ice::NotRegisteredException::ice_clone() const +{ + return new NotRegisteredException(*this); +} + +void +Ice::NotRegisteredException::ice_throw() const +{ + throw *this; +} + +Ice::TwowayOnlyException::TwowayOnlyException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::TwowayOnlyException::TwowayOnlyException(const char* file, int line, const ::std::string& operation) : + LocalException(file, line), + operation(operation) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::TwowayOnlyException::~TwowayOnlyException() +{ +} +#else +Ice::TwowayOnlyException::~TwowayOnlyException() throw() +{ +} +#endif + +::std::string +Ice::TwowayOnlyException::ice_id() const +{ + return "::Ice::TwowayOnlyException"; +} + +Ice::TwowayOnlyException* +Ice::TwowayOnlyException::ice_clone() const +{ + return new TwowayOnlyException(*this); +} + +void +Ice::TwowayOnlyException::ice_throw() const +{ + throw *this; +} + +Ice::CloneNotImplementedException::CloneNotImplementedException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CloneNotImplementedException::~CloneNotImplementedException() +{ +} +#else +Ice::CloneNotImplementedException::~CloneNotImplementedException() throw() +{ +} +#endif + +::std::string +Ice::CloneNotImplementedException::ice_id() const +{ + return "::Ice::CloneNotImplementedException"; +} + +Ice::CloneNotImplementedException* +Ice::CloneNotImplementedException::ice_clone() const +{ + return new CloneNotImplementedException(*this); +} + +void +Ice::CloneNotImplementedException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownException::UnknownException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::UnknownException::UnknownException(const char* file, int line, const ::std::string& unknown) : + LocalException(file, line), + unknown(unknown) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownException::~UnknownException() +{ +} +#else +Ice::UnknownException::~UnknownException() throw() +{ +} +#endif + +::std::string +Ice::UnknownException::ice_id() const +{ + return "::Ice::UnknownException"; +} + +Ice::UnknownException* +Ice::UnknownException::ice_clone() const +{ + return new UnknownException(*this); +} + +void +Ice::UnknownException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownLocalException::UnknownLocalException(const char* file, int line) : + UnknownException(file, line) +{ +} + +Ice::UnknownLocalException::UnknownLocalException(const char* file, int line, const ::std::string& unknown) : + UnknownException(file, line, unknown) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownLocalException::~UnknownLocalException() +{ +} +#else +Ice::UnknownLocalException::~UnknownLocalException() throw() +{ +} +#endif + +::std::string +Ice::UnknownLocalException::ice_id() const +{ + return "::Ice::UnknownLocalException"; +} + +Ice::UnknownLocalException* +Ice::UnknownLocalException::ice_clone() const +{ + return new UnknownLocalException(*this); +} + +void +Ice::UnknownLocalException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownUserException::UnknownUserException(const char* file, int line) : + UnknownException(file, line) +{ +} + +Ice::UnknownUserException::UnknownUserException(const char* file, int line, const ::std::string& unknown) : + UnknownException(file, line, unknown) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownUserException::~UnknownUserException() +{ +} +#else +Ice::UnknownUserException::~UnknownUserException() throw() +{ +} +#endif + +::std::string +Ice::UnknownUserException::ice_id() const +{ + return "::Ice::UnknownUserException"; +} + +Ice::UnknownUserException* +Ice::UnknownUserException::ice_clone() const +{ + return new UnknownUserException(*this); +} + +void +Ice::UnknownUserException::ice_throw() const +{ + throw *this; +} + +Ice::VersionMismatchException::VersionMismatchException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::VersionMismatchException::~VersionMismatchException() +{ +} +#else +Ice::VersionMismatchException::~VersionMismatchException() throw() +{ +} +#endif + +::std::string +Ice::VersionMismatchException::ice_id() const +{ + return "::Ice::VersionMismatchException"; +} + +Ice::VersionMismatchException* +Ice::VersionMismatchException::ice_clone() const +{ + return new VersionMismatchException(*this); +} + +void +Ice::VersionMismatchException::ice_throw() const +{ + throw *this; +} + +Ice::CommunicatorDestroyedException::CommunicatorDestroyedException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CommunicatorDestroyedException::~CommunicatorDestroyedException() +{ +} +#else +Ice::CommunicatorDestroyedException::~CommunicatorDestroyedException() throw() +{ +} +#endif + +::std::string +Ice::CommunicatorDestroyedException::ice_id() const +{ + return "::Ice::CommunicatorDestroyedException"; +} + +Ice::CommunicatorDestroyedException* +Ice::CommunicatorDestroyedException::ice_clone() const +{ + return new CommunicatorDestroyedException(*this); +} + +void +Ice::CommunicatorDestroyedException::ice_throw() const +{ + throw *this; +} + +Ice::ObjectAdapterDeactivatedException::ObjectAdapterDeactivatedException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::ObjectAdapterDeactivatedException::ObjectAdapterDeactivatedException(const char* file, int line, const ::std::string& name) : + LocalException(file, line), + name(name) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ObjectAdapterDeactivatedException::~ObjectAdapterDeactivatedException() +{ +} +#else +Ice::ObjectAdapterDeactivatedException::~ObjectAdapterDeactivatedException() throw() +{ +} +#endif + +::std::string +Ice::ObjectAdapterDeactivatedException::ice_id() const +{ + return "::Ice::ObjectAdapterDeactivatedException"; +} + +Ice::ObjectAdapterDeactivatedException* +Ice::ObjectAdapterDeactivatedException::ice_clone() const +{ + return new ObjectAdapterDeactivatedException(*this); +} + +void +Ice::ObjectAdapterDeactivatedException::ice_throw() const +{ + throw *this; +} + +Ice::ObjectAdapterIdInUseException::ObjectAdapterIdInUseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::ObjectAdapterIdInUseException::ObjectAdapterIdInUseException(const char* file, int line, const ::std::string& id) : + LocalException(file, line), + id(id) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ObjectAdapterIdInUseException::~ObjectAdapterIdInUseException() +{ +} +#else +Ice::ObjectAdapterIdInUseException::~ObjectAdapterIdInUseException() throw() +{ +} +#endif + +::std::string +Ice::ObjectAdapterIdInUseException::ice_id() const +{ + return "::Ice::ObjectAdapterIdInUseException"; +} + +Ice::ObjectAdapterIdInUseException* +Ice::ObjectAdapterIdInUseException::ice_clone() const +{ + return new ObjectAdapterIdInUseException(*this); +} + +void +Ice::ObjectAdapterIdInUseException::ice_throw() const +{ + throw *this; +} + +Ice::NoEndpointException::NoEndpointException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::NoEndpointException::NoEndpointException(const char* file, int line, const ::std::string& proxy) : + LocalException(file, line), + proxy(proxy) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::NoEndpointException::~NoEndpointException() +{ +} +#else +Ice::NoEndpointException::~NoEndpointException() throw() +{ +} +#endif + +::std::string +Ice::NoEndpointException::ice_id() const +{ + return "::Ice::NoEndpointException"; +} + +Ice::NoEndpointException* +Ice::NoEndpointException::ice_clone() const +{ + return new NoEndpointException(*this); +} + +void +Ice::NoEndpointException::ice_throw() const +{ + throw *this; +} + +Ice::EndpointParseException::EndpointParseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::EndpointParseException::EndpointParseException(const char* file, int line, const ::std::string& str) : + LocalException(file, line), + str(str) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::EndpointParseException::~EndpointParseException() +{ +} +#else +Ice::EndpointParseException::~EndpointParseException() throw() +{ +} +#endif + +::std::string +Ice::EndpointParseException::ice_id() const +{ + return "::Ice::EndpointParseException"; +} + +Ice::EndpointParseException* +Ice::EndpointParseException::ice_clone() const +{ + return new EndpointParseException(*this); +} + +void +Ice::EndpointParseException::ice_throw() const +{ + throw *this; +} + +Ice::EndpointSelectionTypeParseException::EndpointSelectionTypeParseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::EndpointSelectionTypeParseException::EndpointSelectionTypeParseException(const char* file, int line, const ::std::string& str) : + LocalException(file, line), + str(str) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::EndpointSelectionTypeParseException::~EndpointSelectionTypeParseException() +{ +} +#else +Ice::EndpointSelectionTypeParseException::~EndpointSelectionTypeParseException() throw() +{ +} +#endif + +::std::string +Ice::EndpointSelectionTypeParseException::ice_id() const +{ + return "::Ice::EndpointSelectionTypeParseException"; +} + +Ice::EndpointSelectionTypeParseException* +Ice::EndpointSelectionTypeParseException::ice_clone() const +{ + return new EndpointSelectionTypeParseException(*this); +} + +void +Ice::EndpointSelectionTypeParseException::ice_throw() const +{ + throw *this; +} + +Ice::VersionParseException::VersionParseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::VersionParseException::VersionParseException(const char* file, int line, const ::std::string& str) : + LocalException(file, line), + str(str) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::VersionParseException::~VersionParseException() +{ +} +#else +Ice::VersionParseException::~VersionParseException() throw() +{ +} +#endif + +::std::string +Ice::VersionParseException::ice_id() const +{ + return "::Ice::VersionParseException"; +} + +Ice::VersionParseException* +Ice::VersionParseException::ice_clone() const +{ + return new VersionParseException(*this); +} + +void +Ice::VersionParseException::ice_throw() const +{ + throw *this; +} + +Ice::IdentityParseException::IdentityParseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::IdentityParseException::IdentityParseException(const char* file, int line, const ::std::string& str) : + LocalException(file, line), + str(str) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::IdentityParseException::~IdentityParseException() +{ +} +#else +Ice::IdentityParseException::~IdentityParseException() throw() +{ +} +#endif + +::std::string +Ice::IdentityParseException::ice_id() const +{ + return "::Ice::IdentityParseException"; +} + +Ice::IdentityParseException* +Ice::IdentityParseException::ice_clone() const +{ + return new IdentityParseException(*this); +} + +void +Ice::IdentityParseException::ice_throw() const +{ + throw *this; +} + +Ice::ProxyParseException::ProxyParseException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::ProxyParseException::ProxyParseException(const char* file, int line, const ::std::string& str) : + LocalException(file, line), + str(str) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ProxyParseException::~ProxyParseException() +{ +} +#else +Ice::ProxyParseException::~ProxyParseException() throw() +{ +} +#endif + +::std::string +Ice::ProxyParseException::ice_id() const +{ + return "::Ice::ProxyParseException"; +} + +Ice::ProxyParseException* +Ice::ProxyParseException::ice_clone() const +{ + return new ProxyParseException(*this); +} + +void +Ice::ProxyParseException::ice_throw() const +{ + throw *this; +} + +Ice::IllegalIdentityException::IllegalIdentityException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::IllegalIdentityException::IllegalIdentityException(const char* file, int line, const Identity& id) : + LocalException(file, line), + id(id) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::IllegalIdentityException::~IllegalIdentityException() +{ +} +#else +Ice::IllegalIdentityException::~IllegalIdentityException() throw() +{ +} +#endif + +::std::string +Ice::IllegalIdentityException::ice_id() const +{ + return "::Ice::IllegalIdentityException"; +} + +Ice::IllegalIdentityException* +Ice::IllegalIdentityException::ice_clone() const +{ + return new IllegalIdentityException(*this); +} + +void +Ice::IllegalIdentityException::ice_throw() const +{ + throw *this; +} + +Ice::IllegalServantException::IllegalServantException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::IllegalServantException::IllegalServantException(const char* file, int line, const ::std::string& reason) : + LocalException(file, line), + reason(reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::IllegalServantException::~IllegalServantException() +{ +} +#else +Ice::IllegalServantException::~IllegalServantException() throw() +{ +} +#endif + +::std::string +Ice::IllegalServantException::ice_id() const +{ + return "::Ice::IllegalServantException"; +} + +Ice::IllegalServantException* +Ice::IllegalServantException::ice_clone() const +{ + return new IllegalServantException(*this); +} + +void +Ice::IllegalServantException::ice_throw() const +{ + throw *this; +} + +Ice::RequestFailedException::RequestFailedException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::RequestFailedException::RequestFailedException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + LocalException(file, line), + id(id), + facet(facet), + operation(operation) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::RequestFailedException::~RequestFailedException() +{ +} +#else +Ice::RequestFailedException::~RequestFailedException() throw() +{ +} +#endif + +::std::string +Ice::RequestFailedException::ice_id() const +{ + return "::Ice::RequestFailedException"; +} + +Ice::RequestFailedException* +Ice::RequestFailedException::ice_clone() const +{ + return new RequestFailedException(*this); +} + +void +Ice::RequestFailedException::ice_throw() const +{ + throw *this; +} + +Ice::ObjectNotExistException::ObjectNotExistException(const char* file, int line) : + RequestFailedException(file, line) +{ +} + +Ice::ObjectNotExistException::ObjectNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + RequestFailedException(file, line, id, facet, operation) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ObjectNotExistException::~ObjectNotExistException() +{ +} +#else +Ice::ObjectNotExistException::~ObjectNotExistException() throw() +{ +} +#endif + +::std::string +Ice::ObjectNotExistException::ice_id() const +{ + return "::Ice::ObjectNotExistException"; +} + +Ice::ObjectNotExistException* +Ice::ObjectNotExistException::ice_clone() const +{ + return new ObjectNotExistException(*this); +} + +void +Ice::ObjectNotExistException::ice_throw() const +{ + throw *this; +} + +Ice::FacetNotExistException::FacetNotExistException(const char* file, int line) : + RequestFailedException(file, line) +{ +} + +Ice::FacetNotExistException::FacetNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + RequestFailedException(file, line, id, facet, operation) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::FacetNotExistException::~FacetNotExistException() +{ +} +#else +Ice::FacetNotExistException::~FacetNotExistException() throw() +{ +} +#endif + +::std::string +Ice::FacetNotExistException::ice_id() const +{ + return "::Ice::FacetNotExistException"; +} + +Ice::FacetNotExistException* +Ice::FacetNotExistException::ice_clone() const +{ + return new FacetNotExistException(*this); +} + +void +Ice::FacetNotExistException::ice_throw() const +{ + throw *this; +} + +Ice::OperationNotExistException::OperationNotExistException(const char* file, int line) : + RequestFailedException(file, line) +{ +} + +Ice::OperationNotExistException::OperationNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + RequestFailedException(file, line, id, facet, operation) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::OperationNotExistException::~OperationNotExistException() +{ +} +#else +Ice::OperationNotExistException::~OperationNotExistException() throw() +{ +} +#endif + +::std::string +Ice::OperationNotExistException::ice_id() const +{ + return "::Ice::OperationNotExistException"; +} + +Ice::OperationNotExistException* +Ice::OperationNotExistException::ice_clone() const +{ + return new OperationNotExistException(*this); +} + +void +Ice::OperationNotExistException::ice_throw() const +{ + throw *this; +} + +Ice::SyscallException::SyscallException(const char* file, int line) : + LocalException(file, line), + error(0) +{ +} + +Ice::SyscallException::SyscallException(const char* file, int line, Int error) : + LocalException(file, line), + error(error) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::SyscallException::~SyscallException() +{ +} +#else +Ice::SyscallException::~SyscallException() throw() +{ +} +#endif + +::std::string +Ice::SyscallException::ice_id() const +{ + return "::Ice::SyscallException"; +} + +Ice::SyscallException* +Ice::SyscallException::ice_clone() const +{ + return new SyscallException(*this); +} + +void +Ice::SyscallException::ice_throw() const +{ + throw *this; +} + +Ice::SocketException::SocketException(const char* file, int line) : + SyscallException(file, line) +{ +} + +Ice::SocketException::SocketException(const char* file, int line, Int error) : + SyscallException(file, line, error) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::SocketException::~SocketException() +{ +} +#else +Ice::SocketException::~SocketException() throw() +{ +} +#endif + +::std::string +Ice::SocketException::ice_id() const +{ + return "::Ice::SocketException"; +} + +Ice::SocketException* +Ice::SocketException::ice_clone() const +{ + return new SocketException(*this); +} + +void +Ice::SocketException::ice_throw() const +{ + throw *this; +} + +Ice::CFNetworkException::CFNetworkException(const char* file, int line) : + SocketException(file, line) +{ +} + +Ice::CFNetworkException::CFNetworkException(const char* file, int line, Int error, const ::std::string& domain) : + SocketException(file, line, error), + domain(domain) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CFNetworkException::~CFNetworkException() +{ +} +#else +Ice::CFNetworkException::~CFNetworkException() throw() +{ +} +#endif + +::std::string +Ice::CFNetworkException::ice_id() const +{ + return "::Ice::CFNetworkException"; +} + +Ice::CFNetworkException* +Ice::CFNetworkException::ice_clone() const +{ + return new CFNetworkException(*this); +} + +void +Ice::CFNetworkException::ice_throw() const +{ + throw *this; +} + +Ice::FileException::FileException(const char* file, int line) : + SyscallException(file, line) +{ +} + +Ice::FileException::FileException(const char* file, int line, Int error, const ::std::string& path) : + SyscallException(file, line, error), + path(path) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::FileException::~FileException() +{ +} +#else +Ice::FileException::~FileException() throw() +{ +} +#endif + +::std::string +Ice::FileException::ice_id() const +{ + return "::Ice::FileException"; +} + +Ice::FileException* +Ice::FileException::ice_clone() const +{ + return new FileException(*this); +} + +void +Ice::FileException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectFailedException::ConnectFailedException(const char* file, int line) : + SocketException(file, line) +{ +} + +Ice::ConnectFailedException::ConnectFailedException(const char* file, int line, Int error) : + SocketException(file, line, error) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectFailedException::~ConnectFailedException() +{ +} +#else +Ice::ConnectFailedException::~ConnectFailedException() throw() +{ +} +#endif + +::std::string +Ice::ConnectFailedException::ice_id() const +{ + return "::Ice::ConnectFailedException"; +} + +Ice::ConnectFailedException* +Ice::ConnectFailedException::ice_clone() const +{ + return new ConnectFailedException(*this); +} + +void +Ice::ConnectFailedException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectionRefusedException::ConnectionRefusedException(const char* file, int line) : + ConnectFailedException(file, line) +{ +} + +Ice::ConnectionRefusedException::ConnectionRefusedException(const char* file, int line, Int error) : + ConnectFailedException(file, line, error) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectionRefusedException::~ConnectionRefusedException() +{ +} +#else +Ice::ConnectionRefusedException::~ConnectionRefusedException() throw() +{ +} +#endif + +::std::string +Ice::ConnectionRefusedException::ice_id() const +{ + return "::Ice::ConnectionRefusedException"; +} + +Ice::ConnectionRefusedException* +Ice::ConnectionRefusedException::ice_clone() const +{ + return new ConnectionRefusedException(*this); +} + +void +Ice::ConnectionRefusedException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectionLostException::ConnectionLostException(const char* file, int line) : + SocketException(file, line) +{ +} + +Ice::ConnectionLostException::ConnectionLostException(const char* file, int line, Int error) : + SocketException(file, line, error) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectionLostException::~ConnectionLostException() +{ +} +#else +Ice::ConnectionLostException::~ConnectionLostException() throw() +{ +} +#endif + +::std::string +Ice::ConnectionLostException::ice_id() const +{ + return "::Ice::ConnectionLostException"; +} + +Ice::ConnectionLostException* +Ice::ConnectionLostException::ice_clone() const +{ + return new ConnectionLostException(*this); +} + +void +Ice::ConnectionLostException::ice_throw() const +{ + throw *this; +} + +Ice::DNSException::DNSException(const char* file, int line) : + LocalException(file, line), + error(0) +{ +} + +Ice::DNSException::DNSException(const char* file, int line, Int error, const ::std::string& host) : + LocalException(file, line), + error(error), + host(host) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::DNSException::~DNSException() +{ +} +#else +Ice::DNSException::~DNSException() throw() +{ +} +#endif + +::std::string +Ice::DNSException::ice_id() const +{ + return "::Ice::DNSException"; +} + +Ice::DNSException* +Ice::DNSException::ice_clone() const +{ + return new DNSException(*this); +} + +void +Ice::DNSException::ice_throw() const +{ + throw *this; +} + +Ice::OperationInterruptedException::OperationInterruptedException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::OperationInterruptedException::~OperationInterruptedException() +{ +} +#else +Ice::OperationInterruptedException::~OperationInterruptedException() throw() +{ +} +#endif + +::std::string +Ice::OperationInterruptedException::ice_id() const +{ + return "::Ice::OperationInterruptedException"; +} + +Ice::OperationInterruptedException* +Ice::OperationInterruptedException::ice_clone() const +{ + return new OperationInterruptedException(*this); +} + +void +Ice::OperationInterruptedException::ice_throw() const +{ + throw *this; +} + +Ice::TimeoutException::TimeoutException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::TimeoutException::~TimeoutException() +{ +} +#else +Ice::TimeoutException::~TimeoutException() throw() +{ +} +#endif + +::std::string +Ice::TimeoutException::ice_id() const +{ + return "::Ice::TimeoutException"; +} + +Ice::TimeoutException* +Ice::TimeoutException::ice_clone() const +{ + return new TimeoutException(*this); +} + +void +Ice::TimeoutException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectTimeoutException::ConnectTimeoutException(const char* file, int line) : + TimeoutException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectTimeoutException::~ConnectTimeoutException() +{ +} +#else +Ice::ConnectTimeoutException::~ConnectTimeoutException() throw() +{ +} +#endif + +::std::string +Ice::ConnectTimeoutException::ice_id() const +{ + return "::Ice::ConnectTimeoutException"; +} + +Ice::ConnectTimeoutException* +Ice::ConnectTimeoutException::ice_clone() const +{ + return new ConnectTimeoutException(*this); +} + +void +Ice::ConnectTimeoutException::ice_throw() const +{ + throw *this; +} + +Ice::CloseTimeoutException::CloseTimeoutException(const char* file, int line) : + TimeoutException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CloseTimeoutException::~CloseTimeoutException() +{ +} +#else +Ice::CloseTimeoutException::~CloseTimeoutException() throw() +{ +} +#endif + +::std::string +Ice::CloseTimeoutException::ice_id() const +{ + return "::Ice::CloseTimeoutException"; +} + +Ice::CloseTimeoutException* +Ice::CloseTimeoutException::ice_clone() const +{ + return new CloseTimeoutException(*this); +} + +void +Ice::CloseTimeoutException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectionTimeoutException::ConnectionTimeoutException(const char* file, int line) : + TimeoutException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectionTimeoutException::~ConnectionTimeoutException() +{ +} +#else +Ice::ConnectionTimeoutException::~ConnectionTimeoutException() throw() +{ +} +#endif + +::std::string +Ice::ConnectionTimeoutException::ice_id() const +{ + return "::Ice::ConnectionTimeoutException"; +} + +Ice::ConnectionTimeoutException* +Ice::ConnectionTimeoutException::ice_clone() const +{ + return new ConnectionTimeoutException(*this); +} + +void +Ice::ConnectionTimeoutException::ice_throw() const +{ + throw *this; +} + +Ice::InvocationTimeoutException::InvocationTimeoutException(const char* file, int line) : + TimeoutException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::InvocationTimeoutException::~InvocationTimeoutException() +{ +} +#else +Ice::InvocationTimeoutException::~InvocationTimeoutException() throw() +{ +} +#endif + +::std::string +Ice::InvocationTimeoutException::ice_id() const +{ + return "::Ice::InvocationTimeoutException"; +} + +Ice::InvocationTimeoutException* +Ice::InvocationTimeoutException::ice_clone() const +{ + return new InvocationTimeoutException(*this); +} + +void +Ice::InvocationTimeoutException::ice_throw() const +{ + throw *this; +} + +Ice::InvocationCanceledException::InvocationCanceledException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::InvocationCanceledException::~InvocationCanceledException() +{ +} +#else +Ice::InvocationCanceledException::~InvocationCanceledException() throw() +{ +} +#endif + +::std::string +Ice::InvocationCanceledException::ice_id() const +{ + return "::Ice::InvocationCanceledException"; +} + +Ice::InvocationCanceledException* +Ice::InvocationCanceledException::ice_clone() const +{ + return new InvocationCanceledException(*this); +} + +void +Ice::InvocationCanceledException::ice_throw() const +{ + throw *this; +} + +Ice::ProtocolException::ProtocolException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::ProtocolException::ProtocolException(const char* file, int line, const ::std::string& reason) : + LocalException(file, line), + reason(reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ProtocolException::~ProtocolException() +{ +} +#else +Ice::ProtocolException::~ProtocolException() throw() +{ +} +#endif + +::std::string +Ice::ProtocolException::ice_id() const +{ + return "::Ice::ProtocolException"; +} + +Ice::ProtocolException* +Ice::ProtocolException::ice_clone() const +{ + return new ProtocolException(*this); +} + +void +Ice::ProtocolException::ice_throw() const +{ + throw *this; +} + +Ice::BadMagicException::BadMagicException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::BadMagicException::BadMagicException(const char* file, int line, const ::std::string& reason, const ByteSeq& badMagic) : + ProtocolException(file, line, reason), + badMagic(badMagic) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::BadMagicException::~BadMagicException() +{ +} +#else +Ice::BadMagicException::~BadMagicException() throw() +{ +} +#endif + +::std::string +Ice::BadMagicException::ice_id() const +{ + return "::Ice::BadMagicException"; +} + +Ice::BadMagicException* +Ice::BadMagicException::ice_clone() const +{ + return new BadMagicException(*this); +} + +void +Ice::BadMagicException::ice_throw() const +{ + throw *this; +} + +Ice::UnsupportedProtocolException::UnsupportedProtocolException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::UnsupportedProtocolException::UnsupportedProtocolException(const char* file, int line, const ::std::string& reason, const ProtocolVersion& bad, const ProtocolVersion& supported) : + ProtocolException(file, line, reason), + bad(bad), + supported(supported) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnsupportedProtocolException::~UnsupportedProtocolException() +{ +} +#else +Ice::UnsupportedProtocolException::~UnsupportedProtocolException() throw() +{ +} +#endif + +::std::string +Ice::UnsupportedProtocolException::ice_id() const +{ + return "::Ice::UnsupportedProtocolException"; +} + +Ice::UnsupportedProtocolException* +Ice::UnsupportedProtocolException::ice_clone() const +{ + return new UnsupportedProtocolException(*this); +} + +void +Ice::UnsupportedProtocolException::ice_throw() const +{ + throw *this; +} + +Ice::UnsupportedEncodingException::UnsupportedEncodingException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::UnsupportedEncodingException::UnsupportedEncodingException(const char* file, int line, const ::std::string& reason, const EncodingVersion& bad, const EncodingVersion& supported) : + ProtocolException(file, line, reason), + bad(bad), + supported(supported) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnsupportedEncodingException::~UnsupportedEncodingException() +{ +} +#else +Ice::UnsupportedEncodingException::~UnsupportedEncodingException() throw() +{ +} +#endif + +::std::string +Ice::UnsupportedEncodingException::ice_id() const +{ + return "::Ice::UnsupportedEncodingException"; +} + +Ice::UnsupportedEncodingException* +Ice::UnsupportedEncodingException::ice_clone() const +{ + return new UnsupportedEncodingException(*this); +} + +void +Ice::UnsupportedEncodingException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownMessageException::UnknownMessageException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::UnknownMessageException::UnknownMessageException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownMessageException::~UnknownMessageException() +{ +} +#else +Ice::UnknownMessageException::~UnknownMessageException() throw() +{ +} +#endif + +::std::string +Ice::UnknownMessageException::ice_id() const +{ + return "::Ice::UnknownMessageException"; +} + +Ice::UnknownMessageException* +Ice::UnknownMessageException::ice_clone() const +{ + return new UnknownMessageException(*this); +} + +void +Ice::UnknownMessageException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectionNotValidatedException::ConnectionNotValidatedException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::ConnectionNotValidatedException::ConnectionNotValidatedException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectionNotValidatedException::~ConnectionNotValidatedException() +{ +} +#else +Ice::ConnectionNotValidatedException::~ConnectionNotValidatedException() throw() +{ +} +#endif + +::std::string +Ice::ConnectionNotValidatedException::ice_id() const +{ + return "::Ice::ConnectionNotValidatedException"; +} + +Ice::ConnectionNotValidatedException* +Ice::ConnectionNotValidatedException::ice_clone() const +{ + return new ConnectionNotValidatedException(*this); +} + +void +Ice::ConnectionNotValidatedException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownRequestIdException::UnknownRequestIdException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::UnknownRequestIdException::UnknownRequestIdException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownRequestIdException::~UnknownRequestIdException() +{ +} +#else +Ice::UnknownRequestIdException::~UnknownRequestIdException() throw() +{ +} +#endif + +::std::string +Ice::UnknownRequestIdException::ice_id() const +{ + return "::Ice::UnknownRequestIdException"; +} + +Ice::UnknownRequestIdException* +Ice::UnknownRequestIdException::ice_clone() const +{ + return new UnknownRequestIdException(*this); +} + +void +Ice::UnknownRequestIdException::ice_throw() const +{ + throw *this; +} + +Ice::UnknownReplyStatusException::UnknownReplyStatusException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::UnknownReplyStatusException::UnknownReplyStatusException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnknownReplyStatusException::~UnknownReplyStatusException() +{ +} +#else +Ice::UnknownReplyStatusException::~UnknownReplyStatusException() throw() +{ +} +#endif + +::std::string +Ice::UnknownReplyStatusException::ice_id() const +{ + return "::Ice::UnknownReplyStatusException"; +} + +Ice::UnknownReplyStatusException* +Ice::UnknownReplyStatusException::ice_clone() const +{ + return new UnknownReplyStatusException(*this); +} + +void +Ice::UnknownReplyStatusException::ice_throw() const +{ + throw *this; +} + +Ice::CloseConnectionException::CloseConnectionException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::CloseConnectionException::CloseConnectionException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CloseConnectionException::~CloseConnectionException() +{ +} +#else +Ice::CloseConnectionException::~CloseConnectionException() throw() +{ +} +#endif + +::std::string +Ice::CloseConnectionException::ice_id() const +{ + return "::Ice::CloseConnectionException"; +} + +Ice::CloseConnectionException* +Ice::CloseConnectionException::ice_clone() const +{ + return new CloseConnectionException(*this); +} + +void +Ice::CloseConnectionException::ice_throw() const +{ + throw *this; +} + +Ice::ConnectionManuallyClosedException::ConnectionManuallyClosedException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::ConnectionManuallyClosedException::ConnectionManuallyClosedException(const char* file, int line, bool graceful) : + LocalException(file, line), + graceful(graceful) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ConnectionManuallyClosedException::~ConnectionManuallyClosedException() +{ +} +#else +Ice::ConnectionManuallyClosedException::~ConnectionManuallyClosedException() throw() +{ +} +#endif + +::std::string +Ice::ConnectionManuallyClosedException::ice_id() const +{ + return "::Ice::ConnectionManuallyClosedException"; +} + +Ice::ConnectionManuallyClosedException* +Ice::ConnectionManuallyClosedException::ice_clone() const +{ + return new ConnectionManuallyClosedException(*this); +} + +void +Ice::ConnectionManuallyClosedException::ice_throw() const +{ + throw *this; +} + +Ice::IllegalMessageSizeException::IllegalMessageSizeException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::IllegalMessageSizeException::IllegalMessageSizeException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::IllegalMessageSizeException::~IllegalMessageSizeException() +{ +} +#else +Ice::IllegalMessageSizeException::~IllegalMessageSizeException() throw() +{ +} +#endif + +::std::string +Ice::IllegalMessageSizeException::ice_id() const +{ + return "::Ice::IllegalMessageSizeException"; +} + +Ice::IllegalMessageSizeException* +Ice::IllegalMessageSizeException::ice_clone() const +{ + return new IllegalMessageSizeException(*this); +} + +void +Ice::IllegalMessageSizeException::ice_throw() const +{ + throw *this; +} + +Ice::CompressionException::CompressionException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::CompressionException::CompressionException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::CompressionException::~CompressionException() +{ +} +#else +Ice::CompressionException::~CompressionException() throw() +{ +} +#endif + +::std::string +Ice::CompressionException::ice_id() const +{ + return "::Ice::CompressionException"; +} + +Ice::CompressionException* +Ice::CompressionException::ice_clone() const +{ + return new CompressionException(*this); +} + +void +Ice::CompressionException::ice_throw() const +{ + throw *this; +} + +Ice::DatagramLimitException::DatagramLimitException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::DatagramLimitException::DatagramLimitException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::DatagramLimitException::~DatagramLimitException() +{ +} +#else +Ice::DatagramLimitException::~DatagramLimitException() throw() +{ +} +#endif + +::std::string +Ice::DatagramLimitException::ice_id() const +{ + return "::Ice::DatagramLimitException"; +} + +Ice::DatagramLimitException* +Ice::DatagramLimitException::ice_clone() const +{ + return new DatagramLimitException(*this); +} + +void +Ice::DatagramLimitException::ice_throw() const +{ + throw *this; +} + +Ice::MarshalException::MarshalException(const char* file, int line) : + ProtocolException(file, line) +{ +} + +Ice::MarshalException::MarshalException(const char* file, int line, const ::std::string& reason) : + ProtocolException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::MarshalException::~MarshalException() +{ +} +#else +Ice::MarshalException::~MarshalException() throw() +{ +} +#endif + +::std::string +Ice::MarshalException::ice_id() const +{ + return "::Ice::MarshalException"; +} + +Ice::MarshalException* +Ice::MarshalException::ice_clone() const +{ + return new MarshalException(*this); +} + +void +Ice::MarshalException::ice_throw() const +{ + throw *this; +} + +Ice::ProxyUnmarshalException::ProxyUnmarshalException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::ProxyUnmarshalException::ProxyUnmarshalException(const char* file, int line, const ::std::string& reason) : + MarshalException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ProxyUnmarshalException::~ProxyUnmarshalException() +{ +} +#else +Ice::ProxyUnmarshalException::~ProxyUnmarshalException() throw() +{ +} +#endif + +::std::string +Ice::ProxyUnmarshalException::ice_id() const +{ + return "::Ice::ProxyUnmarshalException"; +} + +Ice::ProxyUnmarshalException* +Ice::ProxyUnmarshalException::ice_clone() const +{ + return new ProxyUnmarshalException(*this); +} + +void +Ice::ProxyUnmarshalException::ice_throw() const +{ + throw *this; +} + +Ice::UnmarshalOutOfBoundsException::UnmarshalOutOfBoundsException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::UnmarshalOutOfBoundsException::UnmarshalOutOfBoundsException(const char* file, int line, const ::std::string& reason) : + MarshalException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnmarshalOutOfBoundsException::~UnmarshalOutOfBoundsException() +{ +} +#else +Ice::UnmarshalOutOfBoundsException::~UnmarshalOutOfBoundsException() throw() +{ +} +#endif + +::std::string +Ice::UnmarshalOutOfBoundsException::ice_id() const +{ + return "::Ice::UnmarshalOutOfBoundsException"; +} + +Ice::UnmarshalOutOfBoundsException* +Ice::UnmarshalOutOfBoundsException::ice_clone() const +{ + return new UnmarshalOutOfBoundsException(*this); +} + +void +Ice::UnmarshalOutOfBoundsException::ice_throw() const +{ + throw *this; +} + +Ice::NoValueFactoryException::NoValueFactoryException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::NoValueFactoryException::NoValueFactoryException(const char* file, int line, const ::std::string& reason, const ::std::string& type) : + MarshalException(file, line, reason), + type(type) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::NoValueFactoryException::~NoValueFactoryException() +{ +} +#else +Ice::NoValueFactoryException::~NoValueFactoryException() throw() +{ +} +#endif + +::std::string +Ice::NoValueFactoryException::ice_id() const +{ + return "::Ice::NoValueFactoryException"; +} + +Ice::NoValueFactoryException* +Ice::NoValueFactoryException::ice_clone() const +{ + return new NoValueFactoryException(*this); +} + +void +Ice::NoValueFactoryException::ice_throw() const +{ + throw *this; +} + +Ice::UnexpectedObjectException::UnexpectedObjectException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::UnexpectedObjectException::UnexpectedObjectException(const char* file, int line, const ::std::string& reason, const ::std::string& type, const ::std::string& expectedType) : + MarshalException(file, line, reason), + type(type), + expectedType(expectedType) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::UnexpectedObjectException::~UnexpectedObjectException() +{ +} +#else +Ice::UnexpectedObjectException::~UnexpectedObjectException() throw() +{ +} +#endif + +::std::string +Ice::UnexpectedObjectException::ice_id() const +{ + return "::Ice::UnexpectedObjectException"; +} + +Ice::UnexpectedObjectException* +Ice::UnexpectedObjectException::ice_clone() const +{ + return new UnexpectedObjectException(*this); +} + +void +Ice::UnexpectedObjectException::ice_throw() const +{ + throw *this; +} + +Ice::MemoryLimitException::MemoryLimitException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::MemoryLimitException::MemoryLimitException(const char* file, int line, const ::std::string& reason) : + MarshalException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::MemoryLimitException::~MemoryLimitException() +{ +} +#else +Ice::MemoryLimitException::~MemoryLimitException() throw() +{ +} +#endif + +::std::string +Ice::MemoryLimitException::ice_id() const +{ + return "::Ice::MemoryLimitException"; +} + +Ice::MemoryLimitException* +Ice::MemoryLimitException::ice_clone() const +{ + return new MemoryLimitException(*this); +} + +void +Ice::MemoryLimitException::ice_throw() const +{ + throw *this; +} + +Ice::StringConversionException::StringConversionException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::StringConversionException::StringConversionException(const char* file, int line, const ::std::string& reason) : + MarshalException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::StringConversionException::~StringConversionException() +{ +} +#else +Ice::StringConversionException::~StringConversionException() throw() +{ +} +#endif + +::std::string +Ice::StringConversionException::ice_id() const +{ + return "::Ice::StringConversionException"; +} + +Ice::StringConversionException* +Ice::StringConversionException::ice_clone() const +{ + return new StringConversionException(*this); +} + +void +Ice::StringConversionException::ice_throw() const +{ + throw *this; +} + +Ice::EncapsulationException::EncapsulationException(const char* file, int line) : + MarshalException(file, line) +{ +} + +Ice::EncapsulationException::EncapsulationException(const char* file, int line, const ::std::string& reason) : + MarshalException(file, line, reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::EncapsulationException::~EncapsulationException() +{ +} +#else +Ice::EncapsulationException::~EncapsulationException() throw() +{ +} +#endif + +::std::string +Ice::EncapsulationException::ice_id() const +{ + return "::Ice::EncapsulationException"; +} + +Ice::EncapsulationException* +Ice::EncapsulationException::ice_clone() const +{ + return new EncapsulationException(*this); +} + +void +Ice::EncapsulationException::ice_throw() const +{ + throw *this; +} + +Ice::FeatureNotSupportedException::FeatureNotSupportedException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::FeatureNotSupportedException::FeatureNotSupportedException(const char* file, int line, const ::std::string& unsupportedFeature) : + LocalException(file, line), + unsupportedFeature(unsupportedFeature) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::FeatureNotSupportedException::~FeatureNotSupportedException() +{ +} +#else +Ice::FeatureNotSupportedException::~FeatureNotSupportedException() throw() +{ +} +#endif + +::std::string +Ice::FeatureNotSupportedException::ice_id() const +{ + return "::Ice::FeatureNotSupportedException"; +} + +Ice::FeatureNotSupportedException* +Ice::FeatureNotSupportedException::ice_clone() const +{ + return new FeatureNotSupportedException(*this); +} + +void +Ice::FeatureNotSupportedException::ice_throw() const +{ + throw *this; +} + +Ice::SecurityException::SecurityException(const char* file, int line) : + LocalException(file, line) +{ +} + +Ice::SecurityException::SecurityException(const char* file, int line, const ::std::string& reason) : + LocalException(file, line), + reason(reason) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::SecurityException::~SecurityException() +{ +} +#else +Ice::SecurityException::~SecurityException() throw() +{ +} +#endif + +::std::string +Ice::SecurityException::ice_id() const +{ + return "::Ice::SecurityException"; +} + +Ice::SecurityException* +Ice::SecurityException::ice_clone() const +{ + return new SecurityException(*this); +} + +void +Ice::SecurityException::ice_throw() const +{ + throw *this; +} + +Ice::FixedProxyException::FixedProxyException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::FixedProxyException::~FixedProxyException() +{ +} +#else +Ice::FixedProxyException::~FixedProxyException() throw() +{ +} +#endif + +::std::string +Ice::FixedProxyException::ice_id() const +{ + return "::Ice::FixedProxyException"; +} + +Ice::FixedProxyException* +Ice::FixedProxyException::ice_clone() const +{ + return new FixedProxyException(*this); +} + +void +Ice::FixedProxyException::ice_throw() const +{ + throw *this; +} + +Ice::ResponseSentException::ResponseSentException(const char* file, int line) : + LocalException(file, line) +{ +} + +#ifdef ICE_CPP11_COMPILER +Ice::ResponseSentException::~ResponseSentException() +{ +} +#else +Ice::ResponseSentException::~ResponseSentException() throw() +{ +} +#endif + +::std::string +Ice::ResponseSentException::ice_id() const +{ + return "::Ice::ResponseSentException"; +} + +Ice::ResponseSentException* +Ice::ResponseSentException::ice_clone() const +{ + return new ResponseSentException(*this); +} + +void +Ice::ResponseSentException::ice_throw() const +{ + throw *this; +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/LocalObject.cpp b/Sources/IceCpp/LocalObject.cpp new file mode 100644 index 0000000..ff6b387 --- /dev/null +++ b/Sources/IceCpp/LocalObject.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* Ice::upCast(LocalObject* obj) { return obj; } + +bool +Ice::LocalObject::operator==(const LocalObject& r) const +{ + return this == &r; +} + +bool +Ice::LocalObject::operator<(const LocalObject& r) const +{ + return this < &r; +} diff --git a/Sources/IceCpp/Locator.cpp b/Sources/IceCpp/Locator.cpp new file mode 100644 index 0000000..c2929f3 --- /dev/null +++ b/Sources/IceCpp/Locator.cpp @@ -0,0 +1,2042 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Locator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::AdapterNotFoundException> iceC_Ice_AdapterNotFoundException_init("::Ice::AdapterNotFoundException"); + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::InvalidReplicaGroupIdException> iceC_Ice_InvalidReplicaGroupIdException_init("::Ice::InvalidReplicaGroupIdException"); + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::AdapterAlreadyActiveException> iceC_Ice_AdapterAlreadyActiveException_init("::Ice::AdapterAlreadyActiveException"); + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::ObjectNotFoundException> iceC_Ice_ObjectNotFoundException_init("::Ice::ObjectNotFoundException"); + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::ServerNotFoundException> iceC_Ice_ServerNotFoundException_init("::Ice::ServerNotFoundException"); + +const ::std::string iceC_Ice_Locator_ids[2] = +{ + "::Ice::Locator", + "::Ice::Object" +}; +const ::std::string iceC_Ice_Locator_ops[] = +{ + "findAdapterById", + "findObjectById", + "getRegistry", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_Ice_Locator_findObjectById_name = "findObjectById"; +const ::std::string iceC_Ice_Locator_findAdapterById_name = "findAdapterById"; +const ::std::string iceC_Ice_Locator_getRegistry_name = "getRegistry"; + +const ::std::string iceC_Ice_LocatorRegistry_ids[2] = +{ + "::Ice::LocatorRegistry", + "::Ice::Object" +}; +const ::std::string iceC_Ice_LocatorRegistry_ops[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "setAdapterDirectProxy", + "setReplicatedAdapterDirectProxy", + "setServerProcessProxy" +}; +const ::std::string iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name = "setAdapterDirectProxy"; +const ::std::string iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name = "setReplicatedAdapterDirectProxy"; +const ::std::string iceC_Ice_LocatorRegistry_setServerProcessProxy_name = "setServerProcessProxy"; + +const ::std::string iceC_Ice_LocatorFinder_ids[2] = +{ + "::Ice::LocatorFinder", + "::Ice::Object" +}; +const ::std::string iceC_Ice_LocatorFinder_ops[] = +{ + "getLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_Ice_LocatorFinder_getLocator_name = "getLocator"; + +} + +Ice::AdapterNotFoundException::~AdapterNotFoundException() +{ +} + +const ::std::string& +Ice::AdapterNotFoundException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::AdapterNotFoundException"; + return typeId; +} + +Ice::InvalidReplicaGroupIdException::~InvalidReplicaGroupIdException() +{ +} + +const ::std::string& +Ice::InvalidReplicaGroupIdException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::InvalidReplicaGroupIdException"; + return typeId; +} + +Ice::AdapterAlreadyActiveException::~AdapterAlreadyActiveException() +{ +} + +const ::std::string& +Ice::AdapterAlreadyActiveException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::AdapterAlreadyActiveException"; + return typeId; +} + +Ice::ObjectNotFoundException::~ObjectNotFoundException() +{ +} + +const ::std::string& +Ice::ObjectNotFoundException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ObjectNotFoundException"; + return typeId; +} + +Ice::ServerNotFoundException::~ServerNotFoundException() +{ +} + +const ::std::string& +Ice::ServerNotFoundException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::ServerNotFoundException"; + return typeId; +} + +bool +Ice::Locator::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Locator_ids, iceC_Ice_Locator_ids + 2, s); +} + +::std::vector<::std::string> +Ice::Locator::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_Locator_ids[0], &iceC_Ice_Locator_ids[2]); +} + +::std::string +Ice::Locator::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Locator::ice_staticId() +{ + static const ::std::string typeId = "::Ice::Locator"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_findObjectById(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + Identity iceP_id; + istr->readAll(iceP_id); + inS.endReadParams(); + auto inA = ::IceInternal::IncomingAsync::create(inS); + auto responseCB = [inA](const ::std::shared_ptr& ret) + { + auto ostr = inA->startWriteParams(); + ostr->writeAll(ret); + inA->endWriteParams(); + inA->completed(); + }; + this->findObjectByIdAsync(::std::move(iceP_id), responseCB, inA->exception(), current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_findAdapterById(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_id; + istr->readAll(iceP_id); + inS.endReadParams(); + auto inA = ::IceInternal::IncomingAsync::create(inS); + auto responseCB = [inA](const ::std::shared_ptr& ret) + { + auto ostr = inA->startWriteParams(); + ostr->writeAll(ret); + inA->endWriteParams(); + inA->completed(); + }; + this->findAdapterByIdAsync(::std::move(iceP_id), responseCB, inA->exception(), current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_getRegistry(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + inS.readEmptyParams(); + ::std::shared_ptr ret = this->getRegistry(current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Locator::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Locator_ops, iceC_Ice_Locator_ops + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Locator_ops) + { + case 0: + { + return _iceD_findAdapterById(in, current); + } + case 1: + { + return _iceD_findObjectById(in, current); + } + case 2: + { + return _iceD_getRegistry(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +Ice::LocatorRegistry::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LocatorRegistry_ids, iceC_Ice_LocatorRegistry_ids + 2, s); +} + +::std::vector<::std::string> +Ice::LocatorRegistry::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_LocatorRegistry_ids[0], &iceC_Ice_LocatorRegistry_ids[2]); +} + +::std::string +Ice::LocatorRegistry::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LocatorRegistry::ice_staticId() +{ + static const ::std::string typeId = "::Ice::LocatorRegistry"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setAdapterDirectProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_id; + ::std::shared_ptr iceP_proxy; + istr->readAll(iceP_id, iceP_proxy); + inS.endReadParams(); + auto inA = ::IceInternal::IncomingAsync::create(inS); + this->setAdapterDirectProxyAsync(::std::move(iceP_id), ::std::move(iceP_proxy), inA->response(), inA->exception(), current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setReplicatedAdapterDirectProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_adapterId; + ::std::string iceP_replicaGroupId; + ::std::shared_ptr iceP_p; + istr->readAll(iceP_adapterId, iceP_replicaGroupId, iceP_p); + inS.endReadParams(); + auto inA = ::IceInternal::IncomingAsync::create(inS); + this->setReplicatedAdapterDirectProxyAsync(::std::move(iceP_adapterId), ::std::move(iceP_replicaGroupId), ::std::move(iceP_p), inA->response(), inA->exception(), current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setServerProcessProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_id; + ::std::shared_ptr iceP_proxy; + istr->readAll(iceP_id, iceP_proxy); + inS.endReadParams(); + auto inA = ::IceInternal::IncomingAsync::create(inS); + this->setServerProcessProxyAsync(::std::move(iceP_id), ::std::move(iceP_proxy), inA->response(), inA->exception(), current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LocatorRegistry_ops, iceC_Ice_LocatorRegistry_ops + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LocatorRegistry_ops) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_setAdapterDirectProxy(in, current); + } + case 5: + { + return _iceD_setReplicatedAdapterDirectProxy(in, current); + } + case 6: + { + return _iceD_setServerProcessProxy(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +Ice::LocatorFinder::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LocatorFinder_ids, iceC_Ice_LocatorFinder_ids + 2, s); +} + +::std::vector<::std::string> +Ice::LocatorFinder::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_LocatorFinder_ids[0], &iceC_Ice_LocatorFinder_ids[2]); +} + +::std::string +Ice::LocatorFinder::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LocatorFinder::ice_staticId() +{ + static const ::std::string typeId = "::Ice::LocatorFinder"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::LocatorFinder::_iceD_getLocator(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + inS.readEmptyParams(); + ::std::shared_ptr ret = this->getLocator(current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorFinder::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LocatorFinder_ops, iceC_Ice_LocatorFinder_ops + 5, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LocatorFinder_ops) + { + case 0: + { + return _iceD_getLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LocatorPrx::_iceI_findObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>& outAsync, const Identity& iceP_id, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Locator_findObjectById_name); + outAsync->invoke(iceC_Ice_Locator_findObjectById_name, ::Ice::OperationMode::Nonmutating, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_id); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const ObjectNotFoundException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LocatorPrx::_iceI_findAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>& outAsync, const ::std::string& iceP_id, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Locator_findAdapterById_name); + outAsync->invoke(iceC_Ice_Locator_findAdapterById_name, ::Ice::OperationMode::Nonmutating, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_id); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const AdapterNotFoundException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LocatorPrx::_iceI_getRegistry(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::LocatorRegistryPrx>>>& outAsync, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Locator_getRegistry_name); + outAsync->invoke(iceC_Ice_Locator_getRegistry_name, ::Ice::OperationMode::Nonmutating, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::LocatorPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::LocatorPrx::ice_staticId() +{ + return Locator::ice_staticId(); +} + +/// \cond INTERNAL +void +Ice::LocatorRegistryPrx::_iceI_setAdapterDirectProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_id, const ::std::shared_ptr& iceP_proxy, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name); + outAsync->invoke(iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_id, iceP_proxy); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const AdapterAlreadyActiveException&) + { + throw; + } + catch(const AdapterNotFoundException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LocatorRegistryPrx::_iceI_setReplicatedAdapterDirectProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_adapterId, const ::std::string& iceP_replicaGroupId, const ::std::shared_ptr& iceP_p, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name); + outAsync->invoke(iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_adapterId, iceP_replicaGroupId, iceP_p); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const AdapterAlreadyActiveException&) + { + throw; + } + catch(const AdapterNotFoundException&) + { + throw; + } + catch(const InvalidReplicaGroupIdException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LocatorRegistryPrx::_iceI_setServerProcessProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_id, const ::std::shared_ptr& iceP_proxy, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setServerProcessProxy_name); + outAsync->invoke(iceC_Ice_LocatorRegistry_setServerProcessProxy_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_id, iceP_proxy); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const ServerNotFoundException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::LocatorRegistryPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::LocatorRegistryPrx::ice_staticId() +{ + return LocatorRegistry::ice_staticId(); +} + +/// \cond INTERNAL +void +Ice::LocatorFinderPrx::_iceI_getLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::LocatorPrx>>>& outAsync, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LocatorFinder_getLocator_name); + outAsync->invoke(iceC_Ice_LocatorFinder_getLocator_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::LocatorFinderPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::LocatorFinderPrx::ice_staticId() +{ + return LocatorFinder::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_Ice_Locator_findObjectById_name = "findObjectById"; + +const ::std::string iceC_Ice_Locator_findAdapterById_name = "findAdapterById"; + +const ::std::string iceC_Ice_Locator_getRegistry_name = "getRegistry"; + +const ::std::string iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name = "setAdapterDirectProxy"; + +const ::std::string iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name = "setReplicatedAdapterDirectProxy"; + +const ::std::string iceC_Ice_LocatorRegistry_setServerProcessProxy_name = "setServerProcessProxy"; + +const ::std::string iceC_Ice_LocatorFinder_getLocator_name = "getLocator"; + +} + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::AdapterNotFoundException> iceC_Ice_AdapterNotFoundException_init("::Ice::AdapterNotFoundException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::AdapterNotFoundException::~AdapterNotFoundException() +{ +} +#else +Ice::AdapterNotFoundException::~AdapterNotFoundException() throw() +{ +} +#endif + +::std::string +Ice::AdapterNotFoundException::ice_id() const +{ + return "::Ice::AdapterNotFoundException"; +} + +Ice::AdapterNotFoundException* +Ice::AdapterNotFoundException::ice_clone() const +{ + return new AdapterNotFoundException(*this); +} + +void +Ice::AdapterNotFoundException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::AdapterNotFoundException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::AdapterNotFoundException", -1, true); + StreamWriter< AdapterNotFoundException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::AdapterNotFoundException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< AdapterNotFoundException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::InvalidReplicaGroupIdException> iceC_Ice_InvalidReplicaGroupIdException_init("::Ice::InvalidReplicaGroupIdException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::InvalidReplicaGroupIdException::~InvalidReplicaGroupIdException() +{ +} +#else +Ice::InvalidReplicaGroupIdException::~InvalidReplicaGroupIdException() throw() +{ +} +#endif + +::std::string +Ice::InvalidReplicaGroupIdException::ice_id() const +{ + return "::Ice::InvalidReplicaGroupIdException"; +} + +Ice::InvalidReplicaGroupIdException* +Ice::InvalidReplicaGroupIdException::ice_clone() const +{ + return new InvalidReplicaGroupIdException(*this); +} + +void +Ice::InvalidReplicaGroupIdException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::InvalidReplicaGroupIdException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::InvalidReplicaGroupIdException", -1, true); + StreamWriter< InvalidReplicaGroupIdException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::InvalidReplicaGroupIdException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< InvalidReplicaGroupIdException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::AdapterAlreadyActiveException> iceC_Ice_AdapterAlreadyActiveException_init("::Ice::AdapterAlreadyActiveException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::AdapterAlreadyActiveException::~AdapterAlreadyActiveException() +{ +} +#else +Ice::AdapterAlreadyActiveException::~AdapterAlreadyActiveException() throw() +{ +} +#endif + +::std::string +Ice::AdapterAlreadyActiveException::ice_id() const +{ + return "::Ice::AdapterAlreadyActiveException"; +} + +Ice::AdapterAlreadyActiveException* +Ice::AdapterAlreadyActiveException::ice_clone() const +{ + return new AdapterAlreadyActiveException(*this); +} + +void +Ice::AdapterAlreadyActiveException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::AdapterAlreadyActiveException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::AdapterAlreadyActiveException", -1, true); + StreamWriter< AdapterAlreadyActiveException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::AdapterAlreadyActiveException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< AdapterAlreadyActiveException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::ObjectNotFoundException> iceC_Ice_ObjectNotFoundException_init("::Ice::ObjectNotFoundException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::ObjectNotFoundException::~ObjectNotFoundException() +{ +} +#else +Ice::ObjectNotFoundException::~ObjectNotFoundException() throw() +{ +} +#endif + +::std::string +Ice::ObjectNotFoundException::ice_id() const +{ + return "::Ice::ObjectNotFoundException"; +} + +Ice::ObjectNotFoundException* +Ice::ObjectNotFoundException::ice_clone() const +{ + return new ObjectNotFoundException(*this); +} + +void +Ice::ObjectNotFoundException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::ObjectNotFoundException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::ObjectNotFoundException", -1, true); + StreamWriter< ObjectNotFoundException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::ObjectNotFoundException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< ObjectNotFoundException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::ServerNotFoundException> iceC_Ice_ServerNotFoundException_init("::Ice::ServerNotFoundException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::ServerNotFoundException::~ServerNotFoundException() +{ +} +#else +Ice::ServerNotFoundException::~ServerNotFoundException() throw() +{ +} +#endif + +::std::string +Ice::ServerNotFoundException::ice_id() const +{ + return "::Ice::ServerNotFoundException"; +} + +Ice::ServerNotFoundException* +Ice::ServerNotFoundException::ice_clone() const +{ + return new ServerNotFoundException(*this); +} + +void +Ice::ServerNotFoundException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::ServerNotFoundException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::ServerNotFoundException", -1, true); + StreamWriter< ServerNotFoundException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::ServerNotFoundException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< ServerNotFoundException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +Ice::AMD_Locator_findObjectById::~AMD_Locator_findObjectById() +{ +} + +Ice::AMD_Locator_findAdapterById::~AMD_Locator_findAdapterById() +{ +} + +Ice::AMD_LocatorRegistry_setAdapterDirectProxy::~AMD_LocatorRegistry_setAdapterDirectProxy() +{ +} + +Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy::~AMD_LocatorRegistry_setReplicatedAdapterDirectProxy() +{ +} + +Ice::AMD_LocatorRegistry_setServerProcessProxy::~AMD_LocatorRegistry_setServerProcessProxy() +{ +} + +/// \cond INTERNAL +IceAsync::Ice::AMD_Locator_findObjectById::AMD_Locator_findObjectById(::IceInternal::Incoming& in) : + ::IceInternal::IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_Locator_findObjectById::ice_response(const ::Ice::ObjectPrx& ret) +{ + ::Ice::OutputStream* ostr = startWriteParams(); + ostr->write(ret); + endWriteParams(); + completed(); +} +/// \endcond + +/// \cond INTERNAL +IceAsync::Ice::AMD_Locator_findAdapterById::AMD_Locator_findAdapterById(::IceInternal::Incoming& in) : + ::IceInternal::IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_Locator_findAdapterById::ice_response(const ::Ice::ObjectPrx& ret) +{ + ::Ice::OutputStream* ostr = startWriteParams(); + ostr->write(ret); + endWriteParams(); + completed(); +} +/// \endcond + +/// \cond INTERNAL +IceAsync::Ice::AMD_LocatorRegistry_setAdapterDirectProxy::AMD_LocatorRegistry_setAdapterDirectProxy(::IceInternal::Incoming& in) : + ::IceInternal::IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_LocatorRegistry_setAdapterDirectProxy::ice_response() +{ + writeEmptyParams(); + completed(); +} +/// \endcond + +/// \cond INTERNAL +IceAsync::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy(::IceInternal::Incoming& in) : + ::IceInternal::IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy::ice_response() +{ + writeEmptyParams(); + completed(); +} +/// \endcond + +/// \cond INTERNAL +IceAsync::Ice::AMD_LocatorRegistry_setServerProcessProxy::AMD_LocatorRegistry_setServerProcessProxy(::IceInternal::Incoming& in) : + ::IceInternal::IncomingAsync(in) +{ +} + +void +IceAsync::Ice::AMD_LocatorRegistry_setServerProcessProxy::ice_response() +{ + writeEmptyParams(); + completed(); +} +/// \endcond + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(Locator* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Locator>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Locator; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::Locator::_iceI_begin_findObjectById(const ::Ice::Identity& iceP_id, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Locator_findObjectById_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Locator_findObjectById_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Locator_findObjectById_name, ::Ice::Nonmutating, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + result->endWriteParams(); + result->invoke(iceC_Ice_Locator_findObjectById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::ObjectPrx +IceProxy::Ice::Locator::end_findObjectById(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Locator_findObjectById_name); + ::Ice::ObjectPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::ObjectNotFoundException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Locator::_iceI_begin_findAdapterById(const ::std::string& iceP_id, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Locator_findAdapterById_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Locator_findAdapterById_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Locator_findAdapterById_name, ::Ice::Nonmutating, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + result->endWriteParams(); + result->invoke(iceC_Ice_Locator_findAdapterById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::ObjectPrx +IceProxy::Ice::Locator::end_findAdapterById(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Locator_findAdapterById_name); + ::Ice::ObjectPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::AdapterNotFoundException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Locator::_iceI_begin_getRegistry(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Locator_getRegistry_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Locator_getRegistry_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Locator_getRegistry_name, ::Ice::Nonmutating, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_Locator_getRegistry_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::LocatorRegistryPrx +IceProxy::Ice::Locator::end_getRegistry(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Locator_getRegistry_name); + ::Ice::LocatorRegistryPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::Locator::_newInstance() const +{ + return new Locator; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::Locator::ice_staticId() +{ + return ::Ice::Locator::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(LocatorRegistry* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< LocatorRegistry>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new LocatorRegistry; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::LocatorRegistry::_iceI_begin_setAdapterDirectProxy(const ::std::string& iceP_id, const ::Ice::ObjectPrx& iceP_proxy, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + ostr->write(iceP_proxy); + result->endWriteParams(); + result->invoke(iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::LocatorRegistry::end_setAdapterDirectProxy(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LocatorRegistry_setAdapterDirectProxy_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::AdapterAlreadyActiveException&) + { + throw; + } + catch(const ::Ice::AdapterNotFoundException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::LocatorRegistry::_iceI_begin_setReplicatedAdapterDirectProxy(const ::std::string& iceP_adapterId, const ::std::string& iceP_replicaGroupId, const ::Ice::ObjectPrx& iceP_p, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_adapterId); + ostr->write(iceP_replicaGroupId); + ostr->write(iceP_p); + result->endWriteParams(); + result->invoke(iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::LocatorRegistry::end_setReplicatedAdapterDirectProxy(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LocatorRegistry_setReplicatedAdapterDirectProxy_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::AdapterAlreadyActiveException&) + { + throw; + } + catch(const ::Ice::AdapterNotFoundException&) + { + throw; + } + catch(const ::Ice::InvalidReplicaGroupIdException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::LocatorRegistry::_iceI_begin_setServerProcessProxy(const ::std::string& iceP_id, const ::Ice::ProcessPrx& iceP_proxy, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LocatorRegistry_setServerProcessProxy_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LocatorRegistry_setServerProcessProxy_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LocatorRegistry_setServerProcessProxy_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + ostr->write(iceP_proxy); + result->endWriteParams(); + result->invoke(iceC_Ice_LocatorRegistry_setServerProcessProxy_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::LocatorRegistry::end_setServerProcessProxy(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LocatorRegistry_setServerProcessProxy_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::ServerNotFoundException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::LocatorRegistry::_newInstance() const +{ + return new LocatorRegistry; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::LocatorRegistry::ice_staticId() +{ + return ::Ice::LocatorRegistry::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(LocatorFinder* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< LocatorFinder>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new LocatorFinder; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::LocatorFinder::_iceI_begin_getLocator(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LocatorFinder_getLocator_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LocatorFinder_getLocator_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LocatorFinder_getLocator_name, ::Ice::Normal, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_LocatorFinder_getLocator_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::LocatorPrx +IceProxy::Ice::LocatorFinder::end_getLocator(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LocatorFinder_getLocator_name); + ::Ice::LocatorPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::LocatorFinder::_newInstance() const +{ + return new LocatorFinder; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::LocatorFinder::ice_staticId() +{ + return ::Ice::LocatorFinder::ice_staticId(); +} + +Ice::Locator::~Locator() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(Locator* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Locator_ids[2] = +{ + "::Ice::Locator", + "::Ice::Object" +}; + +} + +bool +Ice::Locator::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Locator_ids, iceC_Ice_Locator_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::Locator::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_Locator_ids[0], &iceC_Ice_Locator_ids[2]); +} + +const ::std::string& +Ice::Locator::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Locator::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::Locator"; + return typeId; +#else + return iceC_Ice_Locator_ids[0]; +#endif +} + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_findObjectById(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + Identity iceP_id; + istr->read(iceP_id); + inS.endReadParams(); + this->findObjectById_async(new IceAsync::Ice::AMD_Locator_findObjectById(inS), iceP_id, current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_findAdapterById(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_id; + istr->read(iceP_id); + inS.endReadParams(); + this->findAdapterById_async(new IceAsync::Ice::AMD_Locator_findAdapterById(inS), iceP_id, current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Locator::_iceD_getRegistry(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + inS.readEmptyParams(); + LocatorRegistryPrx ret = this->getRegistry(current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Locator_all[] = +{ + "findAdapterById", + "findObjectById", + "getRegistry", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +Ice::Locator::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Locator_all, iceC_Ice_Locator_all + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Locator_all) + { + case 0: + { + return _iceD_findAdapterById(in, current); + } + case 1: + { + return _iceD_findObjectById(in, current); + } + case 2: + { + return _iceD_getRegistry(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::Locator::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< Locator, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::Locator::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< Locator, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(LocatorPtr& handle, const ObjectPtr& v) +{ + handle = LocatorPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Locator::ice_staticId(), v); + } +} +/// \endcond + +Ice::LocatorRegistry::~LocatorRegistry() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(LocatorRegistry* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LocatorRegistry_ids[2] = +{ + "::Ice::LocatorRegistry", + "::Ice::Object" +}; + +} + +bool +Ice::LocatorRegistry::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LocatorRegistry_ids, iceC_Ice_LocatorRegistry_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::LocatorRegistry::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_LocatorRegistry_ids[0], &iceC_Ice_LocatorRegistry_ids[2]); +} + +const ::std::string& +Ice::LocatorRegistry::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LocatorRegistry::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::LocatorRegistry"; + return typeId; +#else + return iceC_Ice_LocatorRegistry_ids[0]; +#endif +} + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setAdapterDirectProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_id; + ObjectPrx iceP_proxy; + istr->read(iceP_id); + istr->read(iceP_proxy); + inS.endReadParams(); + this->setAdapterDirectProxy_async(new IceAsync::Ice::AMD_LocatorRegistry_setAdapterDirectProxy(inS), iceP_id, iceP_proxy, current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setReplicatedAdapterDirectProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_adapterId; + ::std::string iceP_replicaGroupId; + ObjectPrx iceP_p; + istr->read(iceP_adapterId); + istr->read(iceP_replicaGroupId); + istr->read(iceP_p); + inS.endReadParams(); + this->setReplicatedAdapterDirectProxy_async(new IceAsync::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy(inS), iceP_adapterId, iceP_replicaGroupId, iceP_p, current); + return false; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceD_setServerProcessProxy(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_id; + ProcessPrx iceP_proxy; + istr->read(iceP_id); + istr->read(iceP_proxy); + inS.endReadParams(); + this->setServerProcessProxy_async(new IceAsync::Ice::AMD_LocatorRegistry_setServerProcessProxy(inS), iceP_id, iceP_proxy, current); + return false; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LocatorRegistry_all[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "setAdapterDirectProxy", + "setReplicatedAdapterDirectProxy", + "setServerProcessProxy" +}; + +} + +/// \cond INTERNAL +bool +Ice::LocatorRegistry::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LocatorRegistry_all, iceC_Ice_LocatorRegistry_all + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LocatorRegistry_all) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_setAdapterDirectProxy(in, current); + } + case 5: + { + return _iceD_setReplicatedAdapterDirectProxy(in, current); + } + case 6: + { + return _iceD_setServerProcessProxy(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::LocatorRegistry::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< LocatorRegistry, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::LocatorRegistry::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< LocatorRegistry, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(LocatorRegistryPtr& handle, const ObjectPtr& v) +{ + handle = LocatorRegistryPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(LocatorRegistry::ice_staticId(), v); + } +} +/// \endcond + +Ice::LocatorFinder::~LocatorFinder() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(LocatorFinder* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LocatorFinder_ids[2] = +{ + "::Ice::LocatorFinder", + "::Ice::Object" +}; + +} + +bool +Ice::LocatorFinder::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LocatorFinder_ids, iceC_Ice_LocatorFinder_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::LocatorFinder::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_LocatorFinder_ids[0], &iceC_Ice_LocatorFinder_ids[2]); +} + +const ::std::string& +Ice::LocatorFinder::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LocatorFinder::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::LocatorFinder"; + return typeId; +#else + return iceC_Ice_LocatorFinder_ids[0]; +#endif +} + +/// \cond INTERNAL +bool +Ice::LocatorFinder::_iceD_getLocator(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + inS.readEmptyParams(); + LocatorPrx ret = this->getLocator(current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LocatorFinder_all[] = +{ + "getLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +Ice::LocatorFinder::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LocatorFinder_all, iceC_Ice_LocatorFinder_all + 5, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LocatorFinder_all) + { + case 0: + { + return _iceD_getLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::LocatorFinder::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< LocatorFinder, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::LocatorFinder::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< LocatorFinder, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(LocatorFinderPtr& handle, const ObjectPtr& v) +{ + handle = LocatorFinderPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(LocatorFinder::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/LocatorF.cpp b/Sources/IceCpp/LocatorF.cpp new file mode 100644 index 0000000..f61eb59 --- /dev/null +++ b/Sources/IceCpp/LocatorF.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/LocatorInfo.cpp b/Sources/IceCpp/LocatorInfo.cpp new file mode 100644 index 0000000..347e1c7 --- /dev/null +++ b/Sources/IceCpp/LocatorInfo.cpp @@ -0,0 +1,889 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(LocatorManager* p) { return p; } +IceUtil::Shared* IceInternal::upCast(LocatorInfo* p) { return p; } +IceUtil::Shared* IceInternal::upCast(LocatorTable* p) { return p; } + +namespace +{ + +class ObjectRequest : public LocatorInfo::Request +{ +public: + + ObjectRequest(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : LocatorInfo::Request(locatorInfo, ref) + { + assert(ref->isWellKnown()); + } + + virtual void send() + { + try + { +#ifdef ICE_CPP11_MAPPING + LocatorInfo::RequestPtr request = this; + _locatorInfo->getLocator()->findObjectByIdAsync( + _reference->getIdentity(), + [request](const ObjectPrxPtr& object) + { + request->response(object); + }, + [request](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Exception& ex) + { + request->exception(ex); + } + }); +#else + _locatorInfo->getLocator()->begin_findObjectById( + _reference->getIdentity(), + newCallback_Locator_findObjectById(static_cast(this), + &LocatorInfo::Request::response, + &LocatorInfo::Request::exception)); +#endif + } + catch(const Ice::Exception& ex) + { + exception(ex); + } + } +}; + +class AdapterRequest : public LocatorInfo::Request +{ +public: + + AdapterRequest(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : LocatorInfo::Request(locatorInfo, ref) + { + assert(ref->isIndirect() && !ref->isWellKnown()); + } + + virtual void send() + { + try + { +#ifdef ICE_CPP11_MAPPING + LocatorInfo::RequestPtr request = this; + _locatorInfo->getLocator()->findAdapterByIdAsync(_reference->getAdapterId(), + [request](const shared_ptr& object) + { + request->response(object); + }, + [request](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Exception& ex) + { + request->exception(ex); + } + }); +#else + _locatorInfo->getLocator()->begin_findAdapterById( + _reference->getAdapterId(), + newCallback_Locator_findAdapterById(static_cast(this), + &LocatorInfo::Request::response, + &LocatorInfo::Request::exception)); +#endif + } + catch(const Ice::Exception& ex) + { + exception(ex); + } + } +}; + +} + +IceInternal::LocatorManager::LocatorManager(const Ice::PropertiesPtr& properties) : + _background(properties->getPropertyAsInt("Ice.BackgroundLocatorCacheUpdates") > 0), + _tableHint(_table.end()) +{ +} + +void +IceInternal::LocatorManager::destroy() +{ + IceUtil::Mutex::Lock sync(*this); + +#ifdef ICE_CPP11_COMPILER + for_each(_table.begin(), _table.end(), [](pair it){ it.second->destroy(); }); +#else + for_each(_table.begin(), _table.end(), Ice::secondVoidMemFun(&LocatorInfo::destroy)); +#endif + _table.clear(); + _tableHint = _table.end(); + + _locatorTables.clear(); +} + +LocatorInfoPtr +IceInternal::LocatorManager::get(const LocatorPrxPtr& loc) +{ + if(!loc) + { + return 0; + } + + LocatorPrxPtr locator = loc->ice_locator(0); // The locator can't be located. + + // + // TODO: reap unused locator info objects? + // + + IceUtil::Mutex::Lock sync(*this); + + LocatorInfoTable::iterator p = _table.end(); + + if(_tableHint != _table.end()) + { + if(targetEqualTo(_tableHint->first, locator)) + { + p = _tableHint; + } + } + + if(p == _table.end()) + { + p = _table.find(locator); + } + + if(p == _table.end()) + { + // + // Rely on locator identity for the adapter table. We want to + // have only one table per locator (not one per locator + // proxy). + // + pair locatorKey(locator->ice_getIdentity(), locator->ice_getEncodingVersion()); + map, LocatorTablePtr>::iterator t = _locatorTables.find(locatorKey); + if(t == _locatorTables.end()) + { + t = _locatorTables.insert(_locatorTables.begin(), + pair, LocatorTablePtr>( + locatorKey, new LocatorTable())); + } + + _tableHint = _table.insert(_tableHint, + pair(locator, + new LocatorInfo(locator, t->second, + _background))); + } + else + { + _tableHint = p; + } + + return _tableHint->second; +} + +IceInternal::LocatorTable::LocatorTable() +{ +} + +void +IceInternal::LocatorTable::clear() +{ + IceUtil::Mutex::Lock sync(*this); + + _adapterEndpointsMap.clear(); + _objectMap.clear(); +} + +bool +IceInternal::LocatorTable::getAdapterEndpoints(const string& adapter, int ttl, vector& endpoints) +{ + if(ttl == 0) // No locator cache. + { + return false; + } + + IceUtil::Mutex::Lock sync(*this); + + map > >::iterator p = _adapterEndpointsMap.find(adapter); + + if(p != _adapterEndpointsMap.end()) + { + endpoints = p->second.second; + return checkTTL(p->second.first, ttl); + } + return false; +} + +void +IceInternal::LocatorTable::addAdapterEndpoints(const string& adapter, const vector& endpoints) +{ + IceUtil::Mutex::Lock sync(*this); + + map > >::iterator p = _adapterEndpointsMap.find(adapter); + + if(p != _adapterEndpointsMap.end()) + { + p->second = make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), endpoints); + } + else + { + _adapterEndpointsMap.insert( + make_pair(adapter, make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), endpoints))); + } +} + +vector +IceInternal::LocatorTable::removeAdapterEndpoints(const string& adapter) +{ + IceUtil::Mutex::Lock sync(*this); + + map > >::iterator p = _adapterEndpointsMap.find(adapter); + if(p == _adapterEndpointsMap.end()) + { + return vector(); + } + + vector endpoints = p->second.second; + + _adapterEndpointsMap.erase(p); + + return endpoints; +} + +bool +IceInternal::LocatorTable::getObjectReference(const Identity& id, int ttl, ReferencePtr& ref) +{ + if(ttl == 0) // No locator cache + { + return false; + } + + IceUtil::Mutex::Lock sync(*this); + + map >::iterator p = _objectMap.find(id); + + if(p != _objectMap.end()) + { + ref = p->second.second; + return checkTTL(p->second.first, ttl); + } + return false; +} + +void +IceInternal::LocatorTable::addObjectReference(const Identity& id, const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); + + map >::iterator p = _objectMap.find(id); + + if(p != _objectMap.end()) + { + p->second = make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), ref); + } + else + { + _objectMap.insert(make_pair(id, make_pair(IceUtil::Time::now(IceUtil::Time::Monotonic), ref))); + } +} + +ReferencePtr +IceInternal::LocatorTable::removeObjectReference(const Identity& id) +{ + IceUtil::Mutex::Lock sync(*this); + + map >::iterator p = _objectMap.find(id); + if(p == _objectMap.end()) + { + return 0; + } + + ReferencePtr ref = p->second.second; + _objectMap.erase(p); + return ref; +} + +bool +IceInternal::LocatorTable::checkTTL(const IceUtil::Time& time, int ttl) const +{ + assert(ttl != 0); + if (ttl < 0) // TTL = infinite + { + return true; + } + else + { + return IceUtil::Time::now(IceUtil::Time::Monotonic) - time <= IceUtil::Time::seconds(ttl); + } +} + +void +IceInternal::LocatorInfo::RequestCallback::response(const LocatorInfoPtr& locatorInfo, const Ice::ObjectPrxPtr& proxy) +{ + vector endpoints; + if(proxy) + { + ReferencePtr r = proxy->_getReference(); + if(_reference->isWellKnown() && !isSupported(_reference->getEncoding(), r->getEncoding())) + { + // + // If a well-known proxy and the returned proxy encoding + // isn't supported, we're done: there's no compatible + // endpoint we can use. + // + } + else if(!r->isIndirect()) + { + endpoints = r->getEndpoints(); + } + else if(_reference->isWellKnown() && !r->isWellKnown()) + { + // + // We're resolving the endpoints of a well-known object and the proxy returned + // by the locator is an indirect proxy. We now need to resolve the endpoints + // of this indirect proxy. + // + if(_reference->getInstance()->traceLevels()->location >= 1) + { + locatorInfo->trace("retrieved adapter for well-known object from locator, adding to locator cache", + _reference, r); + } + locatorInfo->getEndpoints(r, _reference, _ttl, _callback); + return; + } + } + + if(_reference->getInstance()->traceLevels()->location >= 1) + { + locatorInfo->getEndpointsTrace(_reference, endpoints, false); + } + if(_callback) + { + _callback->setEndpoints(endpoints, false); + } +} + +void +IceInternal::LocatorInfo::RequestCallback::exception(const LocatorInfoPtr& locatorInfo, const Ice::Exception& exc) +{ + try + { + locatorInfo->getEndpointsException(_reference, exc); // This throws. + } + catch(const Ice::LocalException& ex) + { + if(_callback) + { + _callback->setException(ex); + } + } +} + +IceInternal::LocatorInfo::RequestCallback::RequestCallback(const ReferencePtr& ref, + int ttl, + const GetEndpointsCallbackPtr& cb) : + _reference(ref), _ttl(ttl), _callback(cb) +{ +} + +void +IceInternal::LocatorInfo::Request::addCallback(const ReferencePtr& ref, + const ReferencePtr& wellKnownRef, + int ttl, + const GetEndpointsCallbackPtr& cb) +{ + RequestCallbackPtr callback = new RequestCallback(ref, ttl, cb); + { + IceUtil::Monitor::Lock sync(_monitor); + if(!_response && !_exception) + { + _callbacks.push_back(callback); + if(wellKnownRef) // This request is to resolve the endpoints of a cached well-known object reference + { + _wellKnownRefs.push_back(wellKnownRef); + } + if(!_sent) + { + _sent = true; + sync.release(); + send(); // send() might call exception() from this thread so we need to release the mutex. + } + return; + } + } + + if(_response) + { + callback->response(_locatorInfo, _proxy); + } + else + { + assert(_exception); + callback->exception(_locatorInfo, *_exception); + } +} + +IceInternal::LocatorInfo::Request::Request(const LocatorInfoPtr& locatorInfo, const ReferencePtr& ref) : + _locatorInfo(locatorInfo), _reference(ref), _sent(false), _response(false) +{ +} + +void +IceInternal::LocatorInfo::Request::response(const Ice::ObjectPrxPtr& proxy) +{ + { + IceUtil::Monitor::Lock sync(_monitor); + _locatorInfo->finishRequest(_reference, _wellKnownRefs, proxy, false); + _response = true; + _proxy = proxy; + _monitor.notifyAll(); + } + for(vector::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) + { + (*p)->response(_locatorInfo, proxy); + } +} + +void +IceInternal::LocatorInfo::Request::exception(const Ice::Exception& ex) +{ + { + IceUtil::Monitor::Lock sync(_monitor); + _locatorInfo->finishRequest(_reference, _wellKnownRefs, 0, dynamic_cast(&ex)); + + ICE_SET_EXCEPTION_FROM_CLONE(_exception, ex.ice_clone()); + _monitor.notifyAll(); + } + for(vector::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) + { + (*p)->exception(_locatorInfo, ex); + } +} + +IceInternal::LocatorInfo::LocatorInfo(const LocatorPrxPtr& locator, const LocatorTablePtr& table, bool background) : + _locator(locator), + _table(table), + _background(background) +{ + assert(_locator); + assert(_table); +} + +void +IceInternal::LocatorInfo::destroy() +{ + IceUtil::Mutex::Lock sync(*this); + + _locatorRegistry = 0; + _table->clear(); +} + +bool +IceInternal::LocatorInfo::operator==(const LocatorInfo& rhs) const +{ + return Ice::targetEqualTo(_locator, rhs._locator); +} + +bool +IceInternal::LocatorInfo::operator<(const LocatorInfo& rhs) const +{ + return Ice::targetLess(_locator, rhs._locator); +} + +LocatorRegistryPrxPtr +IceInternal::LocatorInfo::getLocatorRegistry() +{ + { + IceUtil::Mutex::Lock sync(*this); + if(_locatorRegistry) + { + return _locatorRegistry; + } + } + + // + // Do not make locator calls from within sync. + // + LocatorRegistryPrxPtr locatorRegistry = _locator->getRegistry(); + if(!locatorRegistry) + { + return 0; + } + + { + IceUtil::Mutex::Lock sync(*this); + + // + // The locator registry can't be located. We use ordered + // endpoint selection in case the locator returned a proxy + // with some endpoints which are prefered to be tried first. + // + _locatorRegistry = locatorRegistry->ice_locator(0)->ice_endpointSelection(Ice::ICE_ENUM(EndpointSelectionType, Ordered)); + return _locatorRegistry; + } +} + +void +IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, + const ReferencePtr& wellKnownRef, + int ttl, + const GetEndpointsCallbackPtr& callback) +{ + assert(ref->isIndirect()); + vector endpoints; + if(!ref->isWellKnown()) + { + if(!_table->getAdapterEndpoints(ref->getAdapterId(), ttl, endpoints)) + { + if(_background && !endpoints.empty()) + { + getAdapterRequest(ref)->addCallback(ref, wellKnownRef, ttl, 0); + } + else + { + getAdapterRequest(ref)->addCallback(ref, wellKnownRef, ttl, callback); + return; + } + } + } + else + { + ReferencePtr r; + if(!_table->getObjectReference(ref->getIdentity(), ttl, r)) + { + if(_background && r) + { + getObjectRequest(ref)->addCallback(ref, 0, ttl, 0); + } + else + { + getObjectRequest(ref)->addCallback(ref, 0, ttl, callback); + return; + } + } + + if(!r->isIndirect()) + { + endpoints = r->getEndpoints(); + } + else if(!r->isWellKnown()) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + trace("found adapter for well-known object in locator cache", ref, r); + } + getEndpoints(r, ref, ttl, callback); + return; + } + } + + assert(!endpoints.empty()); + if(ref->getInstance()->traceLevels()->location >= 1) + { + getEndpointsTrace(ref, endpoints, true); + } + if(callback) + { + callback->setEndpoints(endpoints, true); + } +} + +void +IceInternal::LocatorInfo::clearCache(const ReferencePtr& ref) +{ + assert(ref->isIndirect()); + + if(!ref->isWellKnown()) + { + vector endpoints = _table->removeAdapterEndpoints(ref->getAdapterId()); + + if(!endpoints.empty() && ref->getInstance()->traceLevels()->location >= 2) + { + trace("removed endpoints for adapter from locator cache", ref, endpoints); + } + } + else + { + ReferencePtr r = _table->removeObjectReference(ref->getIdentity()); + if(r) + { + if(!r->isIndirect()) + { + if(ref->getInstance()->traceLevels()->location >= 2) + { + trace("removed endpoints for well-known object from locator cache", ref, r->getEndpoints()); + } + } + else if(!r->isWellKnown()) + { + if(ref->getInstance()->traceLevels()->location >= 2) + { + trace("removed adapter for well-known object from locator cache", ref, r); + } + clearCache(r); + } + } + } +} + +void +IceInternal::LocatorInfo::getEndpointsException(const ReferencePtr& ref, const Ice::Exception& exc) +{ + assert(ref->isIndirect()); + + try + { + exc.ice_throw(); + } + catch(const AdapterNotFoundException&) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, + ref->getInstance()->traceLevels()->locationCat); + out << "adapter not found" << "\n"; + out << "adapter = " << ref->getAdapterId(); + } + + throw NotRegisteredException(__FILE__, __LINE__, "object adapter", ref->getAdapterId()); + } + catch(const ObjectNotFoundException&) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, + ref->getInstance()->traceLevels()->locationCat); + out << "object not found" << "\n"; + out << "object = " << Ice::identityToString(ref->getIdentity(), + ref->getInstance()->toStringMode()); + } + + throw NotRegisteredException(__FILE__, __LINE__, "object", + Ice::identityToString(ref->getIdentity(), ref->getInstance()->toStringMode())); + } + catch(const NotRegisteredException&) + { + throw; + } + catch(const LocalException& ex) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "couldn't contact the locator to retrieve endpoints\n"; + if(ref->getAdapterId().empty()) + { + out << "well-known proxy = " << ref->toString() << "\n"; + } + else + { + out << "adapter = " << ref->getAdapterId() << "\n"; + } + out << "reason = " << ex; + } + throw; + } +} + +void +IceInternal::LocatorInfo::getEndpointsTrace(const ReferencePtr& ref, + const vector& endpoints, + bool cached) +{ + if(!endpoints.empty()) + { + if(cached) + { + if(ref->isWellKnown()) + { + trace("found endpoints for well-known proxy in locator cache", ref, endpoints); + } + else + { + trace("found endpoints for adapter in locator cache", ref, endpoints); + } + } + else + { + if(ref->isWellKnown()) + { + trace("retrieved endpoints for well-known proxy from locator, adding to locator cache", ref, endpoints); + } + else + { + trace("retrieved endpoints for adapter from locator, adding to locator cache", ref, endpoints); + } + } + } + else + { + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "no endpoints configured for "; + if(ref->getAdapterId().empty()) + { + out << "well-known object\n"; + out << "well-known proxy = " << ref->toString(); + } + else + { + out << "adapter\n"; + out << "adapter = " << ref->getAdapterId(); + } + } +} + +void +IceInternal::LocatorInfo::trace(const string& msg, const ReferencePtr& ref, const vector& endpoints) +{ + assert(ref->isIndirect()); + + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << msg << '\n'; + if(!ref->isWellKnown()) + { + out << "adapter = " << ref->getAdapterId() << '\n'; + } + else + { + out << "well-known proxy = " << ref->toString() << '\n'; + } + + const char* sep = endpoints.size() > 1 ? ":" : ""; + ostringstream o; +#ifdef ICE_CPP11_COMPILER + transform(endpoints.begin(), endpoints.end(), ostream_iterator(o, sep), + [](const EndpointPtr& endpoint) + { + return endpoint->toString(); + }); +#else + transform(endpoints.begin(), endpoints.end(), ostream_iterator(o, sep), + Ice::constMemFun(&Endpoint::toString)); +#endif + out << "endpoints = " << o.str(); +} + +void +IceInternal::LocatorInfo::trace(const string& msg, const ReferencePtr& ref, const ReferencePtr& resolved) +{ + assert(ref->isWellKnown()); + + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << msg << '\n'; + out << "well-known proxy = " << ref->toString() << '\n'; + out << "adapter = " << resolved->getAdapterId(); +} + +IceInternal::LocatorInfo::RequestPtr +IceInternal::LocatorInfo::getAdapterRequest(const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "searching for adapter by id\nadapter = " << ref->getAdapterId(); + } + + map::const_iterator p = _adapterRequests.find(ref->getAdapterId()); + if(p != _adapterRequests.end()) + { + return p->second; + } + + RequestPtr request = new AdapterRequest(this, ref); + _adapterRequests.insert(make_pair(ref->getAdapterId(), request)); + return request; +} + +IceInternal::LocatorInfo::RequestPtr +IceInternal::LocatorInfo::getObjectRequest(const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "searching for well-known object\nwell-known proxy = " << ref->toString(); + } + + map::const_iterator p = _objectRequests.find(ref->getIdentity()); + if(p != _objectRequests.end()) + { + return p->second; + } + RequestPtr request = new ObjectRequest(this, ref); + _objectRequests.insert(make_pair(ref->getIdentity(), request)); + return request; +} + +void +IceInternal::LocatorInfo::finishRequest(const ReferencePtr& ref, + const vector& wellKnownRefs, + const Ice::ObjectPrxPtr& proxy, + bool notRegistered) +{ + if(!proxy || proxy->_getReference()->isIndirect()) + { + // + // Remove the cached references of well-known objects for which we tried + // to resolved the endpoints if these endpoints are empty. + // + for(vector::const_iterator q = wellKnownRefs.begin(); q != wellKnownRefs.end(); ++q) + { + _table->removeObjectReference((*q)->getIdentity()); + } + } + + if(!ref->isWellKnown()) + { + if(proxy && !proxy->_getReference()->isIndirect()) // Cache the adapter endpoints. + { + _table->addAdapterEndpoints(ref->getAdapterId(), proxy->_getReference()->getEndpoints()); + } + else if(notRegistered) // If the adapter isn't registered anymore, remove it from the cache. + { + _table->removeAdapterEndpoints(ref->getAdapterId()); + } + + IceUtil::Mutex::Lock sync(*this); + assert(_adapterRequests.find(ref->getAdapterId()) != _adapterRequests.end()); + _adapterRequests.erase(ref->getAdapterId()); + } + else + { + if(proxy && !proxy->_getReference()->isWellKnown()) // Cache the well-known object reference. + { + _table->addObjectReference(ref->getIdentity(), proxy->_getReference()); + } + else if(notRegistered) // If the well-known object isn't registered anymore, remove it from the cache. + { + _table->removeObjectReference(ref->getIdentity()); + } + + IceUtil::Mutex::Lock sync(*this); + assert(_objectRequests.find(ref->getIdentity()) != _objectRequests.end()); + _objectRequests.erase(ref->getIdentity()); + } +} diff --git a/Sources/IceCpp/Logger.cpp b/Sources/IceCpp/Logger.cpp new file mode 100644 index 0000000..5e91e40 --- /dev/null +++ b/Sources/IceCpp/Logger.cpp @@ -0,0 +1,73 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Logger.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::Logger::~Logger() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::Logger::~Logger() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Logger* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/LoggerAdminI.cpp b/Sources/IceCpp/LoggerAdminI.cpp new file mode 100644 index 0000000..d293311 --- /dev/null +++ b/Sources/IceCpp/LoggerAdminI.cpp @@ -0,0 +1,956 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace Ice; +using namespace std; + +namespace +{ + +const char* traceCategory = "Admin.Logger"; + +class LoggerAdminI : public Ice::LoggerAdmin +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + LoggerAdminI(const PropertiesPtr&); + +#ifdef ICE_CPP11_MAPPING + virtual void attachRemoteLogger(shared_ptr, LogMessageTypeSeq, + StringSeq, Int, const Current&); + + virtual bool detachRemoteLogger(shared_ptr, const Current&); + + virtual LogMessageSeq getLog(LogMessageTypeSeq, StringSeq, Int, string&, const Current&); +#else + virtual void attachRemoteLogger(const RemoteLoggerPrx&, const LogMessageTypeSeq&, + const StringSeq&, Int, const Current&); + + virtual bool detachRemoteLogger(const RemoteLoggerPrx&, const Current&); + + virtual LogMessageSeq getLog(const LogMessageTypeSeq&, const StringSeq&, Int, string&, const Current&); +#endif + + void destroy(); + + vector log(const LogMessage&); + + void deadRemoteLogger(const RemoteLoggerPrxPtr&, const LoggerPtr&, const LocalException&, const string&); + + int getTraceLevel() const + { + return _traceLevel; + } + +private: + + bool removeRemoteLogger(const RemoteLoggerPrxPtr&); + +#ifndef ICE_CPP11_MAPPING // C++98 mapping begin_init callback + void initCompleted(const AsyncResultPtr&); +#endif + + IceUtil::Mutex _mutex; + list _queue; + int _logCount; // non-trace messages + const int _maxLogCount; + int _traceCount; + const int _maxTraceCount; + const int _traceLevel; + + list::iterator _oldestTrace; + list::iterator _oldestLog; + + struct ObjectIdentityCompare + { + bool operator()(const RemoteLoggerPrxPtr& lhs, const RemoteLoggerPrxPtr& rhs) const + { + // + // Caller should make sure that proxies are never null + // + assert(lhs != 0 && rhs != 0); + + return lhs->ice_getIdentity() < rhs->ice_getIdentity(); + } + }; + + struct Filters + { + Filters(const LogMessageTypeSeq& m, const StringSeq& c) : + messageTypes(m.begin(), m.end()), + traceCategories(c.begin(), c.end()) + { + } + + const set messageTypes; + const set traceCategories; + }; + + typedef map RemoteLoggerMap; + + struct GetRemoteLoggerMapKey + { + RemoteLoggerMap::key_type + operator()(const RemoteLoggerMap::value_type& val) + { + return val.first; + } + }; + + RemoteLoggerMap _remoteLoggerMap; + CommunicatorPtr _sendLogCommunicator; + bool _destroyed; +}; +ICE_DEFINE_PTR(LoggerAdminIPtr, LoggerAdminI); + +class Job : public IceUtil::Shared +{ +public: + + Job(const vector& r, const LogMessage& l) : + remoteLoggers(r), + logMessage(l) + { + } + + const vector remoteLoggers; + const LogMessage logMessage; +}; +typedef IceUtil::Handle JobPtr; + +class LoggerAdminLoggerI : public IceInternal::LoggerAdminLogger +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif + +{ +public: + + LoggerAdminLoggerI(const PropertiesPtr&, const LoggerPtr&); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual LoggerPtr cloneWithPrefix(const std::string&); + + virtual ObjectPtr getFacet() const; + + virtual void destroy(); + + const LoggerPtr& getLocalLogger() const + { + return _localLogger; + } + + void run(); + +private: + + void log(const LogMessage&); +#ifndef ICE_CPP11_MAPPING // C++98 mapping begin_log callback + void logCompleted(const AsyncResultPtr&); +#endif + + LoggerPtr _localLogger; + const LoggerAdminIPtr _loggerAdmin; + + IceUtil::Monitor _monitor; + + bool _destroyed; + IceUtil::ThreadPtr _sendLogThread; + std::deque _jobQueue; +}; +ICE_DEFINE_PTR(LoggerAdminLoggerIPtr, LoggerAdminLoggerI); + +class SendLogThread : public IceUtil::Thread +{ +public: + + SendLogThread(const LoggerAdminLoggerIPtr&); + + virtual void run(); + +private: + + LoggerAdminLoggerIPtr _logger; +}; + +// +// Helper functions +// + +// +// Filter out messages from in/out logMessages list +// +void +filterLogMessages(LogMessageSeq& logMessages, const set& messageTypes, + const set& traceCategories, Int messageMax) +{ + assert(!logMessages.empty() && messageMax != 0); + + // + // Filter only if one of the 3 filters is set; messageMax < 0 means "give me all" + // that match the other filters, if any. + // + if(!messageTypes.empty() || !traceCategories.empty() || messageMax > 0) + { + int count = 0; + LogMessageSeq::reverse_iterator p = logMessages.rbegin(); + while(p != logMessages.rend()) + { + bool keepIt = false; + if(messageTypes.empty() || messageTypes.count(p->type) != 0) + { + if(p->type != ICE_ENUM(LogMessageType, TraceMessage) || traceCategories.empty() || + traceCategories.count(p->traceCategory) != 0) + { + keepIt = true; + } + } + + if(keepIt) + { + ++p; + ++count; + if(messageMax > 0 && count >= messageMax) + { + // + // p.base() points to p "+1"; note that this invalidates p. + // + logMessages.erase(logMessages.begin(), p.base()); + break; // while + } + } + else + { + ++p; + // + // p.base() points to p "+1"; the erase invalidates p so we + // need to rebuild it + // + p = LogMessageSeq::reverse_iterator(logMessages.erase(p.base())); + } + } + } + // else, don't need any filtering +} + +// +// Change this proxy's communicator, while keeping its invocation timeout +// +RemoteLoggerPrxPtr +changeCommunicator(const RemoteLoggerPrxPtr& prx, const CommunicatorPtr& communicator) +{ + if(prx == 0) + { + return 0; + } + + RemoteLoggerPrxPtr result = ICE_UNCHECKED_CAST(RemoteLoggerPrx, communicator->stringToProxy(prx->ice_toString())); + + return result->ice_invocationTimeout(prx->ice_getInvocationTimeout()); +} + +// +// Copies a set of properties +// +void +copyProperties(const string& prefix, const PropertiesPtr& from, const PropertiesPtr& to) +{ + PropertyDict dict = from->getPropertiesForPrefix(prefix); + for(PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + to->setProperty(p->first, p->second); + } +} + +// +// Create communicator used to send logs +// +CommunicatorPtr +createSendLogCommunicator(const CommunicatorPtr& communicator, const LoggerPtr& logger) +{ + InitializationData initData; + initData.logger = logger; + initData.properties = createProperties(); + + PropertiesPtr mainProps = communicator->getProperties(); + + copyProperties("Ice.Default.Locator", mainProps, initData.properties); + copyProperties("Ice.Plugin.IceSSL", mainProps, initData.properties); + copyProperties("IceSSL.", mainProps, initData.properties); + + StringSeq extraProps = mainProps->getPropertyAsList("Ice.Admin.Logger.Properties"); + + if(!extraProps.empty()) + { + for(vector::iterator p = extraProps.begin(); p != extraProps.end(); ++p) + { + if(p->find("--") != 0) + { + *p = "--" + *p; + } + } + initData.properties->parseCommandLineOptions("", extraProps); + } + + return initialize(initData); +} + +// +// LoggerAdminI +// + +LoggerAdminI::LoggerAdminI(const PropertiesPtr& props) : + _logCount(0), + _maxLogCount(props->getPropertyAsIntWithDefault("Ice.Admin.Logger.KeepLogs", 100)), + _traceCount(0), + _maxTraceCount(props->getPropertyAsIntWithDefault("Ice.Admin.Logger.KeepTraces", 100)), + _traceLevel(props->getPropertyAsInt("Ice.Trace.Admin.Logger")), + _destroyed(false) +{ + _oldestLog = _queue.end(); + _oldestTrace = _queue.end(); +} + +void +#ifdef ICE_CPP11_MAPPING +LoggerAdminI::attachRemoteLogger(shared_ptr prx, + LogMessageTypeSeq messageTypes, + StringSeq categories, + Int messageMax, + const Current& current) +#else +LoggerAdminI::attachRemoteLogger(const RemoteLoggerPrx& prx, + const LogMessageTypeSeq& messageTypes, + const StringSeq& categories, + Int messageMax, + const Current& current) +#endif +{ + if(!prx) + { + return; // can't send this null RemoteLogger anything! + } + + // + // In C++, LoggerAdminI does not keep a "logger" data member to avoid a hard-to-break circular + // reference, so we retrieve the logger from Current + // + LoggerAdminLoggerIPtr logger = ICE_DYNAMIC_CAST(LoggerAdminLoggerI, current.adapter->getCommunicator()->getLogger()); + assert(logger); + + RemoteLoggerPrxPtr remoteLogger = prx->ice_twoway(); + + Filters filters(messageTypes, categories); + LogMessageSeq initLogMessages; + { + IceUtil::Mutex::Lock lock(_mutex); + + if(!_sendLogCommunicator) + { + if(_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + + _sendLogCommunicator = + createSendLogCommunicator(current.adapter->getCommunicator(), logger->getLocalLogger()); + } + + if(!_remoteLoggerMap.insert(make_pair(changeCommunicator(remoteLogger, _sendLogCommunicator), filters)).second) + { + if(_traceLevel > 0) + { + Trace trace(logger, traceCategory); + trace << "rejecting `" << remoteLogger << "' with RemoteLoggerAlreadyAttachedException"; + } + + throw RemoteLoggerAlreadyAttachedException(); + } + + if(messageMax != 0) + { + initLogMessages = _queue; // copy + } + } + + if(_traceLevel > 0) + { + Trace trace(logger, traceCategory); + trace << "attached `" << remoteLogger << "'"; + } + + if(!initLogMessages.empty()) + { + filterLogMessages(initLogMessages, filters.messageTypes, filters.traceCategories, messageMax); + } + +#ifdef ICE_CPP11_MAPPING + try + { + auto self = shared_from_this(); + remoteLogger->initAsync(logger->getPrefix(), initLogMessages, + [self, logger, remoteLogger]() + { + if(self->_traceLevel > 1) + { + Trace trace(logger, traceCategory); + trace << "init on `" << remoteLogger << "' completed successfully"; + } + }, + [self, logger, remoteLogger](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Ice::LocalException& le) + { + self->deadRemoteLogger(remoteLogger, logger, le, "init"); + } + }); + } + catch(const LocalException& ex) + { + deadRemoteLogger(remoteLogger, logger, ex, "init"); + throw; + } +#else + CallbackPtr initCompletedCb = newCallback(this, &LoggerAdminI::initCompleted); + try + { + remoteLogger->begin_init(logger->getPrefix(), initLogMessages, initCompletedCb, logger); + } + catch(const LocalException& ex) + { + deadRemoteLogger(remoteLogger, logger, ex, "init"); + throw; + } +#endif +} + +bool +#ifdef ICE_CPP11_MAPPING +LoggerAdminI::detachRemoteLogger(shared_ptr remoteLogger, const Current& current) +#else +LoggerAdminI::detachRemoteLogger(const RemoteLoggerPrx& remoteLogger, const Current& current) +#endif +{ + if(remoteLogger == 0) + { + return false; + } + + // + // No need to convert the proxy as we only use its identity + // + bool found = removeRemoteLogger(remoteLogger); + + if(_traceLevel > 0) + { + Trace trace(current.adapter->getCommunicator()->getLogger(), traceCategory); + if(found) + { + trace << "detached `" << remoteLogger << "'"; + } + else + { + trace << "cannot detach `" << remoteLogger << "': not found"; + } + } + + return found; +} + +LogMessageSeq +#ifdef ICE_CPP11_MAPPING +LoggerAdminI::getLog(LogMessageTypeSeq messageTypes, StringSeq categories, + Int messageMax, string& prefix, const Current& current) +#else +LoggerAdminI::getLog(const LogMessageTypeSeq& messageTypes, const StringSeq& categories, + Int messageMax, string& prefix, const Current& current) +#endif +{ + LogMessageSeq logMessages; + { + IceUtil::Mutex::Lock lock(_mutex); + + if(messageMax != 0) + { + logMessages = _queue; + } + } + + LoggerPtr logger = current.adapter->getCommunicator()->getLogger(); + prefix = logger->getPrefix(); + + if(!logMessages.empty()) + { + Filters filters(messageTypes, categories); + filterLogMessages(logMessages, filters.messageTypes, filters.traceCategories, messageMax); + } + + return logMessages; +} + +void +LoggerAdminI::destroy() +{ + CommunicatorPtr sendLogCommunicator; + { + IceUtil::Mutex::Lock lock(_mutex); + if(!_destroyed) + { + _destroyed = true; + sendLogCommunicator = _sendLogCommunicator; + _sendLogCommunicator = 0; + } + } + + // + // Destroy outside lock to avoid deadlock when there are outstanding two-way log calls sent to + // remote loggers + // + if(sendLogCommunicator) + { + sendLogCommunicator->destroy(); + } +} + +vector +LoggerAdminI::log(const LogMessage& logMessage) +{ + vector remoteLoggers; + + IceUtil::Mutex::Lock lock(_mutex); + + // + // Put message in _queue + // + if((logMessage.type != ICE_ENUM(LogMessageType, TraceMessage) && _maxLogCount > 0) || + (logMessage.type == ICE_ENUM(LogMessageType, TraceMessage) && _maxTraceCount > 0)) + { + list::iterator p = _queue.insert(_queue.end(), logMessage); + + if(logMessage.type != ICE_ENUM(LogMessageType, TraceMessage)) + { + assert(_maxLogCount > 0); + if(_logCount == _maxLogCount) + { + // + // Need to remove the oldest log from the queue + // + assert(_oldestLog != _queue.end()); + _oldestLog = _queue.erase(_oldestLog); + while(_oldestLog != _queue.end() && _oldestLog->type == ICE_ENUM(LogMessageType, TraceMessage)) + { + _oldestLog++; + } + assert(_oldestLog != _queue.end()); + } + else + { + assert(_logCount < _maxLogCount); + _logCount++; + if(_oldestLog == _queue.end()) + { + _oldestLog = p; + } + } + } + else + { + assert(_maxTraceCount > 0); + if(_traceCount == _maxTraceCount) + { + // + // Need to remove the oldest trace from the queue + // + assert(_oldestTrace != _queue.end()); + _oldestTrace = _queue.erase(_oldestTrace); + while(_oldestTrace != _queue.end() && _oldestTrace->type != ICE_ENUM(LogMessageType, TraceMessage)) + { + _oldestTrace++; + } + assert(_oldestTrace != _queue.end()); + } + else + { + assert(_traceCount < _maxTraceCount); + _traceCount++; + if(_oldestTrace == _queue.end()) + { + _oldestTrace = p; + } + } + } + + // + // Queue updated, now find which remote loggers want this message + // + for(RemoteLoggerMap::const_iterator q = _remoteLoggerMap.begin(); q != _remoteLoggerMap.end(); ++q) + { + const Filters& filters = q->second; + + if(filters.messageTypes.empty() || filters.messageTypes.count(logMessage.type) != 0) + { + if(logMessage.type != ICE_ENUM(LogMessageType, TraceMessage) || filters.traceCategories.empty() || + filters.traceCategories.count(logMessage.traceCategory) != 0) + { + remoteLoggers.push_back(q->first); + } + } + } + } + return remoteLoggers; +} + +void +LoggerAdminI::deadRemoteLogger(const RemoteLoggerPrxPtr& remoteLogger, + const LoggerPtr& logger, + const LocalException& ex, + const string& operation) +{ + // + // No need to convert remoteLogger as we only use its identity + // + if(removeRemoteLogger(remoteLogger)) + { + if(_traceLevel > 0) + { + Trace trace(logger, traceCategory); + trace << "detached `" << remoteLogger << "' because " << operation << " raised:\n" << ex; + } + } +} + +bool +LoggerAdminI::removeRemoteLogger(const RemoteLoggerPrxPtr& remoteLogger) +{ + IceUtil::Mutex::Lock lock(_mutex); + return _remoteLoggerMap.erase(remoteLogger) > 0; +} + +#ifndef ICE_CPP11_MAPPING +// +// begin_init callback method for C++98 mapping +// +void +LoggerAdminI::initCompleted(const AsyncResultPtr& r) +{ + RemoteLoggerPrxPtr remoteLogger = ICE_UNCHECKED_CAST(RemoteLoggerPrx, r->getProxy()); + + try + { + remoteLogger->end_init(r); + + if(_traceLevel > 1) + { + LoggerPtr logger = ICE_DYNAMIC_CAST(Logger, r->getCookie()); + Trace trace(logger, traceCategory); + trace << r->getOperation() << " on `" << remoteLogger << "' completed successfully"; + } + } + catch(const LocalException& ex) + { + deadRemoteLogger(remoteLogger, ICE_DYNAMIC_CAST(Logger, r->getCookie()), ex, r->getOperation()); + } +} +#endif + +// +// LoggerAdminLoggerI +// + +LoggerAdminLoggerI::LoggerAdminLoggerI(const PropertiesPtr& props, + const LoggerPtr& localLogger) : + _loggerAdmin(new LoggerAdminI(props)), + _destroyed(false) +{ + // + // There is currently no way to have a null local logger + // + assert(localLogger != 0); + + LoggerAdminLoggerI* wrapper = dynamic_cast(localLogger.get()); + if(wrapper) + { + // use the underlying local logger + _localLogger = wrapper->getLocalLogger(); + } + else + { + _localLogger = localLogger; + } +} + +void +LoggerAdminLoggerI::print(const string& message) +{ + LogMessage logMessage = { ICE_ENUM(LogMessageType, PrintMessage), IceUtil::Time::now().toMicroSeconds(), "", message }; + + _localLogger->print(message); + log(logMessage); +} + +void +LoggerAdminLoggerI::trace(const string& category, const string& message) +{ + LogMessage logMessage = { ICE_ENUM(LogMessageType, TraceMessage), IceUtil::Time::now().toMicroSeconds(), category, message }; + + _localLogger->trace(category, message); + log(logMessage); +} + +void +LoggerAdminLoggerI::warning(const string& message) +{ + LogMessage logMessage = { ICE_ENUM(LogMessageType, WarningMessage), IceUtil::Time::now().toMicroSeconds(), "", message }; + + _localLogger->warning(message); + log(logMessage); +} + +void +LoggerAdminLoggerI::error(const string& message) +{ + LogMessage logMessage = { ICE_ENUM(LogMessageType, ErrorMessage), IceUtil::Time::now().toMicroSeconds(), "", message }; + + _localLogger->error(message); + log(logMessage); +} + +string +LoggerAdminLoggerI::getPrefix() +{ + return _localLogger->getPrefix(); +} + +LoggerPtr +LoggerAdminLoggerI::cloneWithPrefix(const string& prefix) +{ + return _localLogger->cloneWithPrefix(prefix); +} + +ObjectPtr +LoggerAdminLoggerI::getFacet() const +{ + return _loggerAdmin; +} + +void +LoggerAdminLoggerI::log(const LogMessage& logMessage) +{ + const vector remoteLoggers = _loggerAdmin->log(logMessage); + + if(!remoteLoggers.empty()) + { + IceUtil::Monitor::Lock lock(_monitor); + + if(!_sendLogThread) + { + _sendLogThread = new SendLogThread(ICE_SHARED_FROM_THIS); + _sendLogThread->start(); + } + + _jobQueue.push_back(new Job(remoteLoggers, logMessage)); + _monitor.notifyAll(); + } +} + +void +LoggerAdminLoggerI::destroy() +{ + IceUtil::ThreadControl sendLogThreadControl; + bool joinThread = false; + { + IceUtil::Monitor::Lock lock(_monitor); + + if(_sendLogThread) + { + joinThread = true; + sendLogThreadControl = _sendLogThread->getThreadControl(); + _sendLogThread = 0; + _destroyed = true; + _monitor.notifyAll(); + } + } + + if(joinThread) + { + sendLogThreadControl.join(); + } + + // destroy sendLogCommunicator + _loggerAdmin->destroy(); +} + +void +LoggerAdminLoggerI::run() +{ + if(_loggerAdmin->getTraceLevel() > 1) + { + Trace trace(_localLogger, traceCategory); + trace << "send log thread started"; + } + +#ifndef ICE_CPP11_MAPPING + CallbackPtr logCompletedCb = newCallback(this, &LoggerAdminLoggerI::logCompleted); +#endif + + for(;;) + { + IceUtil::Monitor::Lock lock(_monitor); + while(!_destroyed && _jobQueue.empty()) + { + _monitor.wait(); + } + if(_destroyed) + { + break; // for(;;) + } + + assert(!_jobQueue.empty()); + JobPtr job = _jobQueue.front(); + _jobQueue.pop_front(); + lock.release(); + + for(vector::const_iterator p = job->remoteLoggers.begin(); p != job->remoteLoggers.end(); ++p) + { + if(_loggerAdmin->getTraceLevel() > 1) + { + Trace trace(_localLogger, traceCategory); + trace << "sending log message to `" << *p << "'"; + } + + try + { +#ifdef ICE_CPP11_MAPPING + RemoteLoggerPrxPtr remoteLogger = *p; + auto self = shared_from_this(); + remoteLogger->logAsync(job->logMessage, + [self, remoteLogger]() + { + if(self->_loggerAdmin->getTraceLevel() > 1) + { + Trace trace(self->_localLogger, traceCategory); + trace << "log on `" << remoteLogger << "' completed successfully"; + } + }, + [self, remoteLogger](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const CommunicatorDestroyedException&) + { + // expected if there are outstanding calls during communicator destruction + } + catch(const LocalException& ex) + { + self->_loggerAdmin->deadRemoteLogger(remoteLogger, self->_localLogger, ex, "log"); + } + }); +#else + // + // *p is a proxy associated with the _sendLogCommunicator + // + (*p)->begin_log(job->logMessage, logCompletedCb); +#endif + } + catch(const LocalException& ex) + { + _loggerAdmin->deadRemoteLogger(*p, _localLogger, ex, "log"); + } + } + } + + if(_loggerAdmin->getTraceLevel() > 1) + { + Trace trace(_localLogger, traceCategory); + trace << "send log thread completed"; + } +} + +#ifndef ICE_CPP11_MAPPING +// +// begin_log callback for C++98 mapping +// +void +LoggerAdminLoggerI::logCompleted(const AsyncResultPtr& r) +{ + RemoteLoggerPrxPtr remoteLogger = ICE_UNCHECKED_CAST(RemoteLoggerPrx, r->getProxy()); + + try + { + remoteLogger->end_log(r); + + if(_loggerAdmin->getTraceLevel() > 1) + { + Trace trace(_localLogger, traceCategory); + trace << r->getOperation() << " on `" << remoteLogger << "' completed successfully"; + } + } + catch(const CommunicatorDestroyedException&) + { + // expected if there are outstanding calls during communicator destruction + } + catch(const LocalException& ex) + { + _loggerAdmin->deadRemoteLogger(remoteLogger, _localLogger, ex, r->getOperation()); + } +} +#endif + +// +// SendLogThread +// + +SendLogThread::SendLogThread(const LoggerAdminLoggerIPtr& logger) : + IceUtil::Thread("Ice.SendLogThread"), + _logger(logger) +{ +} + +void +SendLogThread::run() +{ + _logger->run(); +} +} + +// +// createLoggerAdminLogger +// + +namespace IceInternal +{ + +LoggerAdminLoggerPtr +createLoggerAdminLogger(const PropertiesPtr& props, + const LoggerPtr& localLogger) +{ + return ICE_MAKE_SHARED(LoggerAdminLoggerI, props, localLogger); +} + +} diff --git a/Sources/IceCpp/LoggerF.cpp b/Sources/IceCpp/LoggerF.cpp new file mode 100644 index 0000000..094ffce --- /dev/null +++ b/Sources/IceCpp/LoggerF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LoggerF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/LoggerI.cpp b/Sources/IceCpp/LoggerI.cpp new file mode 100644 index 0000000..75d4623 --- /dev/null +++ b/Sources/IceCpp/LoggerI.cpp @@ -0,0 +1,259 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __IBMCPP__ +// Work-around for xlC visibility bug +// See "ifstream::tellg visibility error" thread on IBM xlC forum +extern template class std::fpos; +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceUtilInternal; + +namespace +{ + +IceUtil::Mutex* outputMutex = 0; + +class Init +{ +public: + + Init() + { + outputMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete outputMutex; + outputMutex = 0; + } +}; + +Init init; + +// +// Timeout in milliseconds after which rename will be attempted +// in case of failures renaming files. That is set to 5 minutes. +// +const IceUtil::Time retryTimeout = IceUtil::Time::seconds(5 * 60); + +} + +Ice::LoggerI::LoggerI(const string& prefix, const string& file, + bool convert, size_t sizeMax) : + _prefix(prefix), + _convert(convert), + _converter(getProcessStringConverter()), + _sizeMax(sizeMax) +{ + if(!prefix.empty()) + { + _formattedPrefix = prefix + ": "; + } + + if(!file.empty()) + { + _file = file; + _out.open(IceUtilInternal::streamFilename(file).c_str(), fstream::out | fstream::app); + if(!_out.is_open()) + { + throw InitializationException(__FILE__, __LINE__, "FileLogger: cannot open " + _file); + } + + if(_sizeMax > 0) + { + _out.seekp(0, _out.end); + } + } +} + +Ice::LoggerI::~LoggerI() +{ + if(_out.is_open()) + { + _out.close(); + } +} + +void +Ice::LoggerI::print(const string& message) +{ + write(message, false); +} + +void +Ice::LoggerI::trace(const string& category, const string& message) +{ + string s = "-- " + IceUtil::Time::now().toDateTime() + " " + _formattedPrefix; + if(!category.empty()) + { + s += category + ": "; + } + s += message; + + write(s, true); +} + +void +Ice::LoggerI::warning(const string& message) +{ + write("-! " + IceUtil::Time::now().toDateTime() + " " + _formattedPrefix + "warning: " + message, true); +} + +void +Ice::LoggerI::error(const string& message) +{ + write("!! " + IceUtil::Time::now().toDateTime() + " " + _formattedPrefix + "error: " + message, true); +} + +string +Ice::LoggerI::getPrefix() +{ + return _prefix; +} + +LoggerPtr +Ice::LoggerI::cloneWithPrefix(const std::string& prefix) +{ + IceUtilInternal::MutexPtrLock sync(outputMutex); // for _sizeMax + return ICE_MAKE_SHARED(LoggerI, prefix, _file, _convert, _sizeMax); +} + +void +Ice::LoggerI::write(const string& message, bool indent) +{ + IceUtilInternal::MutexPtrLock sync(outputMutex); + + string s = message; + + if(indent) + { + string::size_type idx = 0; + while((idx = s.find("\n", idx)) != string::npos) + { + s.insert(idx + 1, " "); + ++idx; + } + } + + if(_out.is_open()) + { + if(_sizeMax > 0) + { + // + // If file size + message size exceeds max size we archive the log file, + // but we do not archive empty files or truncate messages. + // + size_t sz = static_cast(_out.tellp()); + if(sz > 0 && sz + message.size() >= _sizeMax && _nextRetry <= IceUtil::Time::now()) + { + string basename = _file; + string ext; + + size_t i = basename.rfind("."); + if(i != string::npos && i + 1 < basename.size()) + { + ext = basename.substr(i + 1); + basename = basename.substr(0, i); + } + _out.close(); + + int id = 0; + string archive; + string date = IceUtil::Time::now().toString("%Y%m%d-%H%M%S"); + while(true) + { + ostringstream oss; + oss << basename << "-" << date; + if(id > 0) + { + oss << "-" << id; + } + if(!ext.empty()) + { + oss << "." << ext; + } + if(IceUtilInternal::fileExists(oss.str())) + { + id++; + continue; + } + archive = oss.str(); + break; + } + + int err = IceUtilInternal::rename(_file, archive); + + _out.open(IceUtilInternal::streamFilename(_file).c_str(), fstream::out | fstream::app); + + if(err) + { + _nextRetry = IceUtil::Time::now() + retryTimeout; + + // + // We temporarily set the maximum size to 0 to ensure there isn't more rename attempts + // in the nested error call. + // + size_t sizeMax = _sizeMax; + _sizeMax = 0; + sync.release(); + error("FileLogger: cannot rename `" + _file + "'\n" + IceUtilInternal::lastErrorToString()); + sync.acquire(); + _sizeMax = sizeMax; + } + else + { + _nextRetry = IceUtil::Time(); + } + + if(!_out.is_open()) + { + sync.release(); + error("FileLogger: cannot open `" + _file + "':\nlog messages will be sent to stderr"); + write(message, indent); + return; + } } + } + _out << s << endl; + } + else + { +#if defined(_WIN32) + // + // Convert the message from the native narrow string encoding to the console + // code page encoding for printing. If the _convert member is set to false + // we don't do any conversion. + // + if(!_convert) + { + // + // Use fprintf_s to avoid encoding conversion when stderr is connected + // to Windows console. When _convert is set to false we always output + // UTF-8 encoded messages. + // + fprintf_s(stderr, "%s\n", nativeToUTF8(s, _converter).c_str()); + fflush(stderr); + } + else + { + consoleErr << s << endl; + } +#else + cerr << s << endl; +#endif + } +} diff --git a/Sources/IceCpp/LoggerUtil.cpp b/Sources/IceCpp/LoggerUtil.cpp new file mode 100644 index 0000000..030ca97 --- /dev/null +++ b/Sources/IceCpp/LoggerUtil.cpp @@ -0,0 +1,100 @@ + +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include + +using namespace std; + +namespace IceUtilInternal +{ + +extern bool printStackTraces; + +} + +string +Ice::LoggerOutputBase::str() const +{ + return _os.str(); +} + +ostringstream& +Ice::LoggerOutputBase::_stream() +{ + return _os; +} + +Ice::LoggerOutputBase& +Ice::operator<<(Ice::LoggerOutputBase& out, ios_base& (*val)(ios_base&)) +{ + out._stream() << val; + return out; +} + +Ice::LoggerOutputBase& +Ice::loggerInsert(Ice::LoggerOutputBase& out, const IceUtil::Exception& ex) +{ + if(IceUtilInternal::printStackTraces) + { + out._stream() << ex.what() << '\n' << ex.ice_stackTrace(); + } + else + { + out._stream() << ex.what(); + } + return out; +} + +Ice::Trace::Trace(const LoggerPtr& logger, const string& category) : + _logger(logger), + _category(category) +{ +} + +Ice::Trace::~Trace() +{ + flush(); +} + +void +Ice::Trace::flush() +{ + string s = _stream().str(); + if(!s.empty()) + { + _logger->trace(_category, s); + } + _stream().str(""); +} + +Ice::LoggerPlugin::LoggerPlugin(const CommunicatorPtr& communicator, const LoggerPtr& logger) +{ + if(communicator == 0) + { + throw PluginInitializationException(__FILE__, __LINE__, "Communicator cannot be null"); + } + + if(logger == 0) + { + throw PluginInitializationException(__FILE__, __LINE__, "Logger cannot be null"); + } + + IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); + instance->setLogger(logger); +} + +void +Ice::LoggerPlugin::initialize() +{ +} + +void +Ice::LoggerPlugin::destroy() +{ +} diff --git a/Sources/IceCpp/Metrics.cpp b/Sources/IceCpp/Metrics.cpp new file mode 100644 index 0000000..1860b13 --- /dev/null +++ b/Sources/IceCpp/Metrics.cpp @@ -0,0 +1,2352 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Metrics.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::Metrics> iceC_IceMX_Metrics_init("::IceMX::Metrics"); + +const ::IceInternal::DefaultUserExceptionFactoryInit<::IceMX::UnknownMetricsView> iceC_IceMX_UnknownMetricsView_init("::IceMX::UnknownMetricsView"); + +const ::std::string iceC_IceMX_MetricsAdmin_ids[2] = +{ + "::Ice::Object", + "::IceMX::MetricsAdmin" +}; +const ::std::string iceC_IceMX_MetricsAdmin_ops[] = +{ + "disableMetricsView", + "enableMetricsView", + "getMapMetricsFailures", + "getMetricsFailures", + "getMetricsView", + "getMetricsViewNames", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsViewNames_name = "getMetricsViewNames"; +const ::std::string iceC_IceMX_MetricsAdmin_enableMetricsView_name = "enableMetricsView"; +const ::std::string iceC_IceMX_MetricsAdmin_disableMetricsView_name = "disableMetricsView"; +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsView_name = "getMetricsView"; +const ::std::string iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name = "getMapMetricsFailures"; +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsFailures_name = "getMetricsFailures"; + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::ThreadMetrics> iceC_IceMX_ThreadMetrics_init("::IceMX::ThreadMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::DispatchMetrics> iceC_IceMX_DispatchMetrics_init("::IceMX::DispatchMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::ChildInvocationMetrics> iceC_IceMX_ChildInvocationMetrics_init("::IceMX::ChildInvocationMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::CollocatedMetrics> iceC_IceMX_CollocatedMetrics_init("::IceMX::CollocatedMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::RemoteMetrics> iceC_IceMX_RemoteMetrics_init("::IceMX::RemoteMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::InvocationMetrics> iceC_IceMX_InvocationMetrics_init("::IceMX::InvocationMetrics"); + +const ::IceInternal::DefaultValueFactoryInit<::IceMX::ConnectionMetrics> iceC_IceMX_ConnectionMetrics_init("::IceMX::ConnectionMetrics"); + +} + +IceMX::UnknownMetricsView::~UnknownMetricsView() +{ +} + +const ::std::string& +IceMX::UnknownMetricsView::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::UnknownMetricsView"; + return typeId; +} + +bool +IceMX::MetricsAdmin::ice_isA(::std::string s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_MetricsAdmin_ids, iceC_IceMX_MetricsAdmin_ids + 2, s); +} + +::std::vector<::std::string> +IceMX::MetricsAdmin::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector<::std::string>(&iceC_IceMX_MetricsAdmin_ids[0], &iceC_IceMX_MetricsAdmin_ids[2]); +} + +::std::string +IceMX::MetricsAdmin::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::MetricsAdmin::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::MetricsAdmin"; + return typeId; +} + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsViewNames(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + inS.readEmptyParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + ::Ice::StringSeq iceP_disabledViews; + ::Ice::StringSeq ret = this->getMetricsViewNames(iceP_disabledViews, current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(iceP_disabledViews, ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_enableMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_name; + istr->readAll(iceP_name); + inS.endReadParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + this->enableMetricsView(::std::move(iceP_name), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_disableMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_name; + istr->readAll(iceP_name); + inS.endReadParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + this->disableMetricsView(::std::move(iceP_name), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_view; + istr->readAll(iceP_view); + inS.endReadParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + long long int iceP_timestamp; + MetricsView ret = this->getMetricsView(::std::move(iceP_view), iceP_timestamp, current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(iceP_timestamp, ret); + ostr->writePendingValues(); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMapMetricsFailures(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_view; + ::std::string iceP_map; + istr->readAll(iceP_view, iceP_map); + inS.endReadParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + MetricsFailuresSeq ret = this->getMapMetricsFailures(::std::move(iceP_view), ::std::move(iceP_map), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsFailures(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_view; + ::std::string iceP_map; + ::std::string iceP_id; + istr->readAll(iceP_view, iceP_map, iceP_id); + inS.endReadParams(); + inS.setFormat(::Ice::FormatType::SlicedFormat); + MetricsFailures ret = this->getMetricsFailures(::std::move(iceP_view), ::std::move(iceP_map), ::std::move(iceP_id), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceMX_MetricsAdmin_ops, iceC_IceMX_MetricsAdmin_ops + 10, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceMX_MetricsAdmin_ops) + { + case 0: + { + return _iceD_disableMetricsView(in, current); + } + case 1: + { + return _iceD_enableMetricsView(in, current); + } + case 2: + { + return _iceD_getMapMetricsFailures(in, current); + } + case 3: + { + return _iceD_getMetricsFailures(in, current); + } + case 4: + { + return _iceD_getMetricsView(in, current); + } + case 5: + { + return _iceD_getMetricsViewNames(in, current); + } + case 6: + { + return _iceD_ice_id(in, current); + } + case 7: + { + return _iceD_ice_ids(in, current); + } + case 8: + { + return _iceD_ice_isA(in, current); + } + case 9: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +IceMX::Metrics::~Metrics() +{ +} + +const ::std::string& +IceMX::Metrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::Metrics"; + return typeId; +} + +IceMX::ThreadMetrics::~ThreadMetrics() +{ +} + +const ::std::string& +IceMX::ThreadMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::ThreadMetrics"; + return typeId; +} + +IceMX::DispatchMetrics::~DispatchMetrics() +{ +} + +const ::std::string& +IceMX::DispatchMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::DispatchMetrics"; + return typeId; +} + +IceMX::ChildInvocationMetrics::~ChildInvocationMetrics() +{ +} + +const ::std::string& +IceMX::ChildInvocationMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::ChildInvocationMetrics"; + return typeId; +} + +IceMX::CollocatedMetrics::~CollocatedMetrics() +{ +} + +const ::std::string& +IceMX::CollocatedMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::CollocatedMetrics"; + return typeId; +} + +IceMX::RemoteMetrics::~RemoteMetrics() +{ +} + +const ::std::string& +IceMX::RemoteMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::RemoteMetrics"; + return typeId; +} + +IceMX::InvocationMetrics::~InvocationMetrics() +{ +} + +const ::std::string& +IceMX::InvocationMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::InvocationMetrics"; + return typeId; +} + +IceMX::ConnectionMetrics::~ConnectionMetrics() +{ +} + +const ::std::string& +IceMX::ConnectionMetrics::ice_staticId() +{ + static const ::std::string typeId = "::IceMX::ConnectionMetrics"; + return typeId; +} + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_getMetricsViewNames(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsViewNames_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_getMetricsViewNames_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + nullptr, + nullptr, + [](::Ice::InputStream* istr) + { + MetricsAdmin::GetMetricsViewNamesResult v; + istr->readAll(v.disabledViews, v.returnValue); + return v; + }); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_enableMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_name, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_enableMetricsView_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_enableMetricsView_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_name); + }, + [](const ::Ice::UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_disableMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_name, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_disableMetricsView_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_disableMetricsView_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_name); + }, + [](const ::Ice::UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_getMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_view, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsView_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_getMetricsView_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_view); + }, + [](const ::Ice::UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException&) + { + } + }, + [](::Ice::InputStream* istr) + { + MetricsAdmin::GetMetricsViewResult v; + istr->readAll(v.timestamp, v.returnValue); + istr->readPendingValues(); + return v; + }); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_getMapMetricsFailures(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::IceMX::MetricsFailuresSeq>>& outAsync, const ::std::string& iceP_view, const ::std::string& iceP_map, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_view, iceP_map); + }, + [](const ::Ice::UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::MetricsAdminPrx::_iceI_getMetricsFailures(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::IceMX::MetricsFailures>>& outAsync, const ::std::string& iceP_view, const ::std::string& iceP_map, const ::std::string& iceP_id, const ::Ice::Context& context) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsFailures_name); + outAsync->invoke(iceC_IceMX_MetricsAdmin_getMetricsFailures_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::SlicedFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_view, iceP_map, iceP_id); + }, + [](const ::Ice::UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +IceMX::MetricsAdminPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +IceMX::MetricsAdminPrx::ice_staticId() +{ + return MetricsAdmin::ice_staticId(); +} + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsViewNames_name = "getMetricsViewNames"; + +const ::std::string iceC_IceMX_MetricsAdmin_enableMetricsView_name = "enableMetricsView"; + +const ::std::string iceC_IceMX_MetricsAdmin_disableMetricsView_name = "disableMetricsView"; + +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsView_name = "getMetricsView"; + +const ::std::string iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name = "getMapMetricsFailures"; + +const ::std::string iceC_IceMX_MetricsAdmin_getMetricsFailures_name = "getMetricsFailures"; + +} + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::IceMX::UnknownMetricsView> iceC_IceMX_UnknownMetricsView_init("::IceMX::UnknownMetricsView"); + +} + +#ifdef ICE_CPP11_COMPILER +IceMX::UnknownMetricsView::~UnknownMetricsView() +{ +} +#else +IceMX::UnknownMetricsView::~UnknownMetricsView() throw() +{ +} +#endif + +::std::string +IceMX::UnknownMetricsView::ice_id() const +{ + return "::IceMX::UnknownMetricsView"; +} + +IceMX::UnknownMetricsView* +IceMX::UnknownMetricsView::ice_clone() const +{ + return new UnknownMetricsView(*this); +} + +void +IceMX::UnknownMetricsView::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +IceMX::UnknownMetricsView::_writeImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice("::IceMX::UnknownMetricsView", -1, true); + ::Ice::StreamWriter< UnknownMetricsView, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceMX::UnknownMetricsView::_readImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< UnknownMetricsView, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(Metrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Metrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Metrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::Metrics::_newInstance() const +{ + return new Metrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::Metrics::ice_staticId() +{ + return ::IceMX::Metrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(MetricsAdmin* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< MetricsAdmin>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new MetricsAdmin; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_getMetricsViewNames(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsViewNames_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_getMetricsViewNames_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_getMetricsViewNames_name, ::Ice::Normal, context); + result->writeEmptyParams(); + result->invoke(iceC_IceMX_MetricsAdmin_getMetricsViewNames_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::StringSeq +IceProxy::IceMX::MetricsAdmin::end_getMetricsViewNames(::Ice::StringSeq& iceP_disabledViews, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMetricsViewNames_name); + ::Ice::StringSeq ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_disabledViews); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +void IceProxy::IceMX::MetricsAdmin::_iceI_end_getMetricsViewNames(::Ice::StringSeq& iceP_disabledViews, ::Ice::StringSeq& ret, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMetricsViewNames_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_disabledViews); + istr->read(ret); + result->_endReadParams(); +} + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_enableMetricsView(const ::std::string& iceP_name, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_enableMetricsView_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_enableMetricsView_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_enableMetricsView_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::SlicedFormat); + ostr->write(iceP_name); + result->endWriteParams(); + result->invoke(iceC_IceMX_MetricsAdmin_enableMetricsView_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceMX::MetricsAdmin::end_enableMetricsView(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_enableMetricsView_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_disableMetricsView(const ::std::string& iceP_name, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_disableMetricsView_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_disableMetricsView_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_disableMetricsView_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::SlicedFormat); + ostr->write(iceP_name); + result->endWriteParams(); + result->invoke(iceC_IceMX_MetricsAdmin_disableMetricsView_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceMX::MetricsAdmin::end_disableMetricsView(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_disableMetricsView_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_getMetricsView(const ::std::string& iceP_view, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsView_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_getMetricsView_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_getMetricsView_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::SlicedFormat); + ostr->write(iceP_view); + result->endWriteParams(); + result->invoke(iceC_IceMX_MetricsAdmin_getMetricsView_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::IceMX::MetricsView +IceProxy::IceMX::MetricsAdmin::end_getMetricsView(::Ice::Long& iceP_timestamp, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMetricsView_name); + ::IceMX::MetricsView ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_timestamp); + istr->read(ret); + istr->readPendingValues(); + result->_endReadParams(); + return ret; +} + +void IceProxy::IceMX::MetricsAdmin::_iceI_end_getMetricsView(::Ice::Long& iceP_timestamp, ::IceMX::MetricsView& ret, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMetricsView_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_timestamp); + istr->read(ret); + istr->readPendingValues(); + result->_endReadParams(); +} + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_getMapMetricsFailures(const ::std::string& iceP_view, const ::std::string& iceP_map, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::SlicedFormat); + ostr->write(iceP_view); + ostr->write(iceP_map); + result->endWriteParams(); + result->invoke(iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::IceMX::MetricsFailuresSeq +IceProxy::IceMX::MetricsAdmin::end_getMapMetricsFailures(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMapMetricsFailures_name); + ::IceMX::MetricsFailuresSeq ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::IceMX::MetricsAdmin::_iceI_begin_getMetricsFailures(const ::std::string& iceP_view, const ::std::string& iceP_map, const ::std::string& iceP_id, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_IceMX_MetricsAdmin_getMetricsFailures_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceMX_MetricsAdmin_getMetricsFailures_name, del, cookie, sync); + try + { + result->prepare(iceC_IceMX_MetricsAdmin_getMetricsFailures_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::SlicedFormat); + ostr->write(iceP_view); + ostr->write(iceP_map); + ostr->write(iceP_id); + result->endWriteParams(); + result->invoke(iceC_IceMX_MetricsAdmin_getMetricsFailures_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::IceMX::MetricsFailures +IceProxy::IceMX::MetricsAdmin::end_getMetricsFailures(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_IceMX_MetricsAdmin_getMetricsFailures_name); + ::IceMX::MetricsFailures ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::IceMX::UnknownMetricsView&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::MetricsAdmin::_newInstance() const +{ + return new MetricsAdmin; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::MetricsAdmin::ice_staticId() +{ + return ::IceMX::MetricsAdmin::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(ThreadMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< ThreadMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new ThreadMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::ThreadMetrics::_newInstance() const +{ + return new ThreadMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::ThreadMetrics::ice_staticId() +{ + return ::IceMX::ThreadMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(DispatchMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< DispatchMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new DispatchMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::DispatchMetrics::_newInstance() const +{ + return new DispatchMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::DispatchMetrics::ice_staticId() +{ + return ::IceMX::DispatchMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(ChildInvocationMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< ChildInvocationMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new ChildInvocationMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::ChildInvocationMetrics::_newInstance() const +{ + return new ChildInvocationMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::ChildInvocationMetrics::ice_staticId() +{ + return ::IceMX::ChildInvocationMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(CollocatedMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< CollocatedMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new CollocatedMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::CollocatedMetrics::_newInstance() const +{ + return new CollocatedMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::CollocatedMetrics::ice_staticId() +{ + return ::IceMX::CollocatedMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(RemoteMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< RemoteMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new RemoteMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::RemoteMetrics::_newInstance() const +{ + return new RemoteMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::RemoteMetrics::ice_staticId() +{ + return ::IceMX::RemoteMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(InvocationMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< InvocationMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new InvocationMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::InvocationMetrics::_newInstance() const +{ + return new InvocationMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::InvocationMetrics::ice_staticId() +{ + return ::IceMX::InvocationMetrics::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::IceMX::upCast(ConnectionMetrics* p) { return p; } + +void +::IceProxy::IceMX::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< ConnectionMetrics>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new ConnectionMetrics; + v->_copyFrom(proxy); + } +} +/// \endcond + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceMX::ConnectionMetrics::_newInstance() const +{ + return new ConnectionMetrics; +} +/// \endcond + +const ::std::string& +IceProxy::IceMX::ConnectionMetrics::ice_staticId() +{ + return ::IceMX::ConnectionMetrics::ice_staticId(); +} + +IceMX::Metrics::~Metrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(Metrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::Metrics::ice_clone() const +{ + ::Ice::Object* p = new Metrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_Metrics_ids[2] = +{ + "::Ice::Object", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::Metrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_Metrics_ids, iceC_IceMX_Metrics_ids + 2, s); +} + +::std::vector< ::std::string> +IceMX::Metrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_Metrics_ids[0], &iceC_IceMX_Metrics_ids[2]); +} + +const ::std::string& +IceMX::Metrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::Metrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::Metrics"; + return typeId; +#else + return iceC_IceMX_Metrics_ids[1]; +#endif +} + +/// \cond STREAM +void +IceMX::Metrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< Metrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceMX::Metrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< Metrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::Metrics> iceC_IceMX_Metrics_init("::IceMX::Metrics"); +} + +::Ice::ValueFactoryPtr +IceMX::Metrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::Metrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(MetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = MetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Metrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::MetricsAdmin::~MetricsAdmin() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(MetricsAdmin* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_IceMX_MetricsAdmin_ids[2] = +{ + "::Ice::Object", + "::IceMX::MetricsAdmin" +}; + +} + +bool +IceMX::MetricsAdmin::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_MetricsAdmin_ids, iceC_IceMX_MetricsAdmin_ids + 2, s); +} + +::std::vector< ::std::string> +IceMX::MetricsAdmin::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_MetricsAdmin_ids[0], &iceC_IceMX_MetricsAdmin_ids[2]); +} + +const ::std::string& +IceMX::MetricsAdmin::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::MetricsAdmin::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::MetricsAdmin"; + return typeId; +#else + return iceC_IceMX_MetricsAdmin_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsViewNames(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + inS.readEmptyParams(); + inS.setFormat(::Ice::SlicedFormat); + ::Ice::StringSeq iceP_disabledViews; + ::Ice::StringSeq ret = this->getMetricsViewNames(iceP_disabledViews, current); + ::Ice::OutputStream* ostr = inS.startWriteParams(); + ostr->write(iceP_disabledViews); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_enableMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_name; + istr->read(iceP_name); + inS.endReadParams(); + inS.setFormat(::Ice::SlicedFormat); + this->enableMetricsView(iceP_name, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_disableMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_name; + istr->read(iceP_name); + inS.endReadParams(); + inS.setFormat(::Ice::SlicedFormat); + this->disableMetricsView(iceP_name, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsView(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_view; + istr->read(iceP_view); + inS.endReadParams(); + inS.setFormat(::Ice::SlicedFormat); + ::Ice::Long iceP_timestamp; + MetricsView ret = this->getMetricsView(iceP_view, iceP_timestamp, current); + ::Ice::OutputStream* ostr = inS.startWriteParams(); + ostr->write(iceP_timestamp); + ostr->write(ret); + ostr->writePendingValues(); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMapMetricsFailures(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_view; + ::std::string iceP_map; + istr->read(iceP_view); + istr->read(iceP_map); + inS.endReadParams(); + inS.setFormat(::Ice::SlicedFormat); + MetricsFailuresSeq ret = this->getMapMetricsFailures(iceP_view, iceP_map, current); + ::Ice::OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceD_getMetricsFailures(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_view; + ::std::string iceP_map; + ::std::string iceP_id; + istr->read(iceP_view); + istr->read(iceP_map); + istr->read(iceP_id); + inS.endReadParams(); + inS.setFormat(::Ice::SlicedFormat); + MetricsFailures ret = this->getMetricsFailures(iceP_view, iceP_map, iceP_id, current); + ::Ice::OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_IceMX_MetricsAdmin_all[] = +{ + "disableMetricsView", + "enableMetricsView", + "getMapMetricsFailures", + "getMetricsFailures", + "getMetricsView", + "getMetricsViewNames", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +IceMX::MetricsAdmin::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceMX_MetricsAdmin_all, iceC_IceMX_MetricsAdmin_all + 10, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceMX_MetricsAdmin_all) + { + case 0: + { + return _iceD_disableMetricsView(in, current); + } + case 1: + { + return _iceD_enableMetricsView(in, current); + } + case 2: + { + return _iceD_getMapMetricsFailures(in, current); + } + case 3: + { + return _iceD_getMetricsFailures(in, current); + } + case 4: + { + return _iceD_getMetricsView(in, current); + } + case 5: + { + return _iceD_getMetricsViewNames(in, current); + } + case 6: + { + return _iceD_ice_id(in, current); + } + case 7: + { + return _iceD_ice_ids(in, current); + } + case 8: + { + return _iceD_ice_isA(in, current); + } + case 9: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +IceMX::MetricsAdmin::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< MetricsAdmin, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceMX::MetricsAdmin::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< MetricsAdmin, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(MetricsAdminPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = MetricsAdminPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(MetricsAdmin::ice_staticId(), v); + } +} +/// \endcond + +IceMX::ThreadMetrics::~ThreadMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(ThreadMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::ThreadMetrics::ice_clone() const +{ + ::Ice::Object* p = new ThreadMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_ThreadMetrics_ids[3] = +{ + "::Ice::Object", + "::IceMX::Metrics", + "::IceMX::ThreadMetrics" +}; + +} + +bool +IceMX::ThreadMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_ThreadMetrics_ids, iceC_IceMX_ThreadMetrics_ids + 3, s); +} + +::std::vector< ::std::string> +IceMX::ThreadMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_ThreadMetrics_ids[0], &iceC_IceMX_ThreadMetrics_ids[3]); +} + +const ::std::string& +IceMX::ThreadMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::ThreadMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::ThreadMetrics"; + return typeId; +#else + return iceC_IceMX_ThreadMetrics_ids[2]; +#endif +} + +/// \cond STREAM +void +IceMX::ThreadMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< ThreadMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + Metrics::_iceWriteImpl(ostr); +} + +void +IceMX::ThreadMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< ThreadMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + Metrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::ThreadMetrics> iceC_IceMX_ThreadMetrics_init("::IceMX::ThreadMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::ThreadMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::ThreadMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(ThreadMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = ThreadMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(ThreadMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::DispatchMetrics::~DispatchMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(DispatchMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::DispatchMetrics::ice_clone() const +{ + ::Ice::Object* p = new DispatchMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_DispatchMetrics_ids[3] = +{ + "::Ice::Object", + "::IceMX::DispatchMetrics", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::DispatchMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_DispatchMetrics_ids, iceC_IceMX_DispatchMetrics_ids + 3, s); +} + +::std::vector< ::std::string> +IceMX::DispatchMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_DispatchMetrics_ids[0], &iceC_IceMX_DispatchMetrics_ids[3]); +} + +const ::std::string& +IceMX::DispatchMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::DispatchMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::DispatchMetrics"; + return typeId; +#else + return iceC_IceMX_DispatchMetrics_ids[1]; +#endif +} + +/// \cond STREAM +void +IceMX::DispatchMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< DispatchMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + Metrics::_iceWriteImpl(ostr); +} + +void +IceMX::DispatchMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< DispatchMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + Metrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::DispatchMetrics> iceC_IceMX_DispatchMetrics_init("::IceMX::DispatchMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::DispatchMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::DispatchMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(DispatchMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = DispatchMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(DispatchMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::ChildInvocationMetrics::~ChildInvocationMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(ChildInvocationMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::ChildInvocationMetrics::ice_clone() const +{ + ::Ice::Object* p = new ChildInvocationMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_ChildInvocationMetrics_ids[3] = +{ + "::Ice::Object", + "::IceMX::ChildInvocationMetrics", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::ChildInvocationMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_ChildInvocationMetrics_ids, iceC_IceMX_ChildInvocationMetrics_ids + 3, s); +} + +::std::vector< ::std::string> +IceMX::ChildInvocationMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_ChildInvocationMetrics_ids[0], &iceC_IceMX_ChildInvocationMetrics_ids[3]); +} + +const ::std::string& +IceMX::ChildInvocationMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::ChildInvocationMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::ChildInvocationMetrics"; + return typeId; +#else + return iceC_IceMX_ChildInvocationMetrics_ids[1]; +#endif +} + +/// \cond STREAM +void +IceMX::ChildInvocationMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< ChildInvocationMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + Metrics::_iceWriteImpl(ostr); +} + +void +IceMX::ChildInvocationMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< ChildInvocationMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + Metrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::ChildInvocationMetrics> iceC_IceMX_ChildInvocationMetrics_init("::IceMX::ChildInvocationMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::ChildInvocationMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::ChildInvocationMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(ChildInvocationMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = ChildInvocationMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(ChildInvocationMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::CollocatedMetrics::~CollocatedMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(CollocatedMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::CollocatedMetrics::ice_clone() const +{ + ::Ice::Object* p = new CollocatedMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_CollocatedMetrics_ids[4] = +{ + "::Ice::Object", + "::IceMX::ChildInvocationMetrics", + "::IceMX::CollocatedMetrics", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::CollocatedMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_CollocatedMetrics_ids, iceC_IceMX_CollocatedMetrics_ids + 4, s); +} + +::std::vector< ::std::string> +IceMX::CollocatedMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_CollocatedMetrics_ids[0], &iceC_IceMX_CollocatedMetrics_ids[4]); +} + +const ::std::string& +IceMX::CollocatedMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::CollocatedMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::CollocatedMetrics"; + return typeId; +#else + return iceC_IceMX_CollocatedMetrics_ids[2]; +#endif +} + +/// \cond STREAM +void +IceMX::CollocatedMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< CollocatedMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + ChildInvocationMetrics::_iceWriteImpl(ostr); +} + +void +IceMX::CollocatedMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< CollocatedMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + ChildInvocationMetrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::CollocatedMetrics> iceC_IceMX_CollocatedMetrics_init("::IceMX::CollocatedMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::CollocatedMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::CollocatedMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(CollocatedMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = CollocatedMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(CollocatedMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::RemoteMetrics::~RemoteMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(RemoteMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::RemoteMetrics::ice_clone() const +{ + ::Ice::Object* p = new RemoteMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_RemoteMetrics_ids[4] = +{ + "::Ice::Object", + "::IceMX::ChildInvocationMetrics", + "::IceMX::Metrics", + "::IceMX::RemoteMetrics" +}; + +} + +bool +IceMX::RemoteMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_RemoteMetrics_ids, iceC_IceMX_RemoteMetrics_ids + 4, s); +} + +::std::vector< ::std::string> +IceMX::RemoteMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_RemoteMetrics_ids[0], &iceC_IceMX_RemoteMetrics_ids[4]); +} + +const ::std::string& +IceMX::RemoteMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::RemoteMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::RemoteMetrics"; + return typeId; +#else + return iceC_IceMX_RemoteMetrics_ids[3]; +#endif +} + +/// \cond STREAM +void +IceMX::RemoteMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< RemoteMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + ChildInvocationMetrics::_iceWriteImpl(ostr); +} + +void +IceMX::RemoteMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< RemoteMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + ChildInvocationMetrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::RemoteMetrics> iceC_IceMX_RemoteMetrics_init("::IceMX::RemoteMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::RemoteMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::RemoteMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(RemoteMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = RemoteMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(RemoteMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::InvocationMetrics::~InvocationMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(InvocationMetrics* p) { return p; } + +/// \endcond + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4589) +#endif +::Ice::ObjectPtr +IceMX::InvocationMetrics::ice_clone() const +{ + ::Ice::Object* p = new InvocationMetrics(*this); + return p; +} +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +namespace +{ +const ::std::string iceC_IceMX_InvocationMetrics_ids[3] = +{ + "::Ice::Object", + "::IceMX::InvocationMetrics", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::InvocationMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_InvocationMetrics_ids, iceC_IceMX_InvocationMetrics_ids + 3, s); +} + +::std::vector< ::std::string> +IceMX::InvocationMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_InvocationMetrics_ids[0], &iceC_IceMX_InvocationMetrics_ids[3]); +} + +const ::std::string& +IceMX::InvocationMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::InvocationMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::InvocationMetrics"; + return typeId; +#else + return iceC_IceMX_InvocationMetrics_ids[1]; +#endif +} + +void +IceMX::InvocationMetrics::_iceGcVisitMembers(::IceInternal::GCVisitor& v_) +{ + { + for(::IceMX::MetricsMap::iterator _i0 = remotes.begin(); _i0 != remotes.end(); ++_i0) + { + if((*_i0)) + { + if((::IceMX::upCast((*_i0).get())->_iceGcVisit(v_))) + { + (*_i0) = 0; + } + } + } + } + { + for(::IceMX::MetricsMap::iterator _i0 = collocated.begin(); _i0 != collocated.end(); ++_i0) + { + if((*_i0)) + { + if((::IceMX::upCast((*_i0).get())->_iceGcVisit(v_))) + { + (*_i0) = 0; + } + } + } + } +} + +/// \cond STREAM +void +IceMX::InvocationMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< InvocationMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + Metrics::_iceWriteImpl(ostr); +} + +void +IceMX::InvocationMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< InvocationMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + Metrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::InvocationMetrics> iceC_IceMX_InvocationMetrics_init("::IceMX::InvocationMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::InvocationMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::InvocationMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(InvocationMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = InvocationMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(InvocationMetrics::ice_staticId(), v); + } +} +/// \endcond + +IceMX::ConnectionMetrics::~ConnectionMetrics() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* IceMX::upCast(ConnectionMetrics* p) { return p; } + +/// \endcond +::Ice::ObjectPtr +IceMX::ConnectionMetrics::ice_clone() const +{ + ::Ice::Object* p = new ConnectionMetrics(*this); + return p; +} + +namespace +{ +const ::std::string iceC_IceMX_ConnectionMetrics_ids[3] = +{ + "::Ice::Object", + "::IceMX::ConnectionMetrics", + "::IceMX::Metrics" +}; + +} + +bool +IceMX::ConnectionMetrics::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceMX_ConnectionMetrics_ids, iceC_IceMX_ConnectionMetrics_ids + 3, s); +} + +::std::vector< ::std::string> +IceMX::ConnectionMetrics::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceMX_ConnectionMetrics_ids[0], &iceC_IceMX_ConnectionMetrics_ids[3]); +} + +const ::std::string& +IceMX::ConnectionMetrics::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceMX::ConnectionMetrics::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceMX::ConnectionMetrics"; + return typeId; +#else + return iceC_IceMX_ConnectionMetrics_ids[1]; +#endif +} + +/// \cond STREAM +void +IceMX::ConnectionMetrics::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, false); + ::Ice::StreamWriter< ConnectionMetrics, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); + Metrics::_iceWriteImpl(ostr); +} + +void +IceMX::ConnectionMetrics::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< ConnectionMetrics, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); + Metrics::_iceReadImpl(istr); +} +/// \endcond + +namespace +{ +const ::IceInternal::DefaultValueFactoryInit< ::IceMX::ConnectionMetrics> iceC_IceMX_ConnectionMetrics_init("::IceMX::ConnectionMetrics"); +} + +::Ice::ValueFactoryPtr +IceMX::ConnectionMetrics::ice_factory() +{ + return ::IceInternal::factoryTable->getValueFactory(::IceMX::ConnectionMetrics::ice_staticId()); +} + +/// \cond INTERNAL +void +IceMX::_icePatchObjectPtr(ConnectionMetricsPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = ConnectionMetricsPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(ConnectionMetrics::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/MetricsAdminI.cpp b/Sources/IceCpp/MetricsAdminI.cpp new file mode 100644 index 0000000..3142164 --- /dev/null +++ b/Sources/IceCpp/MetricsAdminI.cpp @@ -0,0 +1,694 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceMX; + +namespace +{ + +const string suffixes[] = +{ + "Disabled", + "GroupBy", + "Accept.*", + "Reject.*", + "RetainDetached", + "Map.*", +}; + +void +validateProperties(const string& prefix, const PropertiesPtr& properties) +{ + vector unknownProps; + PropertyDict props = properties->getPropertiesForPrefix(prefix); + for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) + { + bool valid = false; + for(size_t i = 0; i < sizeof(suffixes) / sizeof(*suffixes); ++i) + { + string prop = prefix + suffixes[i]; + if(IceUtilInternal::match(p->first, prop)) + { + valid = true; + break; + } + } + if(!valid) + { + unknownProps.push_back(p->first); + } + } + + if(!unknownProps.empty() && properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) + { + Warning out(getProcessLogger()); + out << "found unknown IceMX properties for '" << prefix.substr(0, prefix.size() - 1) << "':"; + for(vector::const_iterator p = unknownProps.begin(); p != unknownProps.end(); ++p) + { + out << "\n " << *p; + properties->setProperty(*p, ""); // Clear the known property to prevent further warnings. + } + } +} + +vector +parseRule(const PropertiesPtr& properties, const string& name) +{ + vector regexps; + PropertyDict rules = properties->getPropertiesForPrefix(name + '.'); + for(PropertyDict::const_iterator p = rules.begin(); p != rules.end(); ++p) + { + try + { + regexps.push_back(ICE_MAKE_SHARED(MetricsMapI::RegExp, p->first.substr(name.length() + 1), p->second)); + } + catch(const std::exception&) + { + throw invalid_argument("invalid regular expression `" + p->second + "' for `" + p->first + "'"); + } + } + return regexps; +} + +} + +MetricsMapI::RegExp::RegExp(const string& attribute, const string& regexp) : _attribute(attribute) +{ +#ifdef __MINGW32__ + // + // No regexp support with MinGW, when MinGW C++11 mode is not experimental + // we can use std::regex. + // +#elif !defined(ICE_CPP11_COMPILER_REGEXP) + if(regcomp(&_preg, regexp.c_str(), REG_EXTENDED | REG_NOSUB) != 0) + { + throw SyscallException(__FILE__, __LINE__); + } +#else +# if _MSC_VER < 1600 + _regex = std::tr1::regex(regexp, std::tr1::regex_constants::extended | std::tr1::regex_constants::nosubs); +# else + _regex = regex(regexp, std::regex_constants::extended | std::regex_constants::nosubs); +# endif +#endif +} + +MetricsMapI::RegExp::~RegExp() +{ +#ifdef __MINGW32__ + // + // No regexp support with MinGW, when MinGW C++11 mode is not experimental + // we can use std::regex. + // +#elif !defined(ICE_CPP11_COMPILER_REGEXP) + regfree(&_preg); +#endif +} + +bool +MetricsMapI::RegExp::match(const string& value) +{ +#ifdef __MINGW32__ + // + // No regexp support with MinGW, when MinGW C++11 mode is not experimental + // we can use std::regex. + // + return false; +#elif !defined(ICE_CPP11_COMPILER_REGEXP) + return regexec(&_preg, value.c_str(), 0, 0, 0) == 0; +#else +# if _MSC_VER < 1600 + return std::tr1::regex_match(value, _regex); +# else + return regex_match(value, _regex); +# endif +#endif +} + +MetricsMapI::~MetricsMapI() +{ + // Out of line to avoid weak vtable +} + +MetricsMapI::MetricsMapI(const std::string& mapPrefix, const PropertiesPtr& properties) : + _properties(properties->getPropertiesForPrefix(mapPrefix)), + _retain(properties->getPropertyAsIntWithDefault(mapPrefix + "RetainDetached", 10)), + _accept(parseRule(properties, mapPrefix + "Accept")), + _reject(parseRule(properties, mapPrefix + "Reject")) +{ + validateProperties(mapPrefix, properties); + + string groupBy = properties->getPropertyWithDefault(mapPrefix + "GroupBy", "id"); + vector& groupByAttributes = const_cast&>(_groupByAttributes); + vector& groupBySeparators = const_cast&>(_groupBySeparators); + if(!groupBy.empty()) + { + string v; + bool attribute = IceUtilInternal::isAlpha(groupBy[0]) || IceUtilInternal::isDigit(groupBy[0]); + if(!attribute) + { + groupByAttributes.push_back(""); + } + + for(string::const_iterator p = groupBy.begin(); p != groupBy.end(); ++p) + { + bool isAlphaNum = IceUtilInternal::isAlpha(*p) || IceUtilInternal::isDigit(*p) || *p == '.'; + if(attribute && !isAlphaNum) + { + groupByAttributes.push_back(v); + v = *p; + attribute = false; + } + else if(!attribute && isAlphaNum) + { + groupBySeparators.push_back(v); + v = *p; + attribute = true; + } + else + { + v += *p; + } + } + + if(attribute) + { + groupByAttributes.push_back(v); + } + else + { + groupBySeparators.push_back(v); + } + } +} + +MetricsMapI::MetricsMapI(const MetricsMapI& map) : +#if defined(ICE_CPP11_MAPPING) + std::enable_shared_from_this(), +#elif defined(__GNUC__) + IceUtil::Shared(), +#endif + _properties(map._properties), + _groupByAttributes(map._groupByAttributes), + _groupBySeparators(map._groupBySeparators), + _retain(map._retain), + _accept(map._accept), + _reject(map._reject) +{ +} + +const ::Ice::PropertyDict& +MetricsMapI::getProperties() const +{ + return _properties; +} + +MetricsMapFactory::~MetricsMapFactory() +{ + // Out of line to avoid weak vtable +} + +MetricsMapFactory::MetricsMapFactory(Updater* updater) : _updater(updater) +{ +} + +void +MetricsMapFactory::update() +{ + assert(_updater); + _updater->update(); +} + +MetricsViewI::MetricsViewI(const string& name) : _name(name) +{ +} + +void +MetricsViewI::destroy() +{ + for(map::const_iterator p = _maps.begin(); p != _maps.end(); ++p) + { + p->second->destroy(); + } +} + +bool +MetricsViewI::addOrUpdateMap(const PropertiesPtr& properties, const string& mapName, + const MetricsMapFactoryPtr& factory, const ::Ice::LoggerPtr& logger) +{ + const string viewPrefix = "IceMX.Metrics." + _name + "."; + const string mapsPrefix = viewPrefix + "Map."; + PropertyDict mapsProps = properties->getPropertiesForPrefix(mapsPrefix); + + string mapPrefix; + PropertyDict mapProps; + if(!mapsProps.empty()) + { + mapPrefix = mapsPrefix + mapName + "."; + mapProps = properties->getPropertiesForPrefix(mapPrefix); + if(mapProps.empty()) + { + // This map isn't configured for this view. + map::iterator q = _maps.find(mapName); + if(q != _maps.end()) + { + q->second->destroy(); + _maps.erase(q); + return true; + } + return false; + } + } + else + { + mapPrefix = viewPrefix; + mapProps = properties->getPropertiesForPrefix(mapPrefix); + } + + if(properties->getPropertyAsInt(mapPrefix + "Disabled") > 0) + { + // This map is disabled for this view. + map::iterator q = _maps.find(mapName); + if(q != _maps.end()) + { + q->second->destroy(); + _maps.erase(q); + return true; + } + return false; + } + + map::iterator q = _maps.find(mapName); + if(q != _maps.end() && q->second->getProperties() == mapProps) + { + return false; // The map configuration didn't change, no need to re-create. + } + + if(q != _maps.end()) + { + // Destroy the previous map + q->second->destroy(); + _maps.erase(q); + } + + try + { + _maps.insert(make_pair(mapName, factory->create(mapPrefix, properties))); + } + catch(const std::exception& ex) + { + ::Ice::Warning warn(logger); + warn << "unexpected exception while creating metrics map:\n" << ex; + } + return true; +} + +bool +MetricsViewI::removeMap(const string& mapName) +{ + map::iterator q = _maps.find(mapName); + if(q != _maps.end()) + { + q->second->destroy(); + _maps.erase(q); + return true; + } + return false; +} + +MetricsView +MetricsViewI::getMetrics() +{ + MetricsView metrics; + for(map::const_iterator p = _maps.begin(); p != _maps.end(); ++p) + { + metrics.insert(make_pair(p->first, p->second->getMetrics())); + } + return metrics; +} + +MetricsFailuresSeq +MetricsViewI::getFailures(const string& mapName) +{ + map::const_iterator p = _maps.find(mapName); + if(p != _maps.end()) + { + return p->second->getFailures(); + } + return MetricsFailuresSeq(); +} + +MetricsFailures +MetricsViewI::getFailures(const string& mapName, const string& id) +{ + map::const_iterator p = _maps.find(mapName); + if(p != _maps.end()) + { + return p->second->getFailures(id); + } + return MetricsFailures(); +} + +vector +MetricsViewI::getMaps() const +{ + vector maps; + for(map::const_iterator p = _maps.begin(); p != _maps.end(); ++p) + { + maps.push_back(p->first); + } + return maps; +} + +MetricsMapIPtr +MetricsViewI::getMap(const string& mapName) const +{ + map::const_iterator p = _maps.find(mapName); + if(p != _maps.end()) + { + return p->second; + } + return ICE_NULLPTR; +} + +MetricsAdminI::MetricsAdminI(const PropertiesPtr& properties, const LoggerPtr& logger) : + _logger(logger), _properties(properties) +{ + updateViews(); +} + +MetricsAdminI::~MetricsAdminI() +{ +} + +void +MetricsAdminI::destroy() +{ + Lock sync(*this); + for(map::const_iterator p = _views.begin(); p != _views.end(); ++p) + { + p->second->destroy(); + } +} + +void +MetricsAdminI::updateViews() +{ + set updatedMaps; + { + Lock sync(*this); + const string viewsPrefix = "IceMX.Metrics."; + PropertyDict viewsProps = _properties->getPropertiesForPrefix(viewsPrefix); + map views; + _disabledViews.clear(); + for(PropertyDict::const_iterator p = viewsProps.begin(); p != viewsProps.end(); ++p) + { + string viewName = p->first.substr(viewsPrefix.size()); + string::size_type dotPos = viewName.find('.'); + if(dotPos != string::npos) + { + viewName = viewName.substr(0, dotPos); + } + + if(views.find(viewName) != views.end() || _disabledViews.find(viewName) != _disabledViews.end()) + { + continue; // View already configured. + } + + validateProperties(viewsPrefix + viewName + ".", _properties); + + if(_properties->getPropertyAsIntWithDefault(viewsPrefix + viewName + ".Disabled", 0) > 0) + { + _disabledViews.insert(viewName); + continue; // The view is disabled + } + + // + // Create the view or update it. + // + map::const_iterator q = _views.find(viewName); + if(q == _views.end()) + { + q = views.insert(map::value_type(viewName, ICE_MAKE_SHARED(MetricsViewI, viewName))).first; + } + else + { + q = views.insert(make_pair(viewName, q->second)).first; + } + + for(map::const_iterator r = _factories.begin(); r != _factories.end(); ++r) + { + if(q->second->addOrUpdateMap(_properties, r->first, r->second, _logger)) + { + updatedMaps.insert(r->second); + } + } + } + _views.swap(views); + + // + // Go through removed views to collect maps to update. + // + for(map::const_iterator p = views.begin(); p != views.end(); ++p) + { + if(_views.find(p->first) == _views.end()) + { + vector maps = p->second->getMaps(); + for(vector::const_iterator q = maps.begin(); q != maps.end(); ++q) + { + updatedMaps.insert(_factories[*q]); + } + p->second->destroy(); + } + } + } + + // + // Call the updaters to update the maps. + // + for(set::const_iterator p = updatedMaps.begin(); p != updatedMaps.end(); ++p) + { + (*p)->update(); + } +} + +void +MetricsAdminI::unregisterMap(const std::string& mapName) +{ + bool updated; + MetricsMapFactoryPtr factory; + { + Lock sync(*this); + map::iterator p = _factories.find(mapName); + if(p == _factories.end()) + { + return; + } + factory = p->second; + _factories.erase(p); + updated = removeMap(mapName); + } + if(updated) + { + factory->update(); + } +} + +Ice::StringSeq +MetricsAdminI::getMetricsViewNames(Ice::StringSeq& disabledViews, const Current&) +{ + Ice::StringSeq enabledViews; + + Lock sync(*this); + for(map::const_iterator p = _views.begin(); p != _views.end(); ++p) + { + enabledViews.push_back(p->first); + } + +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + for(set::const_iterator p = _disabledViews.begin(); p != _disabledViews.end(); ++p) + { + disabledViews.push_back(*p); + } + +#else + disabledViews.insert(disabledViews.end(), _disabledViews.begin(), _disabledViews.end()); +#endif + + return enabledViews; +} + +void +#ifdef ICE_CPP11_MAPPING +MetricsAdminI::enableMetricsView(string viewName, const Current&) +#else +MetricsAdminI::enableMetricsView(const string& viewName, const Current&) +#endif +{ + { + Lock sync(*this); + getMetricsView(viewName); // Throws if unkonwn metrics view. + _properties->setProperty("IceMX.Metrics." + viewName + ".Disabled", "0"); + } + updateViews(); +} + +void +#ifdef ICE_CPP11_MAPPING +MetricsAdminI::disableMetricsView(string viewName, const Current&) +#else +MetricsAdminI::disableMetricsView(const string& viewName, const Current&) +#endif +{ + { + Lock sync(*this); + getMetricsView(viewName); // Throws if unkonwn metrics view. + _properties->setProperty("IceMX.Metrics." + viewName + ".Disabled", "1"); + } + updateViews(); +} + +MetricsView +#ifdef ICE_CPP11_MAPPING +MetricsAdminI::getMetricsView(string viewName, ::Ice::Long& timestamp, const Current&) +#else +MetricsAdminI::getMetricsView(const string& viewName, ::Ice::Long& timestamp, const Current&) +#endif +{ + Lock sync(*this); + MetricsViewIPtr view = getMetricsView(viewName); + timestamp = IceUtil::Time::now().toMilliSeconds(); + if(view) + { + return view->getMetrics(); + } + return MetricsView(); +} + +MetricsFailuresSeq +#ifdef ICE_CPP11_MAPPING +MetricsAdminI::getMapMetricsFailures(string viewName, string map, const Current&) +#else +MetricsAdminI::getMapMetricsFailures(const string& viewName, const string& map, const Current&) +#endif +{ + Lock sync(*this); + MetricsViewIPtr view = getMetricsView(viewName); + if(view) + { + return view->getFailures(map); + } + return MetricsFailuresSeq(); +} + +MetricsFailures +#ifdef ICE_CPP11_MAPPING +MetricsAdminI::getMetricsFailures(string viewName, string map, string id, const Current&) +#else +MetricsAdminI::getMetricsFailures(const string& viewName, const string& map, const string& id, const Current&) +#endif +{ + Lock sync(*this); + MetricsViewIPtr view = getMetricsView(viewName); + if(view) + { + return view->getFailures(map, id); + } + return MetricsFailures(); +} + +vector +MetricsAdminI::getMaps(const string& mapName) const +{ + Lock sync(*this); + vector maps; + for(std::map::const_iterator p = _views.begin(); p != _views.end(); ++p) + { + MetricsMapIPtr map = p->second->getMap(mapName); + if(map) + { + maps.push_back(map); + } + } + return maps; +} + +const LoggerPtr& +MetricsAdminI::getLogger() const +{ + return _logger; +} + +MetricsViewIPtr +MetricsAdminI::getMetricsView(const std::string& name) +{ + std::map::const_iterator p = _views.find(name); + if(p == _views.end()) + { + if(_disabledViews.find(name) == _disabledViews.end()) + { + throw UnknownMetricsView(); + } + return ICE_NULLPTR; + } + return p->second; +} + +void +MetricsAdminI::updated(const PropertyDict& props) +{ + for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) + { + if(p->first.find("IceMX.") == 0) + { + // Udpate the metrics views using the new configuration. + try + { + updateViews(); + } + catch(const std::exception& ex) + { + ::Ice::Warning warn(_logger); + warn << "unexpected exception while updating metrics view configuration:\n" << ex.what(); + } + return; + } + } +} + +bool +MetricsAdminI::addOrUpdateMap(const std::string& mapName, const MetricsMapFactoryPtr& factory) +{ + bool updated = false; + for(std::map::const_iterator p = _views.begin(); p != _views.end(); ++p) + { + updated |= p->second->addOrUpdateMap(_properties, mapName, factory, _logger); + } + return updated; +} + +bool +MetricsAdminI::removeMap(const std::string& mapName) +{ + bool updated = false; + for(std::map::const_iterator p = _views.begin(); p != _views.end(); ++p) + { + updated |= p->second->removeMap(mapName); + } + return updated; +} diff --git a/Sources/IceCpp/MetricsObserverI.cpp b/Sources/IceCpp/MetricsObserverI.cpp new file mode 100644 index 0000000..4bd5f66 --- /dev/null +++ b/Sources/IceCpp/MetricsObserverI.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include diff --git a/Sources/IceCpp/MutexProtocol.cpp b/Sources/IceCpp/MutexProtocol.cpp new file mode 100644 index 0000000..f8b2e8a --- /dev/null +++ b/Sources/IceCpp/MutexProtocol.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +IceUtil::MutexProtocol +IceUtil::getDefaultMutexProtocol() +{ +#ifdef _WIN32 + return PrioNone; +#else +# if defined(ICE_PRIO_INHERIT) && defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 + return PrioInherit; +# else + return PrioNone; +# endif +#endif +} diff --git a/Sources/IceCpp/Network.cpp b/Sources/IceCpp/Network.cpp new file mode 100644 index 0000000..ccf78cc --- /dev/null +++ b/Sources/IceCpp/Network.cpp @@ -0,0 +1,2249 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// +// The following is required on HP-UX in order to bring in +// the definition for the ip_mreq structure. +// +#if defined(__hpux) +# undef _XOPEN_SOURCE_EXTENDED +# define _XOPEN_SOURCE +# include +#endif + +#include +#include +#include +#include +#include +#include +#include // For setTcpBufSize +#include // For setTcpBufSize +#include // For setTcpBufSize +#include +#include +#include + +// TODO: fix this warning +#if defined(_MSC_VER) +# pragma warning(disable:4244) // 'argument': conversion from 'int' to 'u_short', possible loss of data +#endif + +#if defined(_WIN32) +# include +# include +# ifdef __MINGW32__ +# include +# endif +# include +# include +# include +#else +# include +# include +#endif + +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) +# include +#elif defined(__sun) +# include +#endif + +#if defined(__GNUC__) && (__GNUC__ < 5) +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined(__MINGW32__) +// +// Work-around for missing definitions in MinGW Windows headers +// +# ifndef IPV6_V6ONLY +# define IPV6_V6ONLY 27 +# endif + +extern "C" +{ + WINSOCK_API_LINKAGE int WSAAPI inet_pton(INT, PCTSTR, PVOID); +} +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifdef _WIN32 +int +IceInternal::getSystemErrno() +{ + return GetLastError(); +} +#else +int +IceInternal::getSystemErrno() +{ + return errno; +} +#endif + +namespace +{ + +struct AddressCompare +{ +public: + + bool + operator()(const Address& lhs, const Address& rhs) const + { + return compareAddress(lhs, rhs) < 0; + } +}; + +#ifndef ICE_CPP11_COMPILER + +struct AddressIsIPv6 : public unary_function +{ +public: + + bool + operator()(const Address& ss) const + { + return ss.saStorage.ss_family == AF_INET6; + } +}; +#endif + +void +sortAddresses(vector
& addrs, ProtocolSupport protocol, Ice::EndpointSelectionType selType, bool preferIPv6) +{ + if(selType == Ice::ICE_ENUM(EndpointSelectionType, Random)) + { + IceUtilInternal::shuffle(addrs.begin(), addrs.end()); + } + + if(protocol == EnableBoth) + { +#ifdef ICE_CPP11_COMPILER + if(preferIPv6) + { + stable_partition(addrs.begin(), addrs.end(), + [](const Address& ss) + { + return ss.saStorage.ss_family == AF_INET6; + }); + } + else + { + stable_partition(addrs.begin(), addrs.end(), + [](const Address& ss) + { + return ss.saStorage.ss_family != AF_INET6; + }); + } +#else + if(preferIPv6) + { + stable_partition(addrs.begin(), addrs.end(), AddressIsIPv6()); + } + else + { + stable_partition(addrs.begin(), addrs.end(), not1(AddressIsIPv6())); + } +#endif + } +} + +void +setTcpNoDelay(SOCKET fd) +{ + int flag = 1; + if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flag), int(sizeof(int))) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +void +setKeepAlive(SOCKET fd) +{ + int flag = 1; + if(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast(&flag), int(sizeof(int))) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +SOCKET +createSocketImpl(bool udp, int family) +{ + SOCKET fd; + if(udp) + { + fd = socket(family, SOCK_DGRAM, IPPROTO_UDP); + } + else + { + fd = socket(family, SOCK_STREAM, IPPROTO_TCP); + } + + if(fd == INVALID_SOCKET) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + if(!udp) + { + setTcpNoDelay(fd); + setKeepAlive(fd); + } + + return fd; +} + +vector
+getLocalAddresses(ProtocolSupport protocol, bool includeLoopback, bool singleAddressPerInterface) +{ + vector
result; + +#if defined(_WIN32) + DWORD family; + switch(protocol) + { + case EnableIPv4: + family = AF_INET; + break; + case EnableIPv6: + family = AF_INET6; + break; + default: + family = AF_UNSPEC; + break; + } + + DWORD size = 0; + DWORD rv = GetAdaptersAddresses(family, 0, ICE_NULLPTR, ICE_NULLPTR, &size); + if(rv == ERROR_BUFFER_OVERFLOW) + { + PIP_ADAPTER_ADDRESSES adapter_addresses = (PIP_ADAPTER_ADDRESSES) malloc(size); + rv = GetAdaptersAddresses(family, 0, ICE_NULLPTR, adapter_addresses, &size); + if(rv == ERROR_SUCCESS) + { + for(PIP_ADAPTER_ADDRESSES aa = adapter_addresses; aa != ICE_NULLPTR; aa = aa->Next) + { + if(aa->OperStatus != IfOperStatusUp) + { + continue; + } + for(PIP_ADAPTER_UNICAST_ADDRESS ua = aa->FirstUnicastAddress; ua != ICE_NULLPTR; ua = ua->Next) + { + Address addr; + memcpy(&addr.saStorage, ua->Address.lpSockaddr, ua->Address.iSockaddrLength); + if(addr.saStorage.ss_family == AF_INET && protocol != EnableIPv6) + { + if(addr.saIn.sin_addr.s_addr != 0 && + (includeLoopback || addr.saIn.sin_addr.s_addr != htonl(INADDR_LOOPBACK))) + { + result.push_back(addr); + if(singleAddressPerInterface) + { + break; // One address is enough for each interface. + } + } + } + else if(addr.saStorage.ss_family == AF_INET6 && protocol != EnableIPv4) + { + if(!IN6_IS_ADDR_UNSPECIFIED(&addr.saIn6.sin6_addr) && + (includeLoopback || !IN6_IS_ADDR_LOOPBACK(&addr.saIn6.sin6_addr))) + { + result.push_back(addr); + if(singleAddressPerInterface) + { + break; // One address is enough for each interface. + } + } + } + } + } + } + + free(adapter_addresses); + } +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) + struct ifaddrs* ifap; + if(::getifaddrs(&ifap) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + struct ifaddrs* curr = ifap; + set interfaces; + while(curr != 0) + { + if(curr->ifa_addr && (includeLoopback || !(curr->ifa_flags & IFF_LOOPBACK))) + { + if(curr->ifa_addr->sa_family == AF_INET && protocol != EnableIPv6) + { + Address addr; + memcpy(&addr.saStorage, curr->ifa_addr, sizeof(sockaddr_in)); + if(addr.saIn.sin_addr.s_addr != 0) + { + if(!singleAddressPerInterface || interfaces.find(curr->ifa_name) == interfaces.end()) + { + result.push_back(addr); + interfaces.insert(curr->ifa_name); + } + } + } + else if(curr->ifa_addr->sa_family == AF_INET6 && protocol != EnableIPv4) + { + Address addr; + memcpy(&addr.saStorage, curr->ifa_addr, sizeof(sockaddr_in6)); + if(!IN6_IS_ADDR_UNSPECIFIED(&addr.saIn6.sin6_addr)) + { + if(!singleAddressPerInterface || interfaces.find(curr->ifa_name) == interfaces.end()) + { + result.push_back(addr); + interfaces.insert(curr->ifa_name); + } + } + } + } + + curr = curr->ifa_next; + } + + ::freeifaddrs(ifap); +#else + for(int i = 0; i < 2; i++) + { + if((i == 0 && protocol == EnableIPv6) || (i == 1 && protocol == EnableIPv4)) + { + continue; + } + SOCKET fd = createSocketImpl(false, i == 0 ? AF_INET : AF_INET6); + +#ifdef _AIX + int cmd = CSIOCGIFCONF; +#else + int cmd = SIOCGIFCONF; +#endif + struct ifconf ifc; + int numaddrs = 10; + int old_ifc_len = 0; + + // + // Need to call ioctl multiple times since we do not know up front + // how many addresses there will be, and thus how large a buffer we need. + // We keep increasing the buffer size until subsequent calls return + // the same length, meaning we have all the addresses. + // + while(true) + { + int bufsize = numaddrs * static_cast(sizeof(struct ifreq)); + ifc.ifc_len = bufsize; + ifc.ifc_buf = (char*)malloc(bufsize); + + int rs = ioctl(fd, cmd, &ifc); + if(rs == SOCKET_ERROR) + { + free(ifc.ifc_buf); + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + else if(ifc.ifc_len == old_ifc_len) + { + // + // Returned same length twice in a row, finished. + // + break; + } + else + { + old_ifc_len = ifc.ifc_len; + } + + numaddrs += 10; + free(ifc.ifc_buf); + } + closeSocket(fd); + + numaddrs = ifc.ifc_len / static_cast(sizeof(struct ifreq)); + struct ifreq* ifr = ifc.ifc_req; + set interfaces; + for(int j = 0; j < numaddrs; ++j) + { + if(!(ifr[j].ifr_flags & IFF_LOOPBACK)) // Don't include loopback interface addresses + { + // + // On Solaris the above Loopback check does not always work so we double + // check the address below. Solaris also returns duplicate entries that need + // to be filtered out. + // + if(ifr[j].ifr_addr.sa_family == AF_INET && protocol != EnableIPv6) + { + Address addr; + memcpy(&addr.saStorage, &ifr[j].ifr_addr, sizeof(sockaddr_in)); + if(addr.saIn.sin_addr.s_addr != 0 && + (includeLoopback || addr.saIn.sin_addr.s_addr != htonl(INADDR_LOOPBACK))) + { + if(!singleAddressPerInterface || interfaces.find(ifr[j].ifr_name) == interfaces.end()) + { + result.push_back(addr); + interfaces.insert(ifr[j].ifr_name); + } + } + } + else if(ifr[j].ifr_addr.sa_family == AF_INET6 && protocol != EnableIPv4) + { + Address addr; + memcpy(&addr.saStorage, &ifr[j].ifr_addr, sizeof(sockaddr_in6)); + if(!IN6_IS_ADDR_UNSPECIFIED(&addr.saIn6.sin6_addr) && + (includeLoopback || !IN6_IS_ADDR_LOOPBACK(&addr.saIn6.sin6_addr))) + { + if(!singleAddressPerInterface || interfaces.find(ifr[j].ifr_name) == interfaces.end()) + { + result.push_back(addr); + interfaces.insert(ifr[j].ifr_name); + } + } + } + } + } + free(ifc.ifc_buf); + } +#endif + + // + // Remove potential duplicates from the result. + // + set seen; + vector
tmp; + tmp.swap(result); + for(vector
::const_iterator p = tmp.begin(); p != tmp.end(); ++p) + { + if(seen.find(*p) == seen.end()) + { + result.push_back(*p); + seen.insert(*p); + } + } + return result; +} + +bool +isLinklocal(const Address& addr) +{ + if(addr.saStorage.ss_family == AF_INET6) + { + return IN6_IS_ADDR_LINKLOCAL(&addr.saIn6.sin6_addr); + } + else if(addr.saStorage.ss_family == AF_INET) + { + // Check for 169.254.X.X in network order + return (addr.saIn.sin_addr.s_addr & 0xFF) == 169 && ((addr.saIn.sin_addr.s_addr & 0xFF00)>>8) == 254; + } + return false; +} + +bool +isWildcard(const string& host, ProtocolSupport protocol, bool& ipv4) +{ + Address addr = getAddressForServer(host, 0, protocol, true, false); + if(addr.saStorage.ss_family == AF_INET) + { + if(addr.saIn.sin_addr.s_addr == INADDR_ANY) + { + ipv4 = true; + return true; + } + } + else if(addr.saStorage.ss_family == AF_INET6) + { + if(IN6_IS_ADDR_UNSPECIFIED(&addr.saIn6.sin6_addr)) + { + ipv4 = false; + return true; + } + } + return false; +} + +int +getInterfaceIndex(const string& intf) +{ + if(intf.empty()) + { + return 0; + } + + string name; + bool isAddr; + in6_addr addr; + string::size_type pos = intf.find("%"); + if(pos != string::npos) + { + // + // If it's a link-local address, use the zone indice. + // + isAddr = false; + name = intf.substr(pos + 1); + } + else + { + // + // Then check if it's an IPv6 address. If it's an address we'll + // look for the interface index by address. + // + isAddr = inet_pton(AF_INET6, intf.c_str(), &addr) > 0; + name = intf; + } + + // + // Check if index + // + int index = -1; + istringstream p(name); + if((p >> index) && p.eof()) + { + return index; + } + +#ifdef _WIN32 + IP_ADAPTER_ADDRESSES addrs; + ULONG buflen = 0; + if(::GetAdaptersAddresses(AF_INET6, 0, 0, &addrs, &buflen) == ERROR_BUFFER_OVERFLOW) + { + PIP_ADAPTER_ADDRESSES paddrs; + char* buf = new char[buflen]; + paddrs = reinterpret_cast(buf); + if(::GetAdaptersAddresses(AF_INET6, 0, 0, paddrs, &buflen) == NO_ERROR) + { + while(paddrs) + { + if(isAddr) + { + PIP_ADAPTER_UNICAST_ADDRESS ipAddr = paddrs->FirstUnicastAddress; + while(ipAddr) + { + if(ipAddr->Address.lpSockaddr->sa_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = + reinterpret_cast(ipAddr->Address.lpSockaddr); + if(memcmp(&addr, &ipv6Addr->sin6_addr, sizeof(in6_addr)) == 0) + { + break; + } + } + ipAddr = ipAddr->Next; + } + if(ipAddr) + { + index = paddrs->Ipv6IfIndex; + break; + } + } + else + { + // + // Don't need to pass a wide string converter as the wide string + // come from Windows API. + // + if(wstringToString(paddrs->FriendlyName, getProcessStringConverter()) == name) + { + index = paddrs->Ipv6IfIndex; + break; + } + } + paddrs = paddrs->Next; + } + } + delete[] buf; + } + if(index < 0) // interface not found + { + throw Ice::SocketException(__FILE__, __LINE__, WSAEINVAL); + } +#elif !defined(__hpux) + + // + // Look for an interface with a matching IP address + // + if(isAddr) + { +# if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) + struct ifaddrs* ifap; + if(::getifaddrs(&ifap) != SOCKET_ERROR) + { + struct ifaddrs* curr = ifap; + while(curr != 0) + { + if(curr->ifa_addr && curr->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = reinterpret_cast(curr->ifa_addr); + if(memcmp(&addr, &ipv6Addr->sin6_addr, sizeof(in6_addr)) == 0) + { + index = static_cast(if_nametoindex(curr->ifa_name)); + break; + } + } + curr = curr->ifa_next; + } + ::freeifaddrs(ifap); + } +# else + SOCKET fd = createSocketImpl(false, AF_INET6); +# ifdef _AIX + int cmd = CSIOCGIFCONF; +# else + int cmd = SIOCGIFCONF; +# endif + struct ifconf ifc; + int numaddrs = 10; + int old_ifc_len = 0; + + // + // Need to call ioctl multiple times since we do not know up front + // how many addresses there will be, and thus how large a buffer we need. + // We keep increasing the buffer size until subsequent calls return + // the same length, meaning we have all the addresses. + // + while(true) + { + int bufsize = numaddrs * static_cast(sizeof(struct ifreq)); + ifc.ifc_len = bufsize; + ifc.ifc_buf = (char*)malloc(bufsize); + + int rs = ioctl(fd, cmd, &ifc); + if(rs == SOCKET_ERROR) + { + free(ifc.ifc_buf); + ifc.ifc_buf = 0; + break; + } + else if(ifc.ifc_len == old_ifc_len) + { + // + // Returned same length twice in a row, finished. + // + break; + } + else + { + old_ifc_len = ifc.ifc_len; + } + numaddrs += 10; + free(ifc.ifc_buf); + } + closeSocketNoThrow(fd); + + if(ifc.ifc_buf) + { + numaddrs = ifc.ifc_len / static_cast(sizeof(struct ifreq)); + struct ifreq* ifr = ifc.ifc_req; + for(int i = 0; i < numaddrs; ++i) + { + if(ifr[i].ifr_addr.sa_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = reinterpret_cast(&ifr[i].ifr_addr); + if(memcmp(&addr, &ipv6Addr->sin6_addr, sizeof(in6_addr)) == 0) + { + index = static_cast(if_nametoindex(ifr[i].ifr_name)); + break; + } + } + } + free(ifc.ifc_buf); + } +# endif + } + else // Look for an interface with the given name. + { + index = static_cast(if_nametoindex(name.c_str())); + } + if(index <= 0) + { + // index == 0 if if_nametoindex returned 0, < 0 if name wasn't found + throw Ice::SocketException(__FILE__, __LINE__, index == 0 ? getSocketErrno() : ENXIO); + } +#endif + + return index; +} + +struct in_addr +getInterfaceAddress(const string& name) +{ + struct in_addr addr; + addr.s_addr = INADDR_ANY; + if(name.empty()) + { + return addr; + } + + if(inet_pton(AF_INET, name.c_str(), &addr) > 0) + { + return addr; + } + +#ifdef _WIN32 + IP_ADAPTER_ADDRESSES addrs; + ULONG buflen = 0; + if(::GetAdaptersAddresses(AF_INET, 0, 0, &addrs, &buflen) == ERROR_BUFFER_OVERFLOW) + { + PIP_ADAPTER_ADDRESSES paddrs; + char* buf = new char[buflen]; + paddrs = reinterpret_cast(buf); + if(::GetAdaptersAddresses(AF_INET, 0, 0, paddrs, &buflen) == NO_ERROR) + { + while(paddrs) + { + // + // Don't need to pass a wide string converter as the wide string come + // from Windows API. + // + if(wstringToString(paddrs->FriendlyName, getProcessStringConverter()) == name) + { + struct sockaddr_in addrin; + memcpy(&addrin, paddrs->FirstUnicastAddress->Address.lpSockaddr, + paddrs->FirstUnicastAddress->Address.iSockaddrLength); + delete[] buf; + return addrin.sin_addr; + } + paddrs = paddrs->Next; + } + } + delete[] buf; + } + throw Ice::SocketException(__FILE__, __LINE__, WSAEINVAL); +#else + ifreq if_address; + strcpy(if_address.ifr_name, name.c_str()); + + SOCKET fd = createSocketImpl(false, AF_INET); + int rc = ioctl(fd, SIOCGIFADDR, &if_address); + closeSocketNoThrow(fd); + if(rc == SOCKET_ERROR) + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + return reinterpret_cast(&if_address.ifr_addr)->sin_addr; +#endif +} + +int +getAddressStorageSize(const Address& addr) +{ + int size = 0; + if(addr.saStorage.ss_family == AF_INET) + { + size = sizeof(sockaddr_in); + } + else if(addr.saStorage.ss_family == AF_INET6) + { + size = sizeof(sockaddr_in6); + } + return size; +} + +vector
+getLoopbackAddresses(ProtocolSupport protocol, int port = 0) +{ + vector
result; + + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + + // + // We don't use getaddrinfo when host is empty as it's not portable (some old Linux + // versions don't support it). + // + if(protocol != EnableIPv4) + { + addr.saIn6.sin6_family = AF_INET6; + addr.saIn6.sin6_port = htons(port); + addr.saIn6.sin6_addr = in6addr_loopback; + result.push_back(addr); + } + if(protocol != EnableIPv6) + { + addr.saIn.sin_family = AF_INET; + addr.saIn.sin_port = htons(port); + addr.saIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + result.push_back(addr); + } + return result; +} + +} + +ReadyCallback::~ReadyCallback() +{ + // Out of line to avoid weak vtable +} + +NativeInfo::~NativeInfo() +{ + // Out of line to avoid weak vtable +} + +void +NativeInfo::setReadyCallback(const ReadyCallbackPtr& callback) +{ + _readyCallback = callback; +} + +#ifdef ICE_USE_IOCP + +IceInternal::AsyncInfo::AsyncInfo(SocketOperation s) +{ + ZeroMemory(this, sizeof(AsyncInfo)); + status = s; +} + +void +IceInternal::NativeInfo::initialize(HANDLE handle, ULONG_PTR key) +{ + _handle = handle; + _key = key; +} + +void +IceInternal::NativeInfo::completed(SocketOperation operation) +{ + if(!PostQueuedCompletionStatus(_handle, 0, _key, getAsyncInfo(operation))) + { + throw Ice::SocketException(__FILE__, __LINE__, GetLastError()); + } +} + +#else + +void +IceInternal::NativeInfo::setNewFd(SOCKET fd) +{ + assert(_fd == INVALID_SOCKET); // This can only be called once, when the current socket isn't set yet. + _newFd = fd; +} + +bool +IceInternal::NativeInfo::newFd() +{ + if(_newFd == INVALID_SOCKET) + { + return false; + } + assert(_fd == INVALID_SOCKET); + swap(_fd, _newFd); + return true; +} + +#endif + +bool +IceInternal::noMoreFds(int error) +{ +#if defined(_WIN32) + return error == WSAEMFILE; +#else + return error == EMFILE || error == ENFILE; +#endif +} + +string +IceInternal::errorToStringDNS(int error) +{ +#if defined(_WIN32) + return IceUtilInternal::errorToString(error); +#else + return gai_strerror(error); +#endif +} + +vector
+IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol, Ice::EndpointSelectionType selType, + bool preferIPv6, bool canBlock) +{ + vector
result; + + // + // We don't use getaddrinfo when host is empty as it's not portable (some old Linux + // versions don't support it). + // + if(host.empty()) + { + result = getLoopbackAddresses(protocol, port); + sortAddresses(result, protocol, selType, preferIPv6); + return result; + } + + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + + struct addrinfo* info = 0; + int retry = 5; + + struct addrinfo hints = {}; + if(protocol == EnableIPv4) + { + hints.ai_family = PF_INET; + } + else if(protocol == EnableIPv6) + { + hints.ai_family = PF_INET6; + } + else + { + hints.ai_family = PF_UNSPEC; + } + + if(!canBlock) + { + hints.ai_flags = AI_NUMERICHOST; + } + + int rs = 0; + do + { + rs = getaddrinfo(host.c_str(), 0, &hints, &info); + } + while(info == 0 && rs == EAI_AGAIN && --retry >= 0); + + // In theory, getaddrinfo should only return EAI_NONAME if + // AI_NUMERICHOST is specified and the host name is not a IP + // address. However on some platforms (e.g. macOS 10.4.x) + // EAI_NODATA is also returned so we also check for it. +#ifdef EAI_NODATA + if(!canBlock && (rs == EAI_NONAME || rs == EAI_NODATA)) +#else + if(!canBlock && rs == EAI_NONAME) +#endif + { + return result; // Empty result indicates that a canBlock lookup is necessary. + } + else if(rs != 0) + { + throw DNSException(__FILE__, __LINE__, rs, host); + } + + for(struct addrinfo* p = info; p != ICE_NULLPTR; p = p->ai_next) + { + memcpy(&addr.saStorage, p->ai_addr, p->ai_addrlen); + if(p->ai_family == PF_INET) + { + addr.saIn.sin_port = htons(port); + } + else if(p->ai_family == PF_INET6) + { + addr.saIn6.sin6_port = htons(port); + } + + bool found = false; + for(unsigned int i = 0; i < result.size(); ++i) + { + if(compareAddress(result[i], addr) == 0) + { + found = true; + break; + } + } + if(!found) + { + result.push_back(addr); + } + } + + freeaddrinfo(info); + + if(result.empty()) + { + throw DNSException(__FILE__, __LINE__, 0, host); + } + sortAddresses(result, protocol, selType, preferIPv6); + return result; +} + +ProtocolSupport +IceInternal::getProtocolSupport(const Address& addr) +{ + return addr.saStorage.ss_family == AF_INET ? EnableIPv4 : EnableIPv6; +} + +Address +IceInternal::getAddressForServer(const string& host, int port, ProtocolSupport protocol, bool preferIPv6, bool canBlock) +{ + // + // We don't use getaddrinfo when host is empty as it's not portable (some old Linux + // versions don't support it). + // + if(host.empty()) + { + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + if(protocol != EnableIPv4) + { + addr.saIn6.sin6_family = AF_INET6; + addr.saIn6.sin6_port = htons(port); + addr.saIn6.sin6_addr = in6addr_any; + } + else + { + addr.saIn.sin_family = AF_INET; + addr.saIn.sin_port = htons(port); + addr.saIn.sin_addr.s_addr = htonl(INADDR_ANY); + } + return addr; + } + vector
addrs = getAddresses(host, port, protocol, Ice::ICE_ENUM(EndpointSelectionType, Ordered), + preferIPv6, canBlock); + return addrs.empty() ? Address() : addrs[0]; +} + +int +IceInternal::compareAddress(const Address& addr1, const Address& addr2) +{ + if(addr1.saStorage.ss_family < addr2.saStorage.ss_family) + { + return -1; + } + else if(addr2.saStorage.ss_family < addr1.saStorage.ss_family) + { + return 1; + } + + if(addr1.saStorage.ss_family == AF_INET) + { + if(addr1.saIn.sin_port < addr2.saIn.sin_port) + { + return -1; + } + else if(addr2.saIn.sin_port < addr1.saIn.sin_port) + { + return 1; + } + + if(addr1.saIn.sin_addr.s_addr < addr2.saIn.sin_addr.s_addr) + { + return -1; + } + else if(addr2.saIn.sin_addr.s_addr < addr1.saIn.sin_addr.s_addr) + { + return 1; + } + } + else + { + if(addr1.saIn6.sin6_port < addr2.saIn6.sin6_port) + { + return -1; + } + else if(addr2.saIn6.sin6_port < addr1.saIn6.sin6_port) + { + return 1; + } + + int res = memcmp(&addr1.saIn6.sin6_addr, &addr2.saIn6.sin6_addr, sizeof(in6_addr)); + if(res < 0) + { + return -1; + } + else if(res > 0) + { + return 1; + } + } + + return 0; +} + +bool +IceInternal::isIPv6Supported() +{ + SOCKET fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if(fd == INVALID_SOCKET) + { + return false; + } + else + { + closeSocketNoThrow(fd); + return true; + } +} + +SOCKET +IceInternal::createSocket(bool udp, const Address& addr) +{ + return createSocketImpl(udp, addr.saStorage.ss_family); +} +SOCKET +IceInternal::createServerSocket(bool udp, const Address& addr, ProtocolSupport protocol) +{ + SOCKET fd = createSocket(udp, addr); + if(addr.saStorage.ss_family == AF_INET6 && protocol != EnableIPv4) + { + int flag = protocol == EnableIPv6 ? 1 : 0; + if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&flag), int(sizeof(int))) == SOCKET_ERROR) + { +#ifdef _WIN32 + if(getSocketErrno() == WSAENOPROTOOPT) + { + return fd; // Windows XP doesn't support IPV6_V6ONLY + } +#endif + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + return fd; +} + +void +IceInternal::closeSocketNoThrow(SOCKET fd) +{ +#if defined(_WIN32) + int error = WSAGetLastError(); + closesocket(fd); + WSASetLastError(error); +#else + int error = errno; + close(fd); + errno = error; +#endif +} + +void +IceInternal::closeSocket(SOCKET fd) +{ +#if defined(_WIN32) + int error = WSAGetLastError(); + if(closesocket(fd) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + WSASetLastError(error); +#else + int error = errno; + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + // + // FreeBSD returns ECONNRESET if the underlying object was + // a stream socket that was shut down by the peer before all + // pending data was delivered. + // + if(close(fd) == SOCKET_ERROR && getSocketErrno() != ECONNRESET) +# else + if(close(fd) == SOCKET_ERROR) +# endif + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + errno = error; +#endif +} + +string +IceInternal::addrToString(const Address& addr) +{ + ostringstream s; + s << inetAddrToString(addr) << ':' << getPort(addr); + return s.str(); +} + +void +IceInternal::fdToLocalAddress(SOCKET fd, Address& addr) +{ + socklen_t len = static_cast(sizeof(sockaddr_storage)); + if(getsockname(fd, &addr.sa, &len) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +bool +IceInternal::fdToRemoteAddress(SOCKET fd, Address& addr) +{ + socklen_t len = static_cast(sizeof(sockaddr_storage)); + if(getpeername(fd, &addr.sa, &len) == SOCKET_ERROR) + { + if(notConnected()) + { + return false; + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + return true; +} + +std::string +IceInternal::fdToString(SOCKET fd, const NetworkProxyPtr& proxy, const Address& target) +{ + if(fd == INVALID_SOCKET) + { + return ""; + } + + ostringstream s; + + Address remoteAddr; + bool peerConnected = fdToRemoteAddress(fd, remoteAddr); + +#ifdef _WIN32 + if(!peerConnected) + { + // + // The local address is only accessible with connected sockets on Windows. + // + s << "local address = "; + } + else +#endif + { + Address localAddr; + fdToLocalAddress(fd, localAddr); + s << "local address = " << addrToString(localAddr); + } + + if(proxy) + { + if(!peerConnected) + { + remoteAddr = proxy->getAddress(); + } + s << "\n" + proxy->getName() + " proxy address = " << addrToString(remoteAddr); + s << "\nremote address = " << addrToString(target); + } + else + { + if(!peerConnected) + { + remoteAddr = target; + } + s << "\nremote address = " << addrToString(remoteAddr); + } + + return s.str(); +} + +std::string +IceInternal::fdToString(SOCKET fd) +{ + if(fd == INVALID_SOCKET) + { + return ""; + } + + Address localAddr; + fdToLocalAddress(fd, localAddr); + + Address remoteAddr; + bool peerConnected = fdToRemoteAddress(fd, remoteAddr); + + return addressesToString(localAddr, remoteAddr, peerConnected); +} + +void +IceInternal::fdToAddressAndPort(SOCKET fd, string& localAddress, int& localPort, string& remoteAddress, int& remotePort) +{ + if(fd == INVALID_SOCKET) + { + localAddress.clear(); + remoteAddress.clear(); + localPort = -1; + remotePort = -1; + return; + } + + Address localAddr; + fdToLocalAddress(fd, localAddr); + addrToAddressAndPort(localAddr, localAddress, localPort); + + Address remoteAddr; + if(fdToRemoteAddress(fd, remoteAddr)) + { + addrToAddressAndPort(remoteAddr, remoteAddress, remotePort); + } + else + { + remoteAddress.clear(); + remotePort = -1; + } +} + +void +IceInternal::addrToAddressAndPort(const Address& addr, string& address, int& port) +{ + address = inetAddrToString(addr); + port = getPort(addr); +} + +std::string +IceInternal::addressesToString(const Address& localAddr, const Address& remoteAddr, bool peerConnected) +{ + ostringstream s; + s << "local address = " << addrToString(localAddr); + if(peerConnected) + { + s << "\nremote address = " << addrToString(remoteAddr); + } + else + { + s << "\nremote address = "; + } + return s.str(); +} + +bool +IceInternal::isAddressValid(const Address& addr) +{ + return addr.saStorage.ss_family != AF_UNSPEC; +} + +vector +IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport protocolSupport, bool includeLoopback) +{ + vector hosts; + bool ipv4Wildcard = false; + if(isWildcard(host, protocolSupport, ipv4Wildcard)) + { + vector
addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocolSupport, includeLoopback, false); + for(vector
::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + // + // NOTE: We don't publish link-local addresses as in most cases + // these are not desired to be published and in some cases + // will not work without extra configuration. + // + if(!isLinklocal(*p)) + { + hosts.push_back(inetAddrToString(*p)); + } + } + if(hosts.empty()) + { + // Return loopback if no other local addresses are available. + addrs = getLoopbackAddresses(protocolSupport); + for(vector
::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + hosts.push_back(inetAddrToString(*p)); + } + } + } + return hosts; // An empty host list indicates to just use the given host. +} + +vector +IceInternal::getInterfacesForMulticast(const string& intf, ProtocolSupport protocolSupport) +{ + vector interfaces; + bool ipv4Wildcard = false; + if(isWildcard(intf, protocolSupport, ipv4Wildcard)) + { + vector
addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocolSupport, true, true); + for(vector
::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + interfaces.push_back(inetAddrToString(*p)); // We keep link local addresses for multicast + } + } + if(interfaces.empty()) + { + interfaces.push_back(intf); + } + return interfaces; +} + +string +IceInternal::inetAddrToString(const Address& ss) +{ + int size = getAddressStorageSize(ss); + if(size == 0) + { + return ""; + } + + char namebuf[1024]; + namebuf[0] = '\0'; + getnameinfo(&ss.sa, static_cast(size), namebuf, static_cast(sizeof(namebuf)), 0, 0, + NI_NUMERICHOST); + return string(namebuf); +} + +int +IceInternal::getPort(const Address& addr) +{ + if(addr.saStorage.ss_family == AF_INET) + { + return ntohs(addr.saIn.sin_port); + } + else if(addr.saStorage.ss_family == AF_INET6) + { + return ntohs(addr.saIn6.sin6_port); + } + else + { + return -1; + } +} + +void +IceInternal::setPort(Address& addr, int port) +{ + if(addr.saStorage.ss_family == AF_INET) + { + addr.saIn.sin_port = htons(port); + } + else + { + assert(addr.saStorage.ss_family == AF_INET6); + addr.saIn6.sin6_port = htons(port); + } +} + +bool +IceInternal::isMulticast(const Address& addr) +{ + if(addr.saStorage.ss_family == AF_INET) + { + return IN_MULTICAST(ntohl(addr.saIn.sin_addr.s_addr)); + } + else if(addr.saStorage.ss_family == AF_INET6) + { + return IN6_IS_ADDR_MULTICAST(&addr.saIn6.sin6_addr); + } + return false; +} + +void +IceInternal::setTcpBufSize(SOCKET fd, const ProtocolInstancePtr& instance) +{ + assert(fd != INVALID_SOCKET); + + // + // By default, on Windows we use a 128KB buffer size. On Unix + // platforms, we use the system defaults. + // +#ifdef _WIN32 + const int dfltBufSize = 128 * 1024; +#else + const int dfltBufSize = 0; +#endif + Int rcvSize = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", dfltBufSize); + Int sndSize = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.SndSize", dfltBufSize); + + setTcpBufSize(fd, rcvSize, sndSize, instance); +} + +void +IceInternal::setTcpBufSize(SOCKET fd, int rcvSize, int sndSize, const ProtocolInstancePtr& instance) +{ + assert(fd != INVALID_SOCKET); + + if(rcvSize > 0) + { + // + // Try to set the buffer size. The kernel will silently adjust + // the size to an acceptable value. Then read the size back to + // get the size that was actually set. + // + setRecvBufferSize(fd, rcvSize); + int size = getRecvBufferSize(fd); + if(size > 0 && size < rcvSize) + { + // Warn if the size that was set is less than the requested size and + // we have not already warned. + BufSizeWarnInfo winfo = instance->getBufSizeWarn(TCPEndpointType); + if(!winfo.rcvWarn || rcvSize != winfo.rcvSize) + { + Ice::Warning out(instance->logger()); + out << "TCP receive buffer size: requested size of " << rcvSize << " adjusted to " << size; + instance->setRcvBufSizeWarn(TCPEndpointType, rcvSize); + } + } + } + + if(sndSize > 0) + { + // + // Try to set the buffer size. The kernel will silently adjust + // the size to an acceptable value. Then read the size back to + // get the size that was actually set. + // + setSendBufferSize(fd, sndSize); + int size = getSendBufferSize(fd); + if(size > 0 && size < sndSize) + { + // Warn if the size that was set is less than the requested size and + // we have not already warned. + BufSizeWarnInfo winfo = instance->getBufSizeWarn(TCPEndpointType); + if(!winfo.sndWarn || sndSize != winfo.sndSize) + { + Ice::Warning out(instance->logger()); + out << "TCP send buffer size: requested size of " << sndSize << " adjusted to " << size; + instance->setSndBufSizeWarn(TCPEndpointType, sndSize); + } + } + } +} + +void +IceInternal::setBlock(SOCKET fd, bool block) +{ +#ifdef _WIN32 + if(block) + { + unsigned long arg = 0; + if(ioctlsocket(fd, FIONBIO, &arg) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, WSAGetLastError()); + } + } + else + { + unsigned long arg = 1; + if(ioctlsocket(fd, FIONBIO, &arg) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, WSAGetLastError()); + } + } +#else + if(block) + { + int flags = fcntl(fd, F_GETFL); + flags &= ~O_NONBLOCK; + if(fcntl(fd, F_SETFL, flags) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, errno); + } + } + else + { + int flags = fcntl(fd, F_GETFL); + flags |= O_NONBLOCK; + if(fcntl(fd, F_SETFL, flags) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, errno); + } + } +#endif +} + +void +IceInternal::setSendBufferSize(SOCKET fd, int sz) +{ + if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&sz), int(sizeof(int))) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +int +IceInternal::getSendBufferSize(SOCKET fd) +{ + int sz; + socklen_t len = sizeof(sz); + if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&sz), &len) == SOCKET_ERROR || + static_cast(len) != sizeof(sz)) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + return sz; +} + +void +IceInternal::setRecvBufferSize(SOCKET fd, int sz) +{ + if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&sz), int(sizeof(int))) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +int +IceInternal::getRecvBufferSize(SOCKET fd) +{ + int sz; + socklen_t len = sizeof(sz); + if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&sz), &len) == SOCKET_ERROR || + static_cast(len) != sizeof(sz)) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + return sz; +} + +void +IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string& intf) +{ + vector interfaces = getInterfacesForMulticast(intf, getProtocolSupport(group)); + set indexes; + for(vector::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) + { + int rc = 0; + if(group.saStorage.ss_family == AF_INET) + { + struct ip_mreq mreq; + mreq.imr_multiaddr = group.saIn.sin_addr; + mreq.imr_interface = getInterfaceAddress(*p); + rc = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast(&mreq), int(sizeof(mreq))); + } + else + { + int index = getInterfaceIndex(*p); + if(indexes.find(index) == indexes.end()) // Don't join twice the same interface (if it has multiple IPs) + { + indexes.insert(index); + struct ipv6_mreq mreq; + mreq.ipv6mr_multiaddr = group.saIn6.sin6_addr; + mreq.ipv6mr_interface = static_cast(index); + rc = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, reinterpret_cast(&mreq), int(sizeof(mreq))); + } + } + if(rc == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } +} + +void +IceInternal::setMcastInterface(SOCKET fd, const string& intf, const Address& addr) +{ + int rc; + if(addr.saStorage.ss_family == AF_INET) + { + struct in_addr iface = getInterfaceAddress(intf); + rc = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, reinterpret_cast(&iface), int(sizeof(iface))); + } + else + { + int interfaceNum = getInterfaceIndex(intf); + rc = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, reinterpret_cast(&interfaceNum), int(sizeof(int))); + } + if(rc == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +void +IceInternal::setMcastTtl(SOCKET fd, int ttl, const Address& addr) +{ + int rc; + if(addr.saStorage.ss_family == AF_INET) + { + rc = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, reinterpret_cast(&ttl), int(sizeof(int))); + } + else + { + rc = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, reinterpret_cast(&ttl), int(sizeof(int))); + } + if(rc == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +void +IceInternal::setReuseAddress(SOCKET fd, bool reuse) +{ + int flag = reuse ? 1 : 0; + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&flag), int(sizeof(int))) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +Address +IceInternal::doBind(SOCKET fd, const Address& addr, const string&) +{ + int size = getAddressStorageSize(addr); + assert(size != 0); + + if(::bind(fd, &addr.sa, static_cast(size)) == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + Address local; + socklen_t len = static_cast(sizeof(sockaddr_storage)); +#ifdef NDEBUG + getsockname(fd, &local.sa, &len); +#else + int ret = getsockname(fd, &local.sa, &len); + assert(ret != SOCKET_ERROR); +#endif + return local; +} + +Address +IceInternal::getNumericAddress(const std::string& address) +{ + vector
addrs = getAddresses(address, 0, EnableBoth, Ice::ICE_ENUM(EndpointSelectionType, Ordered), false, + false); + if(addrs.empty()) + { + return Address(); + } + else + { + return addrs[0]; + } +} + +int +IceInternal::getSocketErrno() +{ +#if defined(_WIN32) + return WSAGetLastError(); +#else + return errno; +#endif +} + +bool +IceInternal::interrupted() +{ +#ifdef _WIN32 + return WSAGetLastError() == WSAEINTR; +#else +# ifdef EPROTO + return errno == EINTR || errno == EPROTO; +# else + return errno == EINTR; +# endif +#endif +} + +bool +IceInternal::acceptInterrupted() +{ + if(interrupted()) + { + return true; + } + +#ifdef _WIN32 + int error = WSAGetLastError(); + return error == WSAECONNABORTED || + error == WSAECONNRESET || + error == WSAETIMEDOUT; +#else + return errno == ECONNABORTED || + errno == ECONNRESET || + errno == ETIMEDOUT; +#endif +} + +bool +IceInternal::noBuffers() +{ +#ifdef _WIN32 + int error = WSAGetLastError(); + return error == WSAENOBUFS || + error == WSAEFAULT; +#else + return errno == ENOBUFS; +#endif +} + +bool +IceInternal::wouldBlock() +{ +#ifdef _WIN32 + int error = WSAGetLastError(); + return error == WSAEWOULDBLOCK || error == WSA_IO_PENDING || error == ERROR_IO_PENDING; +#else + return errno == EAGAIN || errno == EWOULDBLOCK; +#endif +} + +bool +IceInternal::connectFailed() +{ +#if defined(_WIN32) + int error = WSAGetLastError(); + return error == WSAECONNREFUSED || + error == WSAETIMEDOUT || + error == WSAENETUNREACH || + error == WSAEHOSTUNREACH || + error == WSAECONNRESET || + error == WSAESHUTDOWN || + error == WSAECONNABORTED || + error == ERROR_SEM_TIMEOUT || + error == ERROR_NETNAME_DELETED; +#else + return errno == ECONNREFUSED || + errno == ETIMEDOUT || + errno == ENETUNREACH || + errno == EHOSTUNREACH || + errno == ECONNRESET || + errno == ESHUTDOWN || + errno == ECONNABORTED; +#endif +} + +bool +IceInternal::connectionRefused() +{ +#if defined(_WIN32) + int error = WSAGetLastError(); + return error == WSAECONNREFUSED || error == ERROR_CONNECTION_REFUSED; +#else + return errno == ECONNREFUSED; +#endif +} + +bool +IceInternal::connectionLost() +{ +#ifdef _WIN32 + int error = WSAGetLastError(); + return error == WSAECONNRESET || + error == WSAESHUTDOWN || + error == WSAENOTCONN || +# ifdef ICE_USE_IOCP + error == ERROR_NETNAME_DELETED || +# endif + error == WSAECONNABORTED; +#else + return errno == ECONNRESET || + errno == ENOTCONN || + errno == ESHUTDOWN || + errno == ECONNABORTED || + errno == EPIPE; +#endif +} + +bool +IceInternal::connectInProgress() +{ +#ifdef _WIN32 + int error = WSAGetLastError(); + return error == WSAEWOULDBLOCK || error == WSA_IO_PENDING || error == ERROR_IO_PENDING; +#else + return errno == EINPROGRESS; +#endif +} + +bool +IceInternal::notConnected() +{ +#ifdef _WIN32 + return WSAGetLastError() == WSAENOTCONN; +#elif defined(__APPLE__) || defined(__FreeBSD__) + return errno == ENOTCONN || errno == EINVAL; +#else + return errno == ENOTCONN; +#endif +} + +bool +IceInternal::recvTruncated() +{ +#ifdef _WIN32 + int err = WSAGetLastError(); + return err == WSAEMSGSIZE || err == ERROR_MORE_DATA; +#else + // We don't get an error under Linux if a datagram is truncated. + return false; +#endif +} + +void +IceInternal::doListen(SOCKET fd, int backlog) +{ +repeatListen: + if(::listen(fd, backlog) == SOCKET_ERROR) + { + if(interrupted()) + { + goto repeatListen; + } + + closeSocketNoThrow(fd); + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} + +bool +IceInternal::doConnect(SOCKET fd, const Address& addr, const Address& sourceAddr) +{ + if(isAddressValid(sourceAddr)) + { + doBind(fd, sourceAddr); + } + +repeatConnect: + int size = getAddressStorageSize(addr); + assert(size != 0); + + if(::connect(fd, &addr.sa, static_cast(size)) == SOCKET_ERROR) + { + if(interrupted()) + { + goto repeatConnect; + } + + if(connectInProgress()) + { + return false; + } + + closeSocketNoThrow(fd); + if(connectionRefused()) + { + throw ConnectionRefusedException(__FILE__, __LINE__, getSocketErrno()); + } + else if(connectFailed()) + { + throw ConnectFailedException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + +#if defined(__linux__) + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // + Address localAddr; + try + { + fdToLocalAddress(fd, localAddr); + if(compareAddress(addr, localAddr) == 0) + { + throw ConnectionRefusedException(__FILE__, __LINE__, 0); // No appropriate errno + } + } + catch(const LocalException&) + { + closeSocketNoThrow(fd); + throw; + } +#endif + return true; +} + +void +IceInternal::doFinishConnect(SOCKET fd) +{ + // + // Note: we don't close the socket if there's an exception. It's the responsability + // of the caller to do so. + // + + // + // Strange windows bug: The following call to Sleep() is + // necessary, otherwise no error is reported through + // getsockopt. + // +#if defined(_WIN32) + Sleep(0); +#endif + + int val; + socklen_t len = static_cast(sizeof(int)); + if(getsockopt(fd, SOL_SOCKET, SO_ERROR, reinterpret_cast(&val), &len) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + if(val > 0) + { +#if defined(_WIN32) + WSASetLastError(val); +#else + errno = val; +#endif + if(connectionRefused()) + { + throw ConnectionRefusedException(__FILE__, __LINE__, getSocketErrno()); + } + else if(connectFailed()) + { + throw ConnectFailedException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + +#if defined(__linux__) + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // + Address localAddr; + fdToLocalAddress(fd, localAddr); + Address remoteAddr; + if(fdToRemoteAddress(fd, remoteAddr) && compareAddress(remoteAddr, localAddr) == 0) + { + throw ConnectionRefusedException(__FILE__, __LINE__, 0); // No appropriate errno + } +#endif +} + +SOCKET +IceInternal::doAccept(SOCKET fd) +{ +#ifdef _WIN32 + SOCKET ret; +#else + int ret; +#endif + +repeatAccept: + if((ret = ::accept(fd, 0, 0)) == INVALID_SOCKET) + { + if(acceptInterrupted()) + { + goto repeatAccept; + } + + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + setTcpNoDelay(ret); + setKeepAlive(ret); + return ret; +} + +void +IceInternal::createPipe(SOCKET fds[2]) +{ +#ifdef _WIN32 + + SOCKET fd = createSocketImpl(false, AF_INET); + setBlock(fd, true); + + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + + addr.saIn.sin_family = AF_INET; + addr.saIn.sin_port = htons(0); + addr.saIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + addr = doBind(fd, addr); + doListen(fd, 1); + + try + { + fds[0] = createSocketImpl(false, AF_INET); + } + catch(...) + { + ::closesocket(fd); + throw; + } + + try + { + setBlock(fds[0], true); +# ifndef NDEBUG + bool connected = doConnect(fds[0], addr, Address()); + assert(connected); +# else + doConnect(fds[0], addr, Address()); +# endif + } + catch(...) + { + // fds[0] is closed by doConnect + ::closesocket(fd); + throw; + } + + try + { + fds[1] = doAccept(fd); + } + catch(...) + { + ::closesocket(fds[0]); + ::closesocket(fd); + throw; + } + + ::closesocket(fd); + + try + { + setBlock(fds[1], true); + } + catch(...) + { + ::closesocket(fds[0]); + // fds[1] is closed by setBlock + throw; + } + +#else + + if(::pipe(fds) != 0) + { + throw SyscallException(__FILE__, __LINE__, getSocketErrno()); + } + + try + { + setBlock(fds[0], true); + } + catch(...) + { + // fds[0] is closed by setBlock + closeSocketNoThrow(fds[1]); + throw; + } + + try + { + setBlock(fds[1], true); + } + catch(...) + { + closeSocketNoThrow(fds[0]); + // fds[1] is closed by setBlock + throw; + } + +#endif +} + +#if defined(ICE_USE_IOCP) +void +IceInternal::doConnectAsync(SOCKET fd, const Address& addr, const Address& sourceAddr, AsyncInfo& info) +{ + // + // NOTE: It's the caller's responsability to close the socket upon + // failure to connect. The socket isn't closed by this method. + // + Address bindAddr; + if(isAddressValid(sourceAddr)) + { + bindAddr = sourceAddr; + } + else + { + memset(&bindAddr.saStorage, 0, sizeof(sockaddr_storage)); + if(addr.saStorage.ss_family == AF_INET) + { + bindAddr.saIn.sin_family = AF_INET; + bindAddr.saIn.sin_port = htons(0); + bindAddr.saIn.sin_addr.s_addr = htonl(INADDR_ANY); + } + else if(addr.saStorage.ss_family == AF_INET6) + { + bindAddr.saIn6.sin6_family = AF_INET6; + bindAddr.saIn6.sin6_port = htons(0); + bindAddr.saIn6.sin6_addr = in6addr_any; + } + } + + int size = getAddressStorageSize(bindAddr); + assert(size != 0); + + if(::bind(fd, &bindAddr.sa, size) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + LPFN_CONNECTEX ConnectEx = ICE_NULLPTR; // a pointer to the 'ConnectEx()' function + GUID GuidConnectEx = WSAID_CONNECTEX; // The Guid + DWORD dwBytes; + if(WSAIoctl(fd, + SIO_GET_EXTENSION_FUNCTION_POINTER, + &GuidConnectEx, + sizeof(GuidConnectEx), + &ConnectEx, + sizeof(ConnectEx), + &dwBytes, + ICE_NULLPTR, + ICE_NULLPTR) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + if(!ConnectEx(fd, &addr.sa, size, 0, 0, 0, &info)) + { + if(!connectInProgress()) + { + if(connectionRefused()) + { + throw ConnectionRefusedException(__FILE__, __LINE__, getSocketErrno()); + } + else if(connectFailed()) + { + throw ConnectFailedException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } +} + +void +IceInternal::doFinishConnectAsync(SOCKET fd, AsyncInfo& info) +{ + // + // NOTE: It's the caller's responsability to close the socket upon + // failure to connect. The socket isn't closed by this method. + // + + if(info.error != ERROR_SUCCESS) + { + WSASetLastError(info.error); + if(connectionRefused()) + { + throw ConnectionRefusedException(__FILE__, __LINE__, getSocketErrno()); + } + else if(connectFailed()) + { + throw ConnectFailedException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + + if(setsockopt(fd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, ICE_NULLPTR, 0) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } +} +#endif + +bool +IceInternal::isIpAddress(const string& name) +{ + in_addr addr; + in6_addr addr6; + + return inet_pton(AF_INET, name.c_str(), &addr) > 0 || inet_pton(AF_INET6, name.c_str(), &addr6) > 0; +} diff --git a/Sources/IceCpp/NetworkProxy.cpp b/Sources/IceCpp/NetworkProxy.cpp new file mode 100644 index 0000000..3190754 --- /dev/null +++ b/Sources/IceCpp/NetworkProxy.cpp @@ -0,0 +1,311 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(NetworkProxy* p) { return p; } + +NetworkProxy::~NetworkProxy() +{ + // Out of line to avoid weak vtable +} + +namespace +{ + +class SOCKSNetworkProxy : public NetworkProxy +{ +public: + + SOCKSNetworkProxy(const string&, int); + SOCKSNetworkProxy(const Address&); + + virtual void beginWrite(const Address&, Buffer&); + virtual SocketOperation endWrite(Buffer&); + virtual void beginRead(Buffer&); + virtual SocketOperation endRead(Buffer&); + virtual void finish(Buffer&, Buffer&); + virtual NetworkProxyPtr resolveHost(ProtocolSupport) const; + virtual Address getAddress() const; + virtual string getName() const; + virtual ProtocolSupport getProtocolSupport() const; + +private: + + string _host; + int _port; + Address _address; +}; + +class HTTPNetworkProxy : public NetworkProxy +{ +public: + + HTTPNetworkProxy(const string&, int); + HTTPNetworkProxy(const Address&, ProtocolSupport); + + virtual void beginWrite(const Address&, Buffer&); + virtual SocketOperation endWrite(Buffer&); + virtual void beginRead(Buffer&); + virtual SocketOperation endRead(Buffer&); + virtual void finish(Buffer&, Buffer&); + virtual NetworkProxyPtr resolveHost(ProtocolSupport) const; + virtual Address getAddress() const; + virtual string getName() const; + virtual ProtocolSupport getProtocolSupport() const; + +private: + + string _host; + int _port; + Address _address; + ProtocolSupport _protocol; +}; + +} + +SOCKSNetworkProxy::SOCKSNetworkProxy(const string& host, int port) : _host(host), _port(port) +{ + assert(!host.empty()); +} + +SOCKSNetworkProxy::SOCKSNetworkProxy(const Address& addr) : _port(0), _address(addr) +{ +} + +void +SOCKSNetworkProxy::beginWrite(const Address& addr, Buffer& buf) +{ + // + // SOCKS connect request + // + buf.b.resize(9); + buf.i = buf.b.begin(); + Ice::Byte* dest = &buf.b[0]; + *dest++ = 0x04; // SOCKS version 4. + *dest++ = 0x01; // Command, establish a TCP/IP stream connection + + const Ice::Byte* src; + + // + // Port (already in big-endian order) + // + src = reinterpret_cast(&addr.saIn.sin_port); + *dest++ = *src++; + *dest++ = *src; + + // + // IPv4 address (already in big-endian order) + // + src = reinterpret_cast(&addr.saIn.sin_addr.s_addr); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src; + + *dest = 0x00; // User ID. +} + +SocketOperation +SOCKSNetworkProxy::endWrite(Buffer& buf) +{ + // Once the request is sent, read the response + return buf.i != buf.b.end() ? SocketOperationWrite : SocketOperationRead; +} + +void +SOCKSNetworkProxy::beginRead(Buffer& buf) +{ + // + // Read the SOCKS4 response whose size is 8 bytes. + // + buf.b.resize(8); + buf.i = buf.b.begin(); +} + +SocketOperation +SOCKSNetworkProxy::endRead(Buffer& buf) +{ + // We're done once we read the response + return buf.i != buf.b.end() ? SocketOperationRead : SocketOperationNone; +} + +void +SOCKSNetworkProxy::finish(Buffer& readBuffer, Buffer&) +{ + readBuffer.i = readBuffer.b.begin(); + + if(readBuffer.b.end() - readBuffer.i < 2) + { + throw Ice::UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + const Ice::Byte* src = &(*readBuffer.i); + const Ice::Byte b1 = *src++; + const Ice::Byte b2 = *src++; + if(b1 != 0x00 || b2 != 0x5a) + { + throw Ice::ConnectFailedException(__FILE__, __LINE__); + } +} + +NetworkProxyPtr +SOCKSNetworkProxy::resolveHost(ProtocolSupport protocol) const +{ + assert(!_host.empty()); + return new SOCKSNetworkProxy(getAddresses(_host, _port, protocol, Ice::ICE_ENUM(EndpointSelectionType, Random), false, true)[0]); +} + +Address +SOCKSNetworkProxy::getAddress() const +{ + assert(_host.empty()); // Host must be resolved. + return _address; +} + +string +SOCKSNetworkProxy::getName() const +{ + return "SOCKS"; +} + +ProtocolSupport +SOCKSNetworkProxy::getProtocolSupport() const +{ + return EnableIPv4; +} + +HTTPNetworkProxy::HTTPNetworkProxy(const string& host, int port) : + _host(host), _port(port), _protocol(EnableBoth) +{ + assert(!host.empty()); +} + +HTTPNetworkProxy::HTTPNetworkProxy(const Address& addr, ProtocolSupport protocol) : + _port(0), _address(addr), _protocol(protocol) +{ +} + +void +HTTPNetworkProxy::beginWrite(const Address& addr, Buffer& buf) +{ + // + // HTTP connect request + // + ostringstream out; + out << "CONNECT " << addrToString(addr) << " HTTP/1.1\r\n" << "Host: " << addrToString(addr) << "\r\n\r\n"; + string str = out.str(); + buf.b.resize(str.size()); + memcpy(&buf.b[0], str.c_str(), str.size()); + buf.i = buf.b.begin(); +} + +SocketOperation +HTTPNetworkProxy::endWrite(Buffer& buf) +{ + // Once the request is sent, read the response + return buf.i != buf.b.end() ? SocketOperationWrite : SocketOperationRead; +} + +void +HTTPNetworkProxy::beginRead(Buffer& buf) +{ + // + // Read the Http response + // + buf.b.resize(7); // Enough space for reading at least HTTP1.1 + buf.i = buf.b.begin(); +} + +SocketOperation +HTTPNetworkProxy::endRead(Buffer& buf) +{ + // + // Check if we received the full HTTP response, if not, continue + // reading otherwise we're done. + // + const Ice::Byte* end = HttpParser().isCompleteMessage(buf.b.begin(), buf.i); + if(!end && buf.i == buf.b.end()) + { + // + // Read one more byte, we can't easily read bytes in advance + // since the transport implenentation might be be able to read + // the data from the memory instead of the socket. This is for + // instance the case with the OpenSSL transport (or we would + // have to use a buffering BIO). + // + buf.b.resize(buf.b.size() + 1); + buf.i = buf.b.begin() + buf.b.size() - 1; + return SocketOperationRead; + } + return SocketOperationNone; +} + +void +HTTPNetworkProxy::finish(Buffer& readBuffer, Buffer&) +{ + HttpParser parser; + parser.parse(readBuffer.b.begin(), readBuffer.b.end()); + if(parser.status() != 200) + { + throw Ice::ConnectFailedException(__FILE__, __LINE__); + } +} + +NetworkProxyPtr +HTTPNetworkProxy::resolveHost(ProtocolSupport protocol) const +{ + assert(!_host.empty()); + return new HTTPNetworkProxy(getAddresses(_host, _port, protocol, Ice::ICE_ENUM(EndpointSelectionType, Random), false, true)[0], protocol); +} + +Address +HTTPNetworkProxy::getAddress() const +{ + assert(_host.empty()); // Host must be resolved. + return _address; +} + +string +HTTPNetworkProxy::getName() const +{ + return "HTTP"; +} + +ProtocolSupport +HTTPNetworkProxy::getProtocolSupport() const +{ + return _protocol; +} + +NetworkProxyPtr +IceInternal::createNetworkProxy(const Ice::PropertiesPtr& properties, ProtocolSupport protocolSupport) +{ + string proxyHost; + + proxyHost = properties->getProperty("Ice.SOCKSProxyHost"); + if(!proxyHost.empty()) + { + if(protocolSupport == EnableIPv6) + { + throw Ice::InitializationException(__FILE__, __LINE__, "IPv6 only is not supported with SOCKS4 proxies"); + } + int proxyPort = properties->getPropertyAsIntWithDefault("Ice.SOCKSProxyPort", 1080); + return new SOCKSNetworkProxy(proxyHost, proxyPort); + } + + proxyHost = properties->getProperty("Ice.HTTPProxyHost"); + if(!proxyHost.empty()) + { + return new HTTPNetworkProxy(proxyHost, properties->getPropertyAsIntWithDefault("Ice.HTTPProxyPort", 1080)); + } + + return 0; +} diff --git a/Sources/IceCpp/OSLogLoggerI.cpp b/Sources/IceCpp/OSLogLoggerI.cpp new file mode 100644 index 0000000..a5c3432 --- /dev/null +++ b/Sources/IceCpp/OSLogLoggerI.cpp @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifdef ICE_SWIFT + +#include +#include + +using namespace std; +using namespace Ice; + +Ice::OSLogLoggerI::OSLogLoggerI(const std::string& prefix) : _prefix(prefix) +{ + const string subsystem = prefix.empty() ? "com.zeroc.ice" : "com.zeroc.ice." + prefix; + _log.reset(os_log_create(subsystem.c_str(), "")); +} + +void +Ice::OSLogLoggerI::print(const std::string& message) +{ + os_log_with_type(_log.get(), OS_LOG_TYPE_DEFAULT, "%{public}s.", message.c_str()); +} + +void +Ice::OSLogLoggerI::trace(const std::string& category, const std::string& message) +{ + const string subsystem = _prefix.empty() ? "com.zeroc.ice" : "com.zeroc.ice." + _prefix; + IceInternal::UniqueRef log(os_log_create(subsystem.c_str(), category.c_str())); + os_log_with_type(log.get(), OS_LOG_TYPE_INFO, "%{public}s.", message.c_str()); +} + +void +Ice::OSLogLoggerI::warning(const std::string& message) +{ + os_log_with_type(_log.get(), OS_LOG_TYPE_ERROR, "%{public}s.", message.c_str()); +} + +void +Ice::OSLogLoggerI::error(const std::string& message) +{ + os_log_with_type(_log.get(), OS_LOG_TYPE_FAULT, "%{public}s.", message.c_str()); +} + +std::string +Ice::OSLogLoggerI::getPrefix() +{ + return _prefix; +} + +LoggerPtr +Ice::OSLogLoggerI::cloneWithPrefix(const std::string& prefix) +{ + return ICE_MAKE_SHARED(OSLogLoggerI, prefix); +} + +#endif diff --git a/Sources/IceCpp/Object.cpp b/Sources/IceCpp/Object.cpp new file mode 100644 index 0000000..83d03a8 --- /dev/null +++ b/Sources/IceCpp/Object.cpp @@ -0,0 +1,435 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace Ice +{ +const Current emptyCurrent = Current(); +} + +#ifndef ICE_CPP11_MAPPING +Object* Ice::upCast(Object* p) { return p; } + +void +Ice::_icePatchObjectPtr(ObjectPtr& obj, const ObjectPtr& v) +{ + obj = v; +} + +bool +Ice::Object::operator==(const Object& r) const +{ + return this == &r; +} + +bool +Ice::Object::operator<(const Object& r) const +{ + return this < &r; +} +#endif + +namespace +{ + +const string object_ids[] = +{ + "::Ice::Object" +}; + +const string object_all[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +#ifndef ICE_CPP11_MAPPING +Ice::DispatchInterceptorAsyncCallback::~DispatchInterceptorAsyncCallback() +{ + // Out of line to avoid weak vtable +} +#endif + +Ice::Request::~Request() +{ + // Out of line to avoid weak vtable +} + +bool +#ifdef ICE_CPP11_MAPPING +Ice::Object::ice_isA(string s, const Current&) const +#else +Ice::Object::ice_isA(const string& s, const Current&) const +#endif +{ + return s == object_ids[0]; +} + +void +Ice::Object::ice_ping(const Current&) const +{ + // Nothing to do. +} + +vector +Ice::Object::ice_ids(const Current&) const +{ + return vector(&object_ids[0], &object_ids[1]); +} + +#ifdef ICE_CPP11_MAPPING +string +#else +const string& +#endif +Ice::Object::ice_id(const Current&) const +{ + return object_ids[0]; +} + +const ::std::string& +Ice::Object::ice_staticId() +{ + return object_ids[0]; +} + +#ifndef ICE_CPP11_MAPPING +Ice::ObjectPtr +Ice::Object::ice_clone() const +{ + throw CloneNotImplementedException(__FILE__, __LINE__); +} + +Ice::SlicedDataPtr +Ice::Object::ice_getSlicedData() const +{ + return 0; +} +#endif + +bool +Ice::Object::_iceD_ice_isA(Incoming& inS, const Current& current) +{ + InputStream* istr = inS.startReadParams(); + string iceP_id; + istr->read(iceP_id, false); + inS.endReadParams(); +#ifdef ICE_CPP11_MAPPING + bool ret = ice_isA(std::move(iceP_id), current); +#else + bool ret = ice_isA(iceP_id, current); +#endif + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} + +bool +Ice::Object::_iceD_ice_ping(Incoming& inS, const Current& current) +{ + inS.readEmptyParams(); + ice_ping(current); + inS.writeEmptyParams(); + return true; +} + +bool +Ice::Object::_iceD_ice_ids(Incoming& inS, const Current& current) +{ + inS.readEmptyParams(); + vector ret = ice_ids(current); + OutputStream* ostr = inS.startWriteParams(); + if(ret.empty()) + { + ostr->write(ret); + } + else + { + ostr->write(&ret[0], &ret[0] + ret.size(), false); + } + inS.endWriteParams(); + return true; +} + +bool +Ice::Object::_iceD_ice_id(Incoming& inS, const Current& current) +{ + inS.readEmptyParams(); + string ret = ice_id(current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret, false); + inS.endWriteParams(); + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +Ice::Object::ice_dispatch(Request& request, std::function r, std::function e) +#else +Ice::Object::ice_dispatch(Request& request, const DispatchInterceptorAsyncCallbackPtr& cb) +#endif +{ + IceInternal::Incoming& in = dynamic_cast(request)._in; + in.startOver(); +#ifdef ICE_CPP11_MAPPING + if(r || e) + { + in.push(r, e); +#else + if(cb) + { + in.push(cb); +#endif + try + { + bool sync = _iceDispatch(in, in.getCurrent()); + in.pop(); + return sync; + } + catch(...) + { + in.pop(); + throw; + } + } + else + { + return _iceDispatch(in, in.getCurrent()); + } +} + +bool +Ice::Object::_iceDispatch(Incoming& in, const Current& current) +{ + pair r = equal_range(object_all, object_all + sizeof(object_all) / sizeof(string), current.operation); + + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - object_all) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} + +#ifndef ICE_CPP11_MAPPING +void +Ice::Object::ice_collectable(bool) +{ +} + +void +Ice::Object::ice_preMarshal() +{ +} + +void +Ice::Object::ice_postUnmarshal() +{ +} + +void +Ice::Object::_iceWrite(Ice::OutputStream* os) const +{ + os->startValue(0); + _iceWriteImpl(os); + os->endValue(); +} + +void +Ice::Object::_iceRead(Ice::InputStream* is) +{ + is->startValue(); + _iceReadImpl(is); + is->endValue(false); +} + +Ice::Int +Ice::Object::ice_operationAttributes(const string&) const +{ + return 0; +} +#endif + +namespace +{ + +string +operationModeToString(OperationMode mode) +{ + switch(mode) + { + case ICE_ENUM(OperationMode, Normal): + return "::Ice::Normal"; + + case ICE_ENUM(OperationMode, Nonmutating): + return "::Ice::Nonmutating"; + + case ICE_ENUM(OperationMode, Idempotent): + return "::Ice::Idempotent"; + } + // + // This could not happen with C++11 strong type enums + // +#ifdef ICE_CPP11_MAPPING + assert(false); + return ""; +#else + ostringstream os; + os << "unknown value (" << mode << ")"; + return os.str(); +#endif +} + +} + +void +Ice::Object::_iceCheckMode(OperationMode expected, OperationMode received) +{ + if(expected != received) + { + assert(expected != ICE_ENUM(OperationMode, Nonmutating)); // We never expect Nonmutating + if(expected == ICE_ENUM(OperationMode, Idempotent) && received == ICE_ENUM(OperationMode, Nonmutating)) + { + // + // Fine: typically an old client still using the deprecated nonmutating keyword + // + } + else + { + std::ostringstream reason; + reason << "unexpected operation mode. expected = " + << operationModeToString(expected) + << " received = " + << operationModeToString(received); + throw Ice::MarshalException(__FILE__, __LINE__, reason.str()); + } + } +} + +bool +Ice::Blobject::_iceDispatch(Incoming& in, const Current& current) +{ + const Byte* inEncaps; + Int sz; + in.readParamEncaps(inEncaps, sz); + vector outEncaps; + bool ok = ice_invoke(vector(inEncaps, inEncaps + sz), outEncaps, current); + if(outEncaps.empty()) + { + in.writeParamEncaps(0, 0, ok); + } + else + { + in.writeParamEncaps(&outEncaps[0], static_cast(outEncaps.size()), ok); + } + return true; +} + +bool +Ice::BlobjectArray::_iceDispatch(Incoming& in, const Current& current) +{ + pair inEncaps; + Int sz; + in.readParamEncaps(inEncaps.first, sz); + inEncaps.second = inEncaps.first + sz; + vector outEncaps; + bool ok = ice_invoke(inEncaps, outEncaps, current); + if(outEncaps.empty()) + { + in.writeParamEncaps(0, 0, ok); + } + else + { + in.writeParamEncaps(&outEncaps[0], static_cast(outEncaps.size()), ok); + } + return true; +} + +bool +Ice::BlobjectAsync::_iceDispatch(Incoming& in, const Current& current) +{ + const Byte* inEncaps; + Int sz; + in.readParamEncaps(inEncaps, sz); +#ifdef ICE_CPP11_MAPPING + auto async = IncomingAsync::create(in); + ice_invokeAsync(vector(inEncaps, inEncaps + sz), + [async](bool ok, const vector& outEncaps) + { + if(outEncaps.empty()) + { + async->writeParamEncaps(0, 0, ok); + } + else + { + async->writeParamEncaps(&outEncaps[0], static_cast(outEncaps.size()), ok); + } + async->completed(); + }, + async->exception(), current); +#else + ice_invoke_async(new ::IceAsync::Ice::AMD_Object_ice_invoke(in), vector(inEncaps, inEncaps + sz), current); +#endif + return false; +} + +bool +Ice::BlobjectArrayAsync::_iceDispatch(Incoming& in, const Current& current) +{ + pair inEncaps; + Int sz; + in.readParamEncaps(inEncaps.first, sz); + inEncaps.second = inEncaps.first + sz; +#ifdef ICE_CPP11_MAPPING + auto async = IncomingAsync::create(in); + ice_invokeAsync(inEncaps, + [async](bool ok, const pair& outE) + { + async->writeParamEncaps(outE.first, static_cast(outE.second - outE.first), ok); + async->completed(); + }, + async->exception(), current); +#else + ice_invoke_async(new ::IceAsync::Ice::AMD_Object_ice_invoke(in), inEncaps, current); +#endif + return false; +} diff --git a/Sources/IceCpp/ObjectAdapter.cpp b/Sources/IceCpp/ObjectAdapter.cpp new file mode 100644 index 0000000..c36dc29 --- /dev/null +++ b/Sources/IceCpp/ObjectAdapter.cpp @@ -0,0 +1,79 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapter.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ObjectAdapter::~ObjectAdapter() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ObjectAdapter::~ObjectAdapter() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ObjectAdapter* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ObjectAdapterF.cpp b/Sources/IceCpp/ObjectAdapterF.cpp new file mode 100644 index 0000000..058e681 --- /dev/null +++ b/Sources/IceCpp/ObjectAdapterF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapterF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ObjectAdapterFactory.cpp b/Sources/IceCpp/ObjectAdapterFactory.cpp new file mode 100644 index 0000000..b5f574c --- /dev/null +++ b/Sources/IceCpp/ObjectAdapterFactory.cpp @@ -0,0 +1,291 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(ObjectAdapterFactory* p) { return p; } +#endif + +void +IceInternal::ObjectAdapterFactory::shutdown() +{ + list adapters; + + { + IceUtil::Monitor::Lock sync(*this); + + // + // Ignore shutdown requests if the object adapter factory has + // already been shut down. + // + if(!_instance) + { + return; + } + + adapters = _adapters; + + _instance = ICE_NULLPTR; + _communicator = ICE_NULLPTR; + + notifyAll(); + } + + // + // Deactivate outside the thread synchronization, to avoid + // deadlocks. + // +#ifdef ICE_CPP11_COMPILER + for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->deactivate(); }); +#else + for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::deactivate)); +#endif +} + +void +IceInternal::ObjectAdapterFactory::waitForShutdown() +{ + list adapters; + + { + IceUtil::Monitor::Lock sync(*this); + + // + // First we wait for the shutdown of the factory itself. + // + while(_instance) + { + wait(); + } + + adapters = _adapters; + } + + // + // Now we wait for deactivation of each object adapter. + // +#ifdef ICE_CPP11_COMPILER + for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->waitForDeactivate(); }); +#else + for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::waitForDeactivate)); +#endif +} + +bool +IceInternal::ObjectAdapterFactory::isShutdown() const +{ + IceUtil::Monitor::Lock sync(*this); + + return _instance == 0; +} + +void +IceInternal::ObjectAdapterFactory::destroy() +{ + // + // First wait for shutdown to finish. + // + waitForShutdown(); + + list adapters; + + { + IceUtil::Monitor::Lock sync(*this); + adapters = _adapters; + } + + // + // Now we destroy each object adapter. + // +#ifdef ICE_CPP11_COMPILER + for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->destroy(); }); +#else + for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::destroy)); +#endif + { + IceUtil::Monitor::Lock sync(*this); + _adapters.clear(); + } +} + +void +IceInternal::ObjectAdapterFactory::updateObservers(void (ObjectAdapterI::*fn)()) +{ + list adapters; + + { + IceUtil::Monitor::Lock sync(*this); + adapters = _adapters; + } +#ifdef ICE_CPP11_COMPILER + for_each(adapters.begin(), adapters.end(), + [fn](const ObjectAdapterIPtr& adapter) + { + (adapter.get() ->* fn)(); + }); +#else + for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(fn)); +#endif +} + +ObjectAdapterPtr +IceInternal::ObjectAdapterFactory::createObjectAdapter(const string& name, const RouterPrxPtr& router) +{ + ObjectAdapterIPtr adapter; + { + IceUtil::Monitor::Lock sync(*this); + + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(name.empty()) + { + string uuid = Ice::generateUUID(); + adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true); + } + else + { + if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name); + } + adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false); + _adapterNamesInUse.insert(name); + } + } + + // + // Must be called outside the synchronization since initialize can make client invocations + // on the router if it's set. + // + bool initialized = false; + try + { + adapter->initialize(router); + initialized = true; + + IceUtil::Monitor::Lock sync(*this); + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + _adapters.push_back(adapter); + } + catch(const Ice::CommunicatorDestroyedException&) + { + if(initialized) + { + adapter->destroy(); + } + throw; + } + catch(const std::exception&) + { + if(!name.empty()) + { + IceUtil::Monitor::Lock sync(*this); + _adapterNamesInUse.erase(name); + } + throw; + } + + return adapter; +} + +ObjectAdapterPtr +IceInternal::ObjectAdapterFactory::findObjectAdapter(const ObjectPrxPtr& proxy) +{ + list adapters; + { + IceUtil::Monitor::Lock sync(*this); + + if(!_instance) + { + return ICE_NULLPTR; + } + + adapters = _adapters; + } + + for(list::iterator p = adapters.begin(); p != adapters.end(); ++p) + { + try + { + if((*p)->isLocal(proxy)) + { + return *p; + } + } + catch(const ObjectAdapterDeactivatedException&) + { + // Ignore. + } + } + + return ICE_NULLPTR; +} + +void +IceInternal::ObjectAdapterFactory::removeObjectAdapter(const ObjectAdapterPtr& adapter) +{ + IceUtil::Monitor::Lock sync(*this); + + if(!_instance) + { + return; + } + + for(list::iterator p = _adapters.begin(); p != _adapters.end(); ++p) + { + if(*p == adapter) + { + _adapters.erase(p); + break; + } + } + _adapterNamesInUse.erase(adapter->getName()); +} + +void +IceInternal::ObjectAdapterFactory::flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr& outAsync, + CompressBatch compressBatch) const +{ + list adapters; + { + IceUtil::Monitor::Lock sync(*this); + + adapters = _adapters; + } + + for(list::const_iterator p = adapters.begin(); p != adapters.end(); ++p) + { + (*p)->flushAsyncBatchRequests(outAsync, compressBatch); + } +} + +IceInternal::ObjectAdapterFactory::ObjectAdapterFactory(const InstancePtr& instance, + const CommunicatorPtr& communicator) : + _instance(instance), + _communicator(communicator) +{ +} + +IceInternal::ObjectAdapterFactory::~ObjectAdapterFactory() +{ + assert(!_instance); + assert(!_communicator); + assert(_adapters.empty()); +} diff --git a/Sources/IceCpp/ObjectAdapterI.cpp b/Sources/IceCpp/ObjectAdapterI.cpp new file mode 100644 index 0000000..9e9f561 --- /dev/null +++ b/Sources/IceCpp/ObjectAdapterI.cpp @@ -0,0 +1,1530 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#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 + +#ifdef _WIN32 +# include +#else +# include +#endif + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ +inline void checkIdentity(const Identity& ident) +{ + if(ident.name.empty()) + { + throw IllegalIdentityException(__FILE__, __LINE__, ident); + } +} + +inline void checkServant(const ObjectPtr& servant) +{ + if(!servant) + { + throw IllegalServantException(__FILE__, __LINE__, "cannot add null servant to Object Adapter"); + } +} + +inline EndpointIPtr toEndpointI(const EndpointPtr& endp) +{ + return ICE_DYNAMIC_CAST(EndpointI, endp); +} + +} + +string +Ice::ObjectAdapterI::getName() const ICE_NOEXCEPT +{ + // + // No mutex lock necessary, _name is immutable. + // + return _noConfig ? string("") : _name; +} + +CommunicatorPtr +Ice::ObjectAdapterI::getCommunicator() const ICE_NOEXCEPT +{ + return _communicator; +} + +void +Ice::ObjectAdapterI::activate() +{ + LocatorInfoPtr locatorInfo; + bool printAdapterReady = false; + + { + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + // + // If we've previously been initialized we just need to activate the + // incoming connection factories and we're done. + // + if(_state != StateUninitialized) + { +#ifdef ICE_CPP11_COMPILER + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->activate(); + }); +#else + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::activate)); +#endif + return; + } + + // + // One off initializations of the adapter: update the + // locator registry and print the "adapter ready" + // message. We set set state to StateActivating to prevent + // deactivation from other threads while these one off + // initializations are done. + // + _state = StateActivating; + + locatorInfo = _locatorInfo; + if(!_noConfig) + { + PropertiesPtr properties = _instance->initializationData().properties; + printAdapterReady = properties->getPropertyAsInt("Ice.PrintAdapterReady") > 0; + } + } + + try + { + Ice::Identity dummy; + dummy.name = "dummy"; + updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); + } + catch(const Ice::LocalException&) + { + // + // If we couldn't update the locator registry, we let the + // exception go through and don't activate the adapter to + // allow to user code to retry activating the adapter + // later. + // + { + IceUtil::Monitor::Lock sync(*this); + _state = StateUninitialized; + notifyAll(); + } + throw; + } + + if(printAdapterReady) + { + consoleOut << _name << " ready" << endl; + } + + { + IceUtil::Monitor::Lock sync(*this); + assert(_state == StateActivating); + +#ifdef ICE_CPP11_COMPILER + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->activate(); + }); +#else + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::activate)); +#endif + _state = StateActive; + notifyAll(); + } +} + +void +Ice::ObjectAdapterI::hold() +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + _state = StateHeld; + +#ifdef ICE_CPP11_COMPILER + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->hold(); + }); +#else + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::hold)); +#endif +} + +void +Ice::ObjectAdapterI::waitForHold() +{ + vector incomingConnectionFactories; + { + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + incomingConnectionFactories = _incomingConnectionFactories; + } + +#ifdef ICE_CPP11_COMPILER + for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->waitUntilHolding(); + }); +#else + for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(), + Ice::constVoidMemFun(&IncomingConnectionFactory::waitUntilHolding)); +#endif +} + +void +Ice::ObjectAdapterI::deactivate() ICE_NOEXCEPT +{ + { + IceUtil::Monitor::Lock sync(*this); + + // + // Wait for activation to complete. This is necessary to not + // get out of order locator updates. + // + while(_state == StateActivating || _state == StateDeactivating) + { + wait(); + } + if(_state >= StateDeactivated) + { + return; + } + _state = StateDeactivating; + } + + // + // NOTE: the router/locator infos and incoming connection + // facatory list are immutable at this point. + // + + try + { + if(_routerInfo) + { + // + // Remove entry from the router manager. + // + _instance->routerManager()->erase(_routerInfo->getRouter()); + + // + // Clear this object adapter with the router. + // + _routerInfo->setAdapter(0); + } + + updateLocatorRegistry(_locatorInfo, 0); + } + catch(const Ice::LocalException&) + { + // + // We can't throw exceptions in deactivate so we ignore + // failures to update the locator registry. + // + } + +#ifdef ICE_CPP11_COMPILER + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->destroy(); + }); +#else + for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::destroy)); +#endif + + _instance->outgoingConnectionFactory()->removeAdapter(ICE_SHARED_FROM_THIS); + + { + IceUtil::Monitor::Lock sync(*this); + assert(_state == StateDeactivating); + _state = StateDeactivated; + notifyAll(); + } +} + +void +Ice::ObjectAdapterI::waitForDeactivate() ICE_NOEXCEPT +{ + vector incomingConnectionFactories; + + { + IceUtil::Monitor::Lock sync(*this); + + // + // Wait for deactivation of the adapter itself, and for + // the return of all direct method calls using this adapter. + // + while((_state < StateDeactivated) || _directCount > 0) + { + wait(); + } + if(_state > StateDeactivated) + { + return; + } + incomingConnectionFactories = _incomingConnectionFactories; + } + + // + // Now we wait until all incoming connection factories are + // finished. + // +#ifdef ICE_CPP11_COMPILER + for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->waitUntilFinished(); + }); +#else + for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(), + Ice::voidMemFun(&IncomingConnectionFactory::waitUntilFinished)); +#endif +} + +bool +Ice::ObjectAdapterI::isDeactivated() const ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + + return _state >= StateDeactivated; +} + +void +Ice::ObjectAdapterI::destroy() ICE_NOEXCEPT +{ + // + // Deactivate and wait for completion. + // + deactivate(); + waitForDeactivate(); + + { + IceUtil::Monitor::Lock sync(*this); + assert(_state >= StateDeactivated); + + // + // Only a single thread is allowed to destroy the object + // adapter. Other threads wait for the destruction to be + // completed. + // + while(_state == StateDestroying) + { + wait(); + } + if(_state == StateDestroyed) + { + return; + } + _state = StateDestroying; + } + + // + // Now it's also time to clean up our servants and servant + // locators. + // + _servantManager->destroy(); + + // + // Destroy the thread pool. + // + if(_threadPool) + { + _threadPool->destroy(); + _threadPool->joinWithAllThreads(); + } + + if(_objectAdapterFactory) + { + _objectAdapterFactory->removeObjectAdapter(ICE_SHARED_FROM_THIS); + } + + { + IceUtil::Monitor::Lock sync(*this); + + // + // We're done, now we can throw away all incoming connection + // factories. + // + _incomingConnectionFactories.clear(); + + // + // Remove object references (some of them cyclic). + // + _instance = 0; + _threadPool = 0; + _routerInfo = 0; + _publishedEndpoints.clear(); + _locatorInfo = 0; + _reference = 0; + _objectAdapterFactory = 0; + + _state = StateDestroyed; + notifyAll(); + } +} + +ObjectPrxPtr +Ice::ObjectAdapterI::add(const ObjectPtr& object, const Identity& ident) +{ + return addFacet(object, ident, ""); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::addFacet(const ObjectPtr& object, const Identity& ident, const string& facet) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkServant(object); + checkIdentity(ident); + + _servantManager->addServant(object, ident, facet); + + return newProxy(ident, facet); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::addWithUUID(const ObjectPtr& object) +{ + return addFacetWithUUID(object, ""); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr& object, const string& facet) +{ + Identity ident; + ident.name = Ice::generateUUID(); + return addFacet(object, ident, facet); +} + +void +Ice::ObjectAdapterI::addDefaultServant(const ObjectPtr& servant, const string& category) +{ + checkServant(servant); + + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + _servantManager->addDefaultServant(servant, category); +} + +ObjectPtr +Ice::ObjectAdapterI::remove(const Identity& ident) +{ + return removeFacet(ident, ""); +} + +ObjectPtr +Ice::ObjectAdapterI::removeFacet(const Identity& ident, const string& facet) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return _servantManager->removeServant(ident, facet); +} + +FacetMap +Ice::ObjectAdapterI::removeAllFacets(const Identity& ident) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return _servantManager->removeAllFacets(ident); +} + +ObjectPtr +Ice::ObjectAdapterI::removeDefaultServant(const string& category) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->removeDefaultServant(category); +} + +ObjectPtr +Ice::ObjectAdapterI::find(const Identity& ident) const +{ + return findFacet(ident, ""); +} + +ObjectPtr +Ice::ObjectAdapterI::findFacet(const Identity& ident, const string& facet) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return _servantManager->findServant(ident, facet); +} + +FacetMap +Ice::ObjectAdapterI::findAllFacets(const Identity& ident) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return _servantManager->findAllFacets(ident); +} + +ObjectPtr +Ice::ObjectAdapterI::findByProxy(const ObjectPrxPtr& proxy) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + ReferencePtr ref = proxy->_getReference(); + return findFacet(ref->getIdentity(), ref->getFacet()); +} + +ObjectPtr +Ice::ObjectAdapterI::findDefaultServant(const string& category) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->findDefaultServant(category); +} + +void +Ice::ObjectAdapterI::addServantLocator(const ServantLocatorPtr& locator, const string& prefix) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + _servantManager->addServantLocator(locator, prefix); +} + +ServantLocatorPtr +Ice::ObjectAdapterI::removeServantLocator(const string& prefix) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->removeServantLocator(prefix); +} + +ServantLocatorPtr +Ice::ObjectAdapterI::findServantLocator(const string& prefix) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->findServantLocator(prefix); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::createProxy(const Identity& ident) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return newProxy(ident, ""); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::createDirectProxy(const Identity& ident) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return newDirectProxy(ident, ""); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::createIndirectProxy(const Identity& ident) const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + checkIdentity(ident); + + return newIndirectProxy(ident, "", _id); +} + +void +Ice::ObjectAdapterI::setLocator(const LocatorPrxPtr& locator) +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + _locatorInfo = _instance->locatorManager()->get(locator); +} + +LocatorPrxPtr +Ice::ObjectAdapterI::getLocator() const ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + + if(!_locatorInfo) + { + return 0; + } + else + { + return _locatorInfo->getLocator(); + } +} + +EndpointSeq +Ice::ObjectAdapterI::getEndpoints() const ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + + EndpointSeq endpoints; + transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), + back_inserter(endpoints), +#ifdef ICE_CPP11_COMPILER + [](const IncomingConnectionFactoryPtr& factory) + { + return factory->endpoint(); + }); +#else + Ice::constMemFun(&IncomingConnectionFactory::endpoint)); +#endif + return endpoints; +} + +void +Ice::ObjectAdapterI::refreshPublishedEndpoints() +{ + LocatorInfoPtr locatorInfo; + vector oldPublishedEndpoints; + + { + IceUtil::Monitor::Lock sync(*this); + checkForDeactivation(); + + oldPublishedEndpoints = _publishedEndpoints; + _publishedEndpoints = computePublishedEndpoints(); + + locatorInfo = _locatorInfo; + } + + try + { + Ice::Identity dummy; + dummy.name = "dummy"; + updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); + } + catch(const Ice::LocalException&) + { + IceUtil::Monitor::Lock sync(*this); + + // + // Restore the old published endpoints. + // + _publishedEndpoints = oldPublishedEndpoints; + throw; + } +} + +EndpointSeq +Ice::ObjectAdapterI::getPublishedEndpoints() const ICE_NOEXCEPT +{ + IceUtil::Monitor::Lock sync(*this); + return EndpointSeq(_publishedEndpoints.begin(), _publishedEndpoints.end()); +} + +void +Ice::ObjectAdapterI::setPublishedEndpoints(const EndpointSeq& newEndpoints) +{ + LocatorInfoPtr locatorInfo; + vector oldPublishedEndpoints; + { + IceUtil::Monitor::Lock sync(*this); + checkForDeactivation(); + + if(_routerInfo) + { + const string s("can't set published endpoints on object adapter associated with a router"); + #ifdef ICE_CPP11_MAPPING + throw invalid_argument(s); + #else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, s); + #endif + } + + oldPublishedEndpoints = _publishedEndpoints; + _publishedEndpoints.clear(); + transform(newEndpoints.begin(), newEndpoints.end(), back_inserter(_publishedEndpoints), toEndpointI); + + locatorInfo = _locatorInfo; + } + + try + { + Ice::Identity dummy; + dummy.name = "dummy"; + updateLocatorRegistry(locatorInfo, createDirectProxy(dummy)); + } + catch(const Ice::LocalException&) + { + IceUtil::Monitor::Lock sync(*this); + + // + // Restore the old published endpoints. + // + _publishedEndpoints = oldPublishedEndpoints; + throw; + } +} + +#ifdef ICE_SWIFT +dispatch_queue_t +Ice::ObjectAdapterI::getDispatchQueue() const +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + return getThreadPool()->getDispatchQueue(); +} +#endif + +bool +Ice::ObjectAdapterI::isLocal(const ObjectPrxPtr& proxy) const +{ + // + // NOTE: it's important that isLocal() doesn't perform any blocking operations as + // it can be called for AMI invocations if the proxy has no delegate set yet. + // + + ReferencePtr ref = proxy->_getReference(); + if(ref->isWellKnown()) + { + // + // Check the active servant map to see if the well-known + // proxy is for a local object. + // + return _servantManager->hasServant(ref->getIdentity()); + } + else if(ref->isIndirect()) + { + // + // Proxy is local if the reference adapter id matches this + // adapter id or replica group id. + // + return ref->getAdapterId() == _id || ref->getAdapterId() == _replicaGroupId; + } + else + { + vector endpoints = ref->getEndpoints(); + + IceUtil::Monitor::Lock sync(*this); + checkForDeactivation(); + + // + // Proxies which have at least one endpoint in common with the + // endpoints used by this object adapter are considered local. + // + for(vector::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + for(vector::const_iterator q = _incomingConnectionFactories.begin(); + q != _incomingConnectionFactories.end(); ++q) + { + if((*q)->isLocal(*p)) + { + return true; + } + } + + for(vector::const_iterator r = _publishedEndpoints.begin(); + r != _publishedEndpoints.end(); ++r) + { + if((*p)->equivalent(*r)) + { + return true; + } + } + } + } + + return false; +} + +void +Ice::ObjectAdapterI::flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr& outAsync, CompressBatch compress) +{ + vector f; + { + IceUtil::Monitor::Lock sync(*this); + f = _incomingConnectionFactories; + } + + for(vector::const_iterator p = f.begin(); p != f.end(); ++p) + { + (*p)->flushAsyncBatchRequests(outAsync, compress); + } +} + +void +Ice::ObjectAdapterI::updateConnectionObservers() +{ + vector f; + { + IceUtil::Monitor::Lock sync(*this); + f = _incomingConnectionFactories; + } +#ifdef ICE_CPP11_COMPILER + for_each(f.begin(), f.end(), + [](const IncomingConnectionFactoryPtr& factory) + { + factory->updateConnectionObservers(); + }); +#else + for_each(f.begin(), f.end(), Ice::voidMemFun(&IncomingConnectionFactory::updateConnectionObservers)); +#endif +} + +void +Ice::ObjectAdapterI::updateThreadObservers() +{ + ThreadPoolPtr threadPool; + { + IceUtil::Monitor::Lock sync(*this); + threadPool = _threadPool; + } + if(threadPool) + { + threadPool->updateObservers(); + } +} + +void +Ice::ObjectAdapterI::incDirectCount() +{ + IceUtil::Monitor::Lock sync(*this); + + checkForDeactivation(); + + assert(_directCount >= 0); + ++_directCount; +} + +void +Ice::ObjectAdapterI::decDirectCount() +{ + IceUtil::Monitor::Lock sync(*this); + + // Not check for deactivation here! + + assert(_instance); // Must not be called after destroy(). + + assert(_directCount > 0); + if(--_directCount == 0) + { + notifyAll(); + } +} + +ThreadPoolPtr +Ice::ObjectAdapterI::getThreadPool() const +{ + // No mutex lock necessary, _threadPool and _instance are + // immutable after creation until they are removed in + // destroy(). + + // Not check for deactivation here! + + assert(_instance); // Must not be called after destroy(). + + if(_threadPool) + { + return _threadPool; + } + else + { + return _instance->serverThreadPool(); + } +} + +ServantManagerPtr +Ice::ObjectAdapterI::getServantManager() const +{ + // + // No mutex lock necessary, _servantManager is immutable. + // + return _servantManager; +} + +IceInternal::ACMConfig +Ice::ObjectAdapterI::getACM() const +{ + // Not check for deactivation here! + + assert(_instance); // Must not be called after destroy(). + return _acm; +} + +void +Ice::ObjectAdapterI::setAdapterOnConnection(const Ice::ConnectionIPtr& connection) +{ + IceUtil::Monitor::Lock sync(*this); + checkForDeactivation(); + connection->setAdapterAndServantManager(ICE_SHARED_FROM_THIS, _servantManager); +} + +// +// COMPILERFIX: The ObjectAdapterI setup is broken out into a separate initialize +// function because when it was part of the constructor C++Builder 2010 apps would +// crash if an exception was thrown from any calls within the constructor. +// +Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const CommunicatorPtr& communicator, + const ObjectAdapterFactoryPtr& objectAdapterFactory, const string& name, + /*const RouterPrxPtr& router,*/ bool noConfig) : + _state(StateUninitialized), + _instance(instance), + _communicator(communicator), + _objectAdapterFactory(objectAdapterFactory), + _servantManager(new ServantManager(instance, name)), + _name(name), + _directCount(0), + _noConfig(noConfig), + _messageSizeMax(0) +{ +} + +void +Ice::ObjectAdapterI::initialize(const RouterPrxPtr& router) +{ + if(_noConfig) + { + _reference = _instance->referenceFactory()->create("dummy -t", ""); + const_cast(_acm) = _instance->serverACM(); + return; + } + + PropertiesPtr properties = _instance->initializationData().properties; + StringSeq unknownProps; + bool noProps = filterProperties(unknownProps); + + // + // Warn about unknown object adapter properties. + // + if(unknownProps.size() != 0 && properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) + { + Warning out(_instance->initializationData().logger); + out << "found unknown properties for object adapter `" << _name << "':"; + for(unsigned int i = 0; i < unknownProps.size(); ++i) + { + out << "\n " << unknownProps[i]; + } + } + + try + { + // + // Make sure named adapter has some configuration + // + if(router == 0 && noProps) + { + throw InitializationException(__FILE__, __LINE__, "object adapter `" + _name + "' requires configuration"); + } + + const_cast(_id) = properties->getProperty(_name + ".AdapterId"); + const_cast(_replicaGroupId) = properties->getProperty(_name + ".ReplicaGroupId"); + + // + // Setup a reference to be used to get the default proxy options + // when creating new proxies. By default, create twoway proxies. + // + string proxyOptions = properties->getPropertyWithDefault(_name + ".ProxyOptions", "-t"); + try + { + _reference = _instance->referenceFactory()->create("dummy " + proxyOptions, ""); + } + catch(const ProxyParseException&) + { + throw InitializationException(__FILE__, __LINE__, "invalid proxy options `" + proxyOptions + + "' for object adapter `" + _name + "'"); + } + + const_cast(_acm) = + ACMConfig(properties, _communicator->getLogger(), _name + ".ACM", _instance->serverACM()); + + { + const int defaultMessageSizeMax = static_cast(_instance->messageSizeMax() / 1024); + Int num = properties->getPropertyAsIntWithDefault(_name + ".MessageSizeMax", defaultMessageSizeMax); + if(num < 1 || static_cast(num) > static_cast(0x7fffffff / 1024)) + { + const_cast(_messageSizeMax) = static_cast(0x7fffffff); + } + else + { + const_cast(_messageSizeMax) = static_cast(num) * 1024; + } + } + + int threadPoolSize = properties->getPropertyAsInt(_name + ".ThreadPool.Size"); + int threadPoolSizeMax = properties->getPropertyAsInt(_name + ".ThreadPool.SizeMax"); + bool hasPriority = properties->getProperty(_name + ".ThreadPool.ThreadPriority") != ""; + + // + // Create the per-adapter thread pool, if necessary. This is done before the creation of the incoming + // connection factory as the thread pool is needed during creation for the call to incFdsInUse. + // + if(threadPoolSize > 0 || threadPoolSizeMax > 0 || hasPriority) + { + _threadPool = new ThreadPool(_instance, _name + ".ThreadPool", 0); + } + + if(!router) + { + const_cast(router) = ICE_UNCHECKED_CAST(RouterPrx, + _instance->proxyFactory()->propertyToProxy(_name + ".Router")); + } + if(router) + { + _routerInfo = _instance->routerManager()->get(router); + assert(_routerInfo); + + // + // Make sure this router is not already registered with another adapter. + // + if(_routerInfo->getAdapter()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, + "object adapter with router", + _communicator->identityToString(router->ice_getIdentity())); + } + + // + // Associate this object adapter with the router. This way, new outgoing connections + // to the router's client proxy will use this object adapter for callbacks. + // + _routerInfo->setAdapter(ICE_SHARED_FROM_THIS); + + // + // Also modify all existing outgoing connections to the router's client proxy to use + // this object adapter for callbacks. + // + _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo); + } + else + { + // + // Parse the endpoints, but don't store them in the adapter. + // The connection factory might change it, for example, to + // fill in the real port number. + // + vector endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"), true); + for(vector::iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + EndpointIPtr publishedEndpoint; + vector expanded = (*p)->expandHost(publishedEndpoint); + for(vector::iterator q = expanded.begin(); q != expanded.end(); ++q) + { + IncomingConnectionFactoryPtr factory = ICE_MAKE_SHARED(IncomingConnectionFactory, + _instance, + *q, + publishedEndpoint, + ICE_SHARED_FROM_THIS); + factory->initialize(); + _incomingConnectionFactories.push_back(factory); + } + } + if(endpoints.empty()) + { + TraceLevelsPtr tl = _instance->traceLevels(); + if(tl->network >= 2) + { + Trace out(_instance->initializationData().logger, tl->networkCat); + out << "created adapter `" << _name << "' without endpoints"; + } + } + } + + // + // Compute the published endpoints. + // + _publishedEndpoints = computePublishedEndpoints(); + + if(!properties->getProperty(_name + ".Locator").empty()) + { + setLocator(ICE_UNCHECKED_CAST(LocatorPrx, _instance->proxyFactory()->propertyToProxy(_name + ".Locator"))); + } + else + { + setLocator(_instance->referenceFactory()->getDefaultLocator()); + } + } + catch(...) + { + destroy(); + throw; + } +} + +Ice::ObjectAdapterI::~ObjectAdapterI() +{ + if(_state < StateDeactivated) + { + Warning out(_instance->initializationData().logger); + out << "object adapter `" << getName() << "' has not been deactivated"; + } + else if(_state != StateDestroyed) + { + Warning out(_instance->initializationData().logger); + out << "object adapter `" << getName() << "' has not been destroyed"; + } + else + { + //assert(!_servantManager); // We don't clear this reference, it needs to be immutable. + assert(!_threadPool); + assert(_incomingConnectionFactories.empty()); + assert(_directCount == 0); + } +} + +ObjectPrxPtr +Ice::ObjectAdapterI::newProxy(const Identity& ident, const string& facet) const +{ + if(_id.empty()) + { + return newDirectProxy(ident, facet); + } + else if(_replicaGroupId.empty()) + { + return newIndirectProxy(ident, facet, _id); + } + else + { + return newIndirectProxy(ident, facet, _replicaGroupId); + } +} + +ObjectPrxPtr +Ice::ObjectAdapterI::newDirectProxy(const Identity& ident, const string& facet) const +{ + // + // Create a reference and return a proxy for this reference. + // + ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, _publishedEndpoints); + return _instance->proxyFactory()->referenceToProxy(ref); +} + +ObjectPrxPtr +Ice::ObjectAdapterI::newIndirectProxy(const Identity& ident, const string& facet, const string& id) const +{ + // + // Create an indirect reference with the given adapter id. + // + ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, id); + + // + // Return a proxy for the reference. + // + return _instance->proxyFactory()->referenceToProxy(ref); +} + +void +Ice::ObjectAdapterI::checkForDeactivation() const +{ + if(_state >= StateDeactivating) + { + throw ObjectAdapterDeactivatedException(__FILE__, __LINE__, getName()); + } +} + +vector +Ice::ObjectAdapterI::parseEndpoints(const string& endpts, bool oaEndpoints) const +{ + string::size_type beg; + string::size_type end = 0; + + vector endpoints; + while(end < endpts.length()) + { + const string delim = " \t\n\r"; + + beg = endpts.find_first_not_of(delim, end); + if(beg == string::npos) + { + if(!endpoints.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid empty object adapter endpoint"); + } + break; + } + + end = beg; + while(true) + { + end = endpts.find(':', end); + if(end == string::npos) + { + end = endpts.length(); + break; + } + else + { + bool quoted = false; + string::size_type quote = beg; + while(true) + { + quote = endpts.find('\"', quote); + if(quote == string::npos || end < quote) + { + break; + } + else + { + quote = endpts.find('\"', ++quote); + if(quote == string::npos) + { + break; + } + else if(end < quote) + { + quoted = true; + break; + } + ++quote; + } + } + if(!quoted) + { + break; + } + ++end; + } + } + + if(end == beg) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid empty object adapter endpoint"); + } + + string s = endpts.substr(beg, end - beg); + EndpointIPtr endp = _instance->endpointFactoryManager()->create(s, oaEndpoints); + if(endp == 0) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid object adapter endpoint `" + s + "'"); + } + endpoints.push_back(endp); + + ++end; + } + + return endpoints; +} + +std::vector +ObjectAdapterI::computePublishedEndpoints() +{ + vector endpoints; + if(_routerInfo) + { + // + // Get the router's server proxy endpoints and use them as the published endpoints. + // + vector endps = _routerInfo->getServerEndpoints(); + for(vector::const_iterator p = endps.begin(); p != endps.end(); ++p) + { + if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end()) + { + endpoints.push_back(*p); + } + } + } + else + { + // + // Parse published endpoints. If set, these are used in proxies + // instead of the connection factory endpoints. + // + string endpts = _communicator->getProperties()->getProperty(_name + ".PublishedEndpoints"); + endpoints = parseEndpoints(endpts, false); + if(endpoints.empty()) + { + // + // If the PublishedEndpoints property isn't set, we compute the published enpdoints + // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY + // to include actual addresses in the published endpoints. + // + for(unsigned int i = 0; i < _incomingConnectionFactories.size(); ++i) + { + vector endps = _incomingConnectionFactories[i]->endpoint()->expandIfWildcard(); + for(vector::const_iterator p = endps.begin(); p != endps.end(); ++p) + { + // + // Check for duplicate endpoints, this might occur if an endpoint with a DNS name + // expands to multiple addresses. In this case, multiple incoming connection + // factories can point to the same published endpoint. + // + if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end()) + { + endpoints.push_back(*p); + } + } + } + } + } + + if(_instance->traceLevels()->network >= 1 && !endpoints.empty()) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat); + out << "published endpoints for object adapter `" << getName() << "':\n"; + for(unsigned int i = 0; i < endpoints.size(); ++i) + { + if(i > 0) + { + out << ":"; + } + out << endpoints[i]->toString(); + } + } + + return endpoints; +} + +void +ObjectAdapterI::updateLocatorRegistry(const IceInternal::LocatorInfoPtr& locatorInfo, const Ice::ObjectPrxPtr& proxy) +{ + if(_id.empty() || !locatorInfo) + { + return; // Nothing to update. + } + + LocatorRegistryPrxPtr locatorRegistry = locatorInfo->getLocatorRegistry(); + if(!locatorRegistry) + { + return; + } + + try + { + if(_replicaGroupId.empty()) + { + locatorRegistry->setAdapterDirectProxy(_id, proxy); + } + else + { + locatorRegistry->setReplicatedAdapterDirectProxy(_id, _replicaGroupId, proxy); + } + } + catch(const AdapterNotFoundException&) + { + if(_instance->traceLevels()->location >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat); + out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"; + out << "the object adapter is not known to the locator registry"; + } + + throw NotRegisteredException(__FILE__, __LINE__, "object adapter", _id); + } + catch(const InvalidReplicaGroupIdException&) + { + if(_instance->traceLevels()->location >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat); + out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"; + out << "the replica group `" << _replicaGroupId << "' is not known to the locator registry"; + } + + throw NotRegisteredException(__FILE__, __LINE__, "replica group", _replicaGroupId); + } + catch(const AdapterAlreadyActiveException&) + { + if(_instance->traceLevels()->location >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat); + out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n"; + out << "the object adapter endpoints are already set"; + } + + throw ObjectAdapterIdInUseException(__FILE__, __LINE__, _id); + } + catch(const ObjectAdapterDeactivatedException&) + { + // Expected if collocated call and OA is deactivated, ignore. + } + catch(const CommunicatorDestroyedException&) + { + // Ignore. + } + catch(const LocalException& ex) + { + if(_instance->traceLevels()->location >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat); + out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n" << ex; + } + throw; // TODO: Shall we raise a special exception instead of a non obvious local exception? + } + + if(_instance->traceLevels()->location >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat); + out << "updated object adapter `" + _id + "' endpoints with the locator registry\n"; + out << "endpoints = "; + if(proxy) + { + EndpointSeq endpts = proxy ? proxy->ice_getEndpoints() : EndpointSeq(); + ostringstream o; +#ifdef ICE_CPP11_COMPILER + transform(endpts.begin(), endpts.end(), ostream_iterator(o, endpts.size() > 1 ? ":" : ""), + [](const EndpointPtr& endpoint) + { + return endpoint->toString(); + }); +#else + transform(endpts.begin(), endpts.end(), ostream_iterator(o, endpts.size() > 1 ? ":" : ""), + Ice::constMemFun(&Endpoint::toString)); +#endif + out << o.str(); + } + } +} + +bool +Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps) +{ + static const string suffixes[] = + { + "ACM", + "ACM.Close", + "ACM.Heartbeat", + "ACM.Timeout", + "AdapterId", + "Endpoints", + "Locator", + "Locator.EncodingVersion", + "Locator.EndpointSelection", + "Locator.ConnectionCached", + "Locator.PreferSecure", + "Locator.CollocationOptimized", + "Locator.Router", + "MessageSizeMax", + "PublishedEndpoints", + "ReplicaGroupId", + "Router", + "Router.EncodingVersion", + "Router.EndpointSelection", + "Router.ConnectionCached", + "Router.PreferSecure", + "Router.CollocationOptimized", + "Router.Locator", + "Router.Locator.EndpointSelection", + "Router.Locator.ConnectionCached", + "Router.Locator.PreferSecure", + "Router.Locator.CollocationOptimized", + "Router.Locator.LocatorCacheTimeout", + "Router.Locator.InvocationTimeout", + "Router.LocatorCacheTimeout", + "Router.InvocationTimeout", + "ProxyOptions", + "ThreadPool.Size", + "ThreadPool.SizeMax", + "ThreadPool.SizeWarn", + "ThreadPool.StackSize", + "ThreadPool.Serialize", + "ThreadPool.ThreadPriority" + }; + + // + // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc + // + bool addUnknown = true; + string prefix = _name + "."; + for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) + { + string icePrefix = string(*i) + "."; + if(prefix.find(icePrefix) == 0) + { + addUnknown = false; + break; + } + } + + bool noProps = true; + PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix); + for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) + { + bool valid = false; + for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) + { + string prop = prefix + suffixes[i]; + if(p->first == prop) + { + noProps = false; + valid = true; + break; + } + } + + if(!valid && addUnknown) + { + unknownProps.push_back(p->first); + } + } + + return noProps; +} diff --git a/Sources/IceCpp/ObjectFactory.cpp b/Sources/IceCpp/ObjectFactory.cpp new file mode 100644 index 0000000..43c6a1f --- /dev/null +++ b/Sources/IceCpp/ObjectFactory.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ObjectFactory::~ObjectFactory() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ObjectFactory::~ObjectFactory() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ObjectFactory* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ObserverHelper.cpp b/Sources/IceCpp/ObserverHelper.cpp new file mode 100644 index 0000000..3fe7e35 --- /dev/null +++ b/Sources/IceCpp/ObserverHelper.cpp @@ -0,0 +1,56 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; + +IceInternal::InvocationObserver::InvocationObserver(const Ice::ObjectPrxPtr& proxy, const string& op, const Context& ctx) +{ + const CommunicatorObserverPtr& obsv = proxy->_getReference()->getInstance()->initializationData().observer; + if(!obsv) + { + return; + } + attach(obsv->getInvocationObserver(proxy, op, ctx)); +} + +IceInternal::InvocationObserver::InvocationObserver(IceInternal::Instance* instance, const string& op) +{ + const CommunicatorObserverPtr& obsv = instance->initializationData().observer; + if(!obsv) + { + return; + } + + attach(obsv->getInvocationObserver(0, op, noExplicitContext)); +} + +void +IceInternal::InvocationObserver::attach(const Ice::ObjectPrxPtr& proxy, const string& op, const Context& ctx) +{ + const CommunicatorObserverPtr& obsv = proxy->_getReference()->getInstance()->initializationData().observer; + if(!obsv) + { + return; + } + attach(obsv->getInvocationObserver(proxy, op, ctx)); +} + +void +IceInternal::InvocationObserver::attach(IceInternal::Instance* instance, const string& op) +{ + const CommunicatorObserverPtr& obsv = instance->initializationData().observer; + if(!obsv) + { + return; + } + + attach(obsv->getInvocationObserver(0, op, Ice::noExplicitContext)); +} diff --git a/Sources/IceCpp/OpaqueEndpointI.cpp b/Sources/IceCpp/OpaqueEndpointI.cpp new file mode 100644 index 0000000..3252b6a --- /dev/null +++ b/Sources/IceCpp/OpaqueEndpointI.cpp @@ -0,0 +1,408 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +static string opaqueEndpointProtocol = "opaque"; +static string opaqueEndpointConnectionId; + +} + +IceInternal::OpaqueEndpointI::OpaqueEndpointI(vector& args) : + _type(-1), _rawEncoding(Encoding_1_0) +{ + initWithOptions(args); + + if(_type < 0) + { + throw EndpointParseException(__FILE__, __LINE__, "no -t option in endpoint " + toString()); + } + if(_rawBytes.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no -v option in endpoint " + toString()); + } +} + +IceInternal::OpaqueEndpointI::OpaqueEndpointI(Short type, InputStream* s) : _type(type) +{ + _rawEncoding = s->getEncoding(); + Int sz = s->getEncapsulationSize(); + s->readBlob(const_cast&>(_rawBytes), sz); +} + +namespace +{ + +class OpaqueEndpointInfoI : public Ice::OpaqueEndpointInfo +{ +public: + + OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncoding, const Ice::ByteSeq& rawBytes); + + virtual Ice::Short + type() const ICE_NOEXCEPT + { + return _type; + } + + virtual bool + datagram() const ICE_NOEXCEPT + { + return false; + } + + virtual bool + secure() const ICE_NOEXCEPT + { + return false; + } + +private: + + Ice::Short _type; +}; + +} +// +// COMPILERFIX: inlining this constructor causes crashes with gcc 4.0.1. +// +OpaqueEndpointInfoI::OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncodingP, + const Ice::ByteSeq& rawBytesP) : + Ice::OpaqueEndpointInfo(ICE_NULLPTR, -1, false, rawEncodingP, rawBytesP), + _type(type) +{ +} + +void +IceInternal::OpaqueEndpointI::streamWrite(OutputStream* s) const +{ + s->startEncapsulation(_rawEncoding, ICE_ENUM(FormatType, DefaultFormat)); + s->writeBlob(_rawBytes); + s->endEncapsulation(); +} + +Ice::EndpointInfoPtr +IceInternal::OpaqueEndpointI::getInfo() const ICE_NOEXCEPT +{ + return ICE_MAKE_SHARED(OpaqueEndpointInfoI, _type, _rawEncoding, _rawBytes); +} + +Short +IceInternal::OpaqueEndpointI::type() const +{ + return _type; +} + +const string& +IceInternal::OpaqueEndpointI::protocol() const +{ + return opaqueEndpointProtocol; +} + +Int +IceInternal::OpaqueEndpointI::timeout() const +{ + return -1; +} + +EndpointIPtr +IceInternal::OpaqueEndpointI::timeout(Int) const +{ + return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI); +} + +const string& +IceInternal::OpaqueEndpointI::connectionId() const +{ + return opaqueEndpointConnectionId; +} + +EndpointIPtr +IceInternal::OpaqueEndpointI::connectionId(const string&) const +{ + return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI); +} + +bool +IceInternal::OpaqueEndpointI::compress() const +{ + return false; +} + +EndpointIPtr +IceInternal::OpaqueEndpointI::compress(bool) const +{ + return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI); +} + +bool +IceInternal::OpaqueEndpointI::datagram() const +{ + return false; +} + +bool +IceInternal::OpaqueEndpointI::secure() const +{ + return false; +} + +TransceiverPtr +IceInternal::OpaqueEndpointI::transceiver() const +{ + return ICE_NULLPTR; +} + +void +IceInternal::OpaqueEndpointI::connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr& cb) const +{ + cb->connectors(vector()); +} + +AcceptorPtr +IceInternal::OpaqueEndpointI::acceptor(const string&) const +{ + return ICE_NULLPTR; +} + +vector +IceInternal::OpaqueEndpointI::expandIfWildcard() const +{ + vector endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI)); + return endps; +} + +vector +IceInternal::OpaqueEndpointI::expandHost(EndpointIPtr&) const +{ + vector endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI)); + return endps; +} + +bool +IceInternal::OpaqueEndpointI::equivalent(const EndpointIPtr&) const +{ + return false; +} + +Int +IceInternal::OpaqueEndpointI::hash() const +{ + Int h = 5381; + hashAdd(h, type()); + hashAdd(h, _rawEncoding.major); + hashAdd(h, _rawEncoding.minor); + hashAdd(h, _rawBytes); + return h; +} + +string +IceInternal::OpaqueEndpointI::options() const +{ + ostringstream s; + if(_type > -1) + { + s << " -t " << _type; + } + s << " -e " << _rawEncoding; + if(!_rawBytes.empty()) + { + s << " -v " << Base64::encode(_rawBytes); + } + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::OpaqueEndpointI::operator==(const Endpoint& r) const +#else +IceInternal::OpaqueEndpointI::operator==(const LocalObject& r) const +#endif +{ + const OpaqueEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_type != p->_type) + { + return false; + } + + if(_rawEncoding != p->_rawEncoding) + { + return false; + } + + if(_rawBytes != p->_rawBytes) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::OpaqueEndpointI::operator<(const Endpoint& r) const +#else +IceInternal::OpaqueEndpointI::operator<(const LocalObject& r) const +#endif +{ + const OpaqueEndpointI* p = dynamic_cast(&r); + if(!p) + { + const EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(_type < p->_type) + { + return true; + } + else if(p->_type < _type) + { + return false; + } + + if(_rawEncoding < p->_rawEncoding) + { + return true; + } + else if(p->_rawEncoding < _rawEncoding) + { + return false; + } + + if(_rawBytes < p->_rawBytes) + { + return true; + } + else if(p->_rawBytes < _rawBytes) + { + return false; + } + + return false; +} + +void +IceInternal::OpaqueEndpointI::streamWriteImpl(Ice::OutputStream*) const +{ + assert(false); +} + +bool +IceInternal::OpaqueEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + switch(option[1]) + { + case 't': + { + if(_type > -1) + { + throw EndpointParseException(__FILE__, __LINE__, "multiple -t options in endpoint " + endpoint); + } + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -t option in endpoint " + + endpoint); + } + istringstream p(argument); + Ice::Int t; + if(!(p >> t) || !p.eof()) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid type value `" + argument + "' in endpoint " + + endpoint); + } + else if(t < 0 || t > 65535) + { + throw EndpointParseException(__FILE__, __LINE__, "type value `" + argument + "' out of range in endpoint " + + endpoint); + } + _type = static_cast(t); + return true; + } + + case 'v': + { + if(!_rawBytes.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "multiple -v options in endpoint " + endpoint); + } + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -v option in endpoint " + endpoint); + } + for(string::size_type i = 0; i < argument.size(); ++i) + { + if(!Base64::isBase64(argument[i])) + { + ostringstream os; + os << "invalid base64 character `" << argument[i] << "' (ordinal " << static_cast(argument[i]) + << ") in endpoint " << endpoint; + throw EndpointParseException(__FILE__, __LINE__, os.str()); + } + } + const_cast&>(_rawBytes) = Base64::decode(argument); + return true; + } + + case 'e': + { + if(argument.empty()) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "no argument provided for -e option in endpoint " + + endpoint); + } + + try + { + _rawEncoding = Ice::stringToEncodingVersion(argument); + } + catch(const Ice::VersionParseException& ex) + { + throw Ice::EndpointParseException(__FILE__, __LINE__, "invalid encoding version `" + argument + + "' in endpoint " + endpoint + ":\n" + ex.str); + } + return true; + } + + default: + { + return false; + } + } +} diff --git a/Sources/IceCpp/Options.cpp b/Sources/IceCpp/Options.cpp new file mode 100644 index 0000000..dd3d11f --- /dev/null +++ b/Sources/IceCpp/Options.cpp @@ -0,0 +1,1051 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace IceUtil; + +IceUtilInternal::APIException::APIException(const char* file, int line, const string& r) + : IceUtil::ExceptionHelper(file, line), reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtilInternal::APIException::~APIException() throw() +{ +} +#endif + +string +IceUtilInternal::APIException::ice_id() const +{ + return "::IceUtilInternal::APIException"; +} + +void +IceUtilInternal::APIException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + if(!reason.empty()) + { + out << ": " << reason; + } +} + +#ifndef ICE_CPP11_MAPPING +IceUtilInternal::APIException* +IceUtilInternal::APIException::ice_clone() const +{ + return new APIException(*this); +} +#endif + +ostream& +IceUtilInternal::operator<<(ostream& out, const IceUtilInternal::APIException& ex) +{ + ex.ice_print(out); + return out; +} + +IceUtilInternal::BadOptException::BadOptException(const char* file, int line, const string& r) + : IceUtil::ExceptionHelper(file, line), reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtilInternal::BadOptException::~BadOptException() throw() +{ +} +#endif + +string +IceUtilInternal::BadOptException::ice_id() const +{ + return "::IceUtilInternal::BadOptException"; +} + +void +IceUtilInternal::BadOptException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + if(!reason.empty()) + { + out << ": " << reason; + } +} + +#ifndef ICE_CPP11_MAPPING +IceUtilInternal::BadOptException* +IceUtilInternal::BadOptException::ice_clone() const +{ + return new BadOptException(*this); +} +#endif + +ostream& +IceUtilInternal::operator<<(ostream& out, const IceUtilInternal::BadOptException& ex) +{ + ex.ice_print(out); + return out; +} + +IceUtilInternal::Options::Options() + : parseCalled(false) +{ +} + +void +IceUtilInternal::Options::checkArgs(const string& shortOpt, const string& longOpt, bool needArg, const string& dflt) +{ + if(shortOpt.empty() && longOpt.empty()) + { + throw IllegalArgumentException(__FILE__, __LINE__, "short and long option cannot both be empty"); + } + + if(!shortOpt.empty()) + { + if(shortOpt.size() != 1) + { + string err = "`"; + err += shortOpt; + err += "': a short option cannot specify more than one option"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + if(shortOpt.find_first_of(" \t\n\r\f\v") != string::npos) + { + string err = "`"; + err += shortOpt; + err += "': a short option cannot be whitespace"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + if(shortOpt[0] == '-') + { + string err = "`"; + err += shortOpt; + err += "': a short option cannot be `-'"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + } + + if(!longOpt.empty()) + { + if(longOpt.find_first_of(" \t\n\r\f\v") != string::npos) + { + string err = "`"; + err += longOpt; + err += "': a long option cannot contain whitespace"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + if(longOpt[0] == '-') + { + string err = "`"; + err += longOpt; + err += "': a long option must not contain a leading `-'"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + } + + if(!needArg && !dflt.empty()) + { + throw IllegalArgumentException(__FILE__, __LINE__, + "a default value can be specified only for options requiring an argument"); + } +} + +void +IceUtilInternal::Options::addOpt(const string& shortOpt, const string& longOpt, ArgType at, string dflt, RepeatType rt) +{ + RecMutex::Lock sync(_m); + + if(parseCalled) + { + throw APIException(__FILE__, __LINE__, "cannot add options after parse() was called"); + } + + checkArgs(shortOpt, longOpt, at == NeedArg, dflt); + + addValidOpt(shortOpt, longOpt, at, dflt, rt); +} + +// +// Split a command line into argv-style arguments, applying +// bash quoting rules. The return value is the arguments +// in the command line, with all shell escapes applied, and +// quotes removed. +// + +IceUtilInternal::Options::StringVector +IceUtilInternal::Options::split(const string& line) +{ + const string IFS = " \t\n"; // Internal Field Separator. + + // + // Strip leading and trailing whitespace. + // + string::size_type start = line.find_first_not_of(IFS); + if(start == string::npos) + { + return StringVector(); + } + string::size_type end = line.find_last_not_of(IFS); + assert(end != string::npos); + + string l(line, start, end - start + 1); + + StringVector vec; + + enum ParseState { Normal, DoubleQuote, SingleQuote, ANSIQuote }; + ParseState state = Normal; + + string arg; + + for(string::size_type i = 0; i < l.size(); ++i) + { + char c = l[i]; + switch(state) + { + case Normal: + { + switch(c) + { + case '\\': + { + // + // Ignore a backslash at the end of the string, + // and strip backslash-newline pairs. If a + // backslash is followed by a space, single quote, + // double quote, or dollar sign, we drop the backslash + // and write the space, single quote, double quote, + // or dollar sign. This is necessary to allow quotes + // to be escaped. Dropping the backslash preceding a + // space deviates from bash quoting rules, but is + // necessary so we don't drop backslashes from Windows + // path names.) + // + if(i < l.size() - 1 && l[++i] != '\n') + { + switch(l[i]) + { + case ' ': + case '$': + case '\'': + case '"': + { + arg.push_back(l[i]); + break; + } + default: + { + arg.push_back('\\'); + arg.push_back(l[i]); + break; + } + } + } + break; + } + case '\'': + { + state = SingleQuote; + break; + } + case '"': + { + state = DoubleQuote; + break; + } + case '$': + { + if(i < l.size() - 1 && l[i + 1] == '\'') + { + state = ANSIQuote; // Bash uses $'' to allow ANSI escape sequences within . + ++i; + } + else + { + arg.push_back('$'); + } + break; + } + default: + { + if(IFS.find(l[i]) != string::npos) + { + vec.push_back(arg); + arg.clear(); + + // + // Move to start of next argument. + // + while(++i < l.size() && IFS.find(l[i]) != string::npos) + { + ; + } + --i; + } + else + { + arg.push_back(l[i]); + } + break; + } + } + break; + } + case DoubleQuote: + { + // + // Within double quotes, only backslash retains its special + // meaning, and only if followed by double quote, backslash, + // or newline. If not followed by one of these characters, + // both the backslash and the character are preserved. + // + if(c == '\\' && i < l.size() - 1) + { + switch(c = l[++i]) + { + case '"': + case '\\': + case '\n': + { + arg.push_back(c); + break; + } + default: + { + arg.push_back('\\'); + arg.push_back(c); + break; + } + } + } + else if(c == '"') // End of double-quote mode. + { + state = Normal; + } + else + { + arg.push_back(c); // Everything else is taken literally. + } + break; + } + case SingleQuote: + { + if(c == '\'') // End of single-quote mode. + { + state = Normal; + } + else + { + arg.push_back(c); // Everything else is taken literally. + } + break; + } + case ANSIQuote: + { + switch(c) + { + case '\\': + { + if(i == l.size() - 1) + { + break; + } + switch(c = l[++i]) + { + // + // Single-letter escape sequences. + // + case 'a': + { + arg.push_back('\a'); + break; + } + case 'b': + { + arg.push_back('\b'); + break; + } + case 'f': + { + arg.push_back('\f'); + break; + } + case 'n': + { + arg.push_back('\n'); + break; + } + case 'r': + { + arg.push_back('\r'); + break; + } + case 't': + { + arg.push_back('\t'); + break; + } + case 'v': + { + arg.push_back('\v'); + break; + } + case '\\': + { + arg.push_back('\\'); + break; + } + case '\'': + { + arg.push_back('\''); + break; + } + case 'e': // Not ANSI-C, but used by bash. + { + arg.push_back('\033'); + break; + } + + // + // Process up to three octal digits. + // + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + static const string octalDigits = "01234567"; + unsigned short us = 0; + string::size_type j; + for(j = i; + j < i + 3 && j < l.size() && octalDigits.find_first_of(c = l[j]) != string::npos; + ++j) + { + us = us * 8 + static_cast(c - '0'); + } + i = j - 1; + arg.push_back(static_cast(us)); + break; + } + + // + // Process up to two hex digits. + // + case 'x': + { + if(i < l.size() - 1 && !isxdigit(static_cast(l[i + 1]))) + { + arg.push_back('\\'); + arg.push_back('x'); + break; + } + + Int64 ull = 0; + string::size_type j; + for(j = i + 1; j < i + 3 && j < l.size() && + isxdigit(static_cast(c = l[j])); ++j) + { + ull *= 16; + if(isdigit(static_cast(c))) + { + ull += c - '0'; + } + else if(islower(static_cast(c))) + { + ull += c - 'a' + 10; + } + else + { + ull += c - 'A' + 10; + } + } + i = j - 1; + arg.push_back(static_cast(ull)); + break; + } + + // + // Process control-chars. + // + case 'c': + { + c = l[++i]; + if(IceUtilInternal::isAlpha(c) || c == '@' || (c >= '[' && c <= '_')) + { + arg.push_back(static_cast(toupper(static_cast(c)) - '@')); + } + else + { + // + // Bash does not define what should happen if a \c + // is not followed by a recognized control character. + // We simply treat this case like other unrecognized + // escape sequences, that is, we preserve the escape + // sequence unchanged. + // + arg.push_back('\\'); + arg.push_back('c'); + arg.push_back(c); + } + break; + } + + // + // If inside an ANSI-quoted string, a backslash isn't followed by + // one of the recognized characters, both the backslash and the + // character are preserved. + // + default: + { + arg.push_back('\\'); + arg.push_back(c); + break; + } + } + break; + } + case '\'': // End of ANSI-quote mode. + { + state = Normal; + break; + } + default: + { + arg.push_back(c); // Everything else is taken literally. + break; + } + } + break; + } + default: + { + assert(false); // Impossible parse state + break; + } + } + } + + switch(state) + { + case Normal: + { + vec.push_back(arg); + break; + } + case SingleQuote: + { + throw BadOptException(__FILE__, __LINE__, "missing closing single quote"); + break; + } + case DoubleQuote: + { + throw BadOptException(__FILE__, __LINE__, "missing closing double quote"); + break; + } + case ANSIQuote: + { + throw BadOptException(__FILE__, __LINE__, "unterminated $' quote"); + break; + } + default: + { + assert(false); // Impossible parse state + break; + } + } + + return vec; +} + +// +// Parse a vector of arguments and return the non-option +// arguments as the return value. Throw BadOptException if any of the +// options are invalid. +// Note that args[0] is ignored because that is the name +// of the executable. +// + +IceUtilInternal::Options::StringVector +IceUtilInternal::Options::parse(const StringVector& args) +{ + RecMutex::Lock sync(_m); + + if(parseCalled) + { + throw APIException(__FILE__, __LINE__, "cannot call parse() more than once on the same Option instance"); + } + parseCalled = true; + + set seenNonRepeatableOpts; // To catch repeated non-repeatable options. + + StringVector result; + + string::size_type i; + for(i = 1; i < args.size(); ++i) + { + if(args[i] == "-" || args[i] == "--") + { + ++i; + break; // "-" and "--" indicate end of options. + } + + string opt; + ValidOpts::iterator pos; + bool argDone = false; + + if(args[i].compare(0, 2, "--") == 0) + { + // + // Long option. If the option has an argument, it can either be separated by '=' + // or appear as a separate argument. For example, "--name value" is the same + // as "--name=value". + // + string::size_type p = args[i].find('=', 2); + if(p != string::npos) + { + opt = args[i].substr(2, p - 2); + } + else + { + opt = args[i].substr(2); + } + + pos = checkOpt(opt, LongOpt); + + if(pos->second->repeat == NoRepeat) + { + set::iterator seenPos = seenNonRepeatableOpts.find(opt); + if(seenPos != seenNonRepeatableOpts.end()) + { + string err = "`--"; + err += opt + ":' option cannot be repeated"; + throw BadOptException(__FILE__, __LINE__, err); + } + seenNonRepeatableOpts.insert(seenPos, opt); + string synonym = getSynonym(opt); + if(!synonym.empty()) + { + seenNonRepeatableOpts.insert(synonym); + } + } + + if(p != string::npos) + { + if(pos->second->arg == NoArg) + { + string err = "`"; + err += opt; + err += "': option does not take an argument"; + throw BadOptException(__FILE__, __LINE__, err); + } + else if(pos->second->arg == NeedArg && p == args[i].size() - 1) + { + string err = "`"; + err += opt; + err += "': option requires an argument"; + throw BadOptException(__FILE__, __LINE__, err); + } + setOpt(opt, "", args[i].substr(p + 1), pos->second->repeat); + argDone = true; + } + } + else if(!args[i].empty() && args[i][0] == '-') + { + // + // Short option. + // + for(string::size_type p = 1; p < args[i].size(); ++p) + { + opt.clear(); + opt.push_back(args[i][p]); + pos = checkOpt(opt, ShortOpt); + + if(pos->second->repeat == NoRepeat) + { + set::iterator seenPos = seenNonRepeatableOpts.find(opt); + if(seenPos != seenNonRepeatableOpts.end()) + { + string err = "`-"; + err += opt + ":' option cannot be repeated"; + throw BadOptException(__FILE__, __LINE__, err); + } + seenNonRepeatableOpts.insert(seenPos, opt); + string synonym = getSynonym(opt); + if(!synonym.empty()) + { + seenNonRepeatableOpts.insert(synonym); + } + } + + if(pos->second->arg == NeedArg) + { + if(p != args[i].size() - 1) + { + string optArg = args[i].substr(p + 1); + setOpt(opt, "", optArg, pos->second->repeat); + argDone = true; + break; + } + } + else + { + setOpt(opt, "", "1", pos->second->repeat); + argDone = true; + } + } + } + else + { + // + // Not an option or option argument. + // + result.push_back(args[i]); + argDone = true; + } + + if(!argDone) + { + if(pos->second->arg == NeedArg) // Need an argument that is separated by whitespace. + { + if(i == args.size() - 1) + { + string err = "`-"; + if(opt.size() != 1) + { + err += "-"; + } + err += opt; + err += "' option requires an argument"; + throw BadOptException(__FILE__, __LINE__, err); + } + setOpt(opt, "", args[++i], pos->second->repeat); + } + else + { + setOpt(opt, "", "1", pos->second->repeat); + } + } + } + + _synonyms.clear(); // Don't need the contents anymore. + + while(i < args.size()) + { + result.push_back(args[i++]); + } + + return result; +} + +// +// Parse a normal argc/argv pair and return the non-option +// arguments as the return value. +// + +IceUtilInternal::Options::StringVector +IceUtilInternal::Options::parse(int argc, const char* const argv[]) +{ + StringVector vec; + for(int i = 0; i < argc; ++i) + { + vec.push_back(argv[i]); + } + return parse(vec); +} + +bool +IceUtilInternal::Options::isSet(const string& opt) const +{ + RecMutex::Lock sync(_m); + + if(!parseCalled) + { + throw APIException(__FILE__, __LINE__, "cannot lookup options before calling parse()"); + } + + ValidOpts::const_iterator pos = checkOptIsValid(opt); + return pos->second->repeat == NoRepeat ? _opts.find(opt) != _opts.end() : _ropts.find(opt) != _ropts.end(); +} + +string +IceUtilInternal::Options::optArg(const string& opt) const +{ + RecMutex::Lock sync(_m); + + if(!parseCalled) + { + throw APIException(__FILE__, __LINE__, "cannot lookup options before calling parse()"); + } + + ValidOpts::const_iterator pos = checkOptHasArg(opt); + + if(pos->second->repeat == Repeat) + { + string err = "`-"; + if(pos->second->length == LongOpt) + { + err.push_back('-'); + } + err += opt; + err += "': is a repeating option -- use argVec() to get its arguments"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + + Opts::const_iterator p = _opts.find(opt); + if(p == _opts.end()) + { + return ""; + } + return p->second->val; +} + +IceUtilInternal::Options::StringVector +IceUtilInternal::Options::argVec(const string& opt) const +{ + RecMutex::Lock sync(_m); + + if(!parseCalled) + { + throw APIException(__FILE__, __LINE__, "cannot lookup options before calling parse()"); + } + + ValidOpts::const_iterator pos = checkOptHasArg(opt); + + if(pos->second->repeat == NoRepeat) + { + string err = "`-"; + if(pos->second->length == LongOpt) + { + err.push_back('-'); + } + err += opt + "': is a non-repeating option -- use optArg() to get its argument"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + + ROpts::const_iterator p = _ropts.find(opt); + return p == _ropts.end() ? StringVector() : p->second->vals; +} + +void +IceUtilInternal::Options::addValidOpt(const string& shortOpt, const string& longOpt, + ArgType at, const string& dflt, RepeatType rt) +{ + if(!shortOpt.empty() && _validOpts.find(shortOpt) != _validOpts.end()) + { + string err = "`"; + err += shortOpt; + err += "': duplicate option"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + if(!longOpt.empty() && _validOpts.find(longOpt) != _validOpts.end()) + { + string err = "`"; + err += longOpt; + err += "': duplicate option"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + + ODPtr odp = new OptionDetails; + odp->arg = at; + odp->repeat = rt; + odp->hasDefault = !dflt.empty(); + + if(!shortOpt.empty()) + { + odp->length = ShortOpt; + _validOpts[shortOpt] = odp; + } + if(!longOpt.empty()) + { + odp->length = LongOpt; + _validOpts[longOpt] = odp; + } + + updateSynonyms(shortOpt, longOpt); + + if(at == NeedArg && !dflt.empty()) + { + setOpt(shortOpt, longOpt, dflt, rt); + } +} + +IceUtilInternal::Options::ValidOpts::iterator +IceUtilInternal::Options::checkOpt(const string& opt, LengthType lt) +{ + ValidOpts::iterator pos = _validOpts.find(opt); + if(pos == _validOpts.end()) + { + string err = "invalid option: `-"; + if(lt == LongOpt) + { + err.push_back('-'); + } + err += opt; + err.push_back('\''); + throw BadOptException(__FILE__, __LINE__, err); + } + return pos; +} + +void +IceUtilInternal::Options::setOpt(const string& opt1, const string& opt2, const string& val, RepeatType rt) +{ + // + // opt1 and opt2 (short and long opt) can't both be empty. + // + assert(!(opt1.empty() && opt2.empty())); + + if(rt == NoRepeat) + { + setNonRepeatingOpt(opt1, val); + setNonRepeatingOpt(opt2, val); + } + else + { + setRepeatingOpt(opt1, val); + setRepeatingOpt(opt2, val); + } +} + +void +IceUtilInternal::Options::setNonRepeatingOpt(const string& opt, const string& val) +{ + if(opt.empty()) + { + return; + } + + // + // The option must not have been set before or, if it was set, it must have + // been because of a default value. + // + assert(_opts.find(opt) == _opts.end() || _validOpts.find(opt)->second->hasDefault); + + OValPtr ovp = new OptionValue; + ovp->val = val; + _opts[opt] = ovp; + + const string synonym = getSynonym(opt); + if(!synonym.empty()) + { + _opts[synonym] = ovp; + } +} + +void +IceUtilInternal::Options::setRepeatingOpt(const string& opt, const string& val) +{ + if(opt.empty()) + { + return; + } + + ValidOpts::const_iterator vpos = _validOpts.find(opt); + assert(vpos != _validOpts.end()); + + ROpts::iterator pos = _ropts.find(opt); + const string synonym = getSynonym(opt); + ROpts::iterator spos = _ropts.find(synonym); + + if(pos != _ropts.end()) + { + assert(_validOpts.find(opt) != _validOpts.end()); + assert(vpos->second->repeat == Repeat); + + _ropts[opt] = pos->second; + if(vpos->second->hasDefault && pos->second->vals.size() == 1) + { + pos->second->vals[0] = val; + vpos->second->hasDefault = false; + } + else + { + pos->second->vals.push_back(val); + } + } + else if(spos != _ropts.end()) + { + assert(_validOpts.find(synonym) != _validOpts.end()); + assert(_validOpts.find(synonym)->second->repeat == Repeat); + + _ropts[synonym] = spos->second; + if(vpos->second->hasDefault && spos->second->vals.size() == 1) + { + spos->second->vals[0] = val; + vpos->second->hasDefault = false; + } + else + { + spos->second->vals.push_back(val); + } + } + else + { + OVecPtr ovp = new OptionValueVector; + ovp->vals.push_back(val); + _ropts[opt] = ovp; + if(!synonym.empty()) + { + _ropts[synonym] = ovp; + } + } +} + +IceUtilInternal::Options::ValidOpts::const_iterator +IceUtilInternal::Options::checkOptIsValid(const string& opt) const +{ + ValidOpts::const_iterator pos = _validOpts.find(opt); + if(pos == _validOpts.end()) + { + string err = "`"; + err += opt; + err += "': invalid option"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + return pos; +} + +IceUtilInternal::Options::ValidOpts::const_iterator +IceUtilInternal::Options::checkOptHasArg(const string& opt) const +{ + ValidOpts::const_iterator pos = checkOptIsValid(opt); + if(pos->second->arg == NoArg) + { + string err = "`-"; + if(pos->second->length == LongOpt) + { + err.push_back('-'); + } + err += opt; + err += "': option does not take arguments"; + throw IllegalArgumentException(__FILE__, __LINE__, err); + } + return pos; +} + +void +IceUtilInternal::Options::updateSynonyms(const ::std::string& shortOpt, const ::std::string& longOpt) +{ + if(!shortOpt.empty() && !longOpt.empty()) + { + _synonyms[shortOpt] = longOpt; + _synonyms[longOpt] = shortOpt; + } +} + +string +IceUtilInternal::Options::getSynonym(const ::std::string& optName) const +{ + Synonyms::const_iterator pos = _synonyms.find(optName); + return pos != _synonyms.end() ? pos->second : string(""); +} diff --git a/Sources/IceCpp/OutgoingAsync.cpp b/Sources/IceCpp/OutgoingAsync.cpp new file mode 100644 index 0000000..44ba61e --- /dev/null +++ b/Sources/IceCpp/OutgoingAsync.cpp @@ -0,0 +1,1322 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(OutgoingAsyncBase* p) { return p; } +IceUtil::Shared* IceInternal::upCast(ProxyOutgoingAsyncBase* p) { return p; } +IceUtil::Shared* IceInternal::upCast(OutgoingAsync* p) { return p; } +#endif + +const unsigned char OutgoingAsyncBase::OK = 0x1; +const unsigned char OutgoingAsyncBase::Sent = 0x2; +#ifndef ICE_CPP11_MAPPING +const unsigned char OutgoingAsyncBase::Done = 0x4; +const unsigned char OutgoingAsyncBase::EndCalled = 0x8; +#endif + +OutgoingAsyncCompletionCallback::~OutgoingAsyncCompletionCallback() +{ + // Out of line to avoid weak vtable +} + +bool +OutgoingAsyncBase::sent() +{ + return sentImpl(true); +} + +bool +OutgoingAsyncBase::exception(const Exception& ex) +{ + return exceptionImpl(ex); +} + +bool +OutgoingAsyncBase::response() +{ + assert(false); // Must be overriden by request that can handle responses + return false; +} + +void +OutgoingAsyncBase::invokeSentAsync() +{ + class AsynchronousSent : public DispatchWorkItem + { + public: + + AsynchronousSent(const ConnectionPtr& connection, const OutgoingAsyncBasePtr& outAsync) : + DispatchWorkItem(connection), _outAsync(outAsync) + { + } + + virtual void + run() + { + _outAsync->invokeSent(); + } + + private: + + const OutgoingAsyncBasePtr _outAsync; + }; + + // + // This is called when it's not safe to call the sent callback + // synchronously from this thread. Instead the exception callback + // is called asynchronously from the client thread pool. + // + try + { + _instance->clientThreadPool()->dispatch(new AsynchronousSent(_cachedConnection, ICE_SHARED_FROM_THIS)); + } + catch(const Ice::CommunicatorDestroyedException&) + { + } +} + +void +OutgoingAsyncBase::invokeExceptionAsync() +{ + class AsynchronousException : public DispatchWorkItem + { + public: + + AsynchronousException(const ConnectionPtr& c, const OutgoingAsyncBasePtr& outAsync) : + DispatchWorkItem(c), _outAsync(outAsync) + { + } + + virtual void + run() + { + _outAsync->invokeException(); + } + + private: + + const OutgoingAsyncBasePtr _outAsync; + }; + + // + // CommunicatorDestroyedException is the only exception that can propagate directly from this method. + // + _instance->clientThreadPool()->dispatch(new AsynchronousException(_cachedConnection, ICE_SHARED_FROM_THIS)); +} + +void +OutgoingAsyncBase::invokeResponseAsync() +{ + class AsynchronousResponse : public DispatchWorkItem + { + public: + + AsynchronousResponse(const ConnectionPtr& connection, const OutgoingAsyncBasePtr& outAsync) : + DispatchWorkItem(connection), _outAsync(outAsync) + { + } + + virtual void + run() + { + _outAsync->invokeResponse(); + } + + private: + + const OutgoingAsyncBasePtr _outAsync; + }; + + // + // CommunicatorDestroyedException is the only exception that can propagate directly from this method. + // + _instance->clientThreadPool()->dispatch(new AsynchronousResponse(_cachedConnection, ICE_SHARED_FROM_THIS)); +} + +void +OutgoingAsyncBase::invokeSent() +{ + try + { + handleInvokeSent(_sentSynchronously, this); + } + catch(const std::exception& ex) + { + warning(ex); + } + catch(...) + { + warning(); + } + + if(_observer && _doneInSent) + { + _observer.detach(); + } +} + +void +OutgoingAsyncBase::invokeException() +{ + try + { + handleInvokeException(*_ex, this); + } + catch(const std::exception& ex) + { + warning(ex); + } + catch(...) + { + warning(); + } + + _observer.detach(); +} + +void +OutgoingAsyncBase::invokeResponse() +{ + if(_ex) + { + invokeException(); + return; + } + + try + { +#ifdef ICE_CPP11_MAPPING + try + { + handleInvokeResponse(_state & OK, this); + } + catch(const Ice::Exception& ex) + { + if(handleException(ex)) + { + handleInvokeException(ex, this); + } + } + catch(const exception_ptr& ex) + { + rethrow_exception(ex); + } +#else + handleInvokeResponse(_state & OK, this); +#endif + } + catch(const std::exception& ex) + { + warning(ex); + } + catch(...) + { + warning(); + } + + _observer.detach(); +} + +void +OutgoingAsyncBase::cancelable(const CancellationHandlerPtr& handler) +{ + Lock sync(_m); + if(_cancellationException) + { + try + { + _cancellationException->ice_throw(); + } + catch(const Ice::LocalException&) + { + _cancellationException.reset(); + throw; + } + } + _cancellationHandler = handler; +} + +void +OutgoingAsyncBase::cancel() +{ + cancel(Ice::InvocationCanceledException(__FILE__, __LINE__)); +} + +OutgoingAsyncBase::OutgoingAsyncBase(const InstancePtr& instance) : + _instance(instance), + _sentSynchronously(false), + _doneInSent(false), + _state(0), + _os(instance.get(), Ice::currentProtocolEncoding), + _is(instance.get(), Ice::currentProtocolEncoding) +{ +} + +bool +OutgoingAsyncBase::sentImpl(bool done) +{ + Lock sync(_m); + bool alreadySent = (_state & Sent) > 0; + _state |= Sent; + if(done) + { + _doneInSent = true; + _childObserver.detach(); + _cancellationHandler = 0; + } + +#ifndef ICE_CPP11_MAPPING + if(done) + { + _state |= Done | OK; + } + _m.notifyAll(); +#endif + + bool invoke = handleSent(done, alreadySent); + if(!invoke && _doneInSent) + { + _observer.detach(); + } + return invoke; +} + +bool +OutgoingAsyncBase::exceptionImpl(const Exception& ex) +{ + Lock sync(_m); + ICE_SET_EXCEPTION_FROM_CLONE(_ex, ex.ice_clone()); + if(_childObserver) + { + _childObserver.failed(ex.ice_id()); + _childObserver.detach(); + } + _cancellationHandler = 0; + _observer.failed(ex.ice_id()); + +#ifndef ICE_CPP11_MAPPING + _state |= Done; + _m.notifyAll(); +#endif + + bool invoke = handleException(ex); + if(!invoke) + { + _observer.detach(); + } + return invoke; +} + +bool +OutgoingAsyncBase::responseImpl(bool ok, bool invoke) +{ + Lock sync(_m); + if(ok) + { + _state |= OK; + } + + _cancellationHandler = 0; + +#ifndef ICE_CPP11_MAPPING + _state |= Done; + _m.notifyAll(); +#endif + + try + { + invoke &= handleResponse(ok); + } + catch(const Ice::Exception& ex) + { + ICE_SET_EXCEPTION_FROM_CLONE(_ex, ex.ice_clone()); + invoke = handleException(ex); + } + if(!invoke) + { + _observer.detach(); + } + return invoke; +} + +void +OutgoingAsyncBase::cancel(const Ice::LocalException& ex) +{ + CancellationHandlerPtr handler; + { + Lock sync(_m); + if(!_cancellationHandler) + { + ICE_SET_EXCEPTION_FROM_CLONE(_cancellationException, ex.ice_clone()); + return; + } + handler = _cancellationHandler; + } + handler->asyncRequestCanceled(ICE_SHARED_FROM_THIS, ex); +} + +#ifndef ICE_CPP11_MAPPING + +Int +OutgoingAsyncBase::getHash() const +{ + return static_cast(reinterpret_cast(this) >> 4); +} + +CommunicatorPtr +OutgoingAsyncBase::getCommunicator() const +{ + return 0; +} + +ConnectionPtr +OutgoingAsyncBase::getConnection() const +{ + return 0; +} + +ObjectPrxPtr +OutgoingAsyncBase::getProxy() const +{ + return 0; +} + +Ice::LocalObjectPtr +OutgoingAsyncBase::getCookie() const +{ + return _cookie; +} + +const std::string& +OutgoingAsyncBase::getOperation() const +{ + assert(false); // Must be overriden + static string empty; + return empty; +} + +bool +OutgoingAsyncBase::isCompleted() const +{ + Lock sync(_m); + return (_state & Done) > 0; +} + +void +OutgoingAsyncBase::waitForCompleted() +{ + Lock sync(_m); + while(!(_state & Done)) + { + _m.wait(); + } +} + +bool +OutgoingAsyncBase::isSent() const +{ + Lock sync(_m); + return (_state & Sent) > 0; +} + +void +OutgoingAsyncBase::waitForSent() +{ + Lock sync(_m); + while(!(_state & Sent) && !_ex.get()) + { + _m.wait(); + } +} + +bool +OutgoingAsyncBase::sentSynchronously() const +{ + return _sentSynchronously; +} + +void +OutgoingAsyncBase::throwLocalException() const +{ + Lock sync(_m); + if(_ex.get()) + { + _ex->ice_throw(); + } +} + +bool +OutgoingAsyncBase::_waitForResponse() +{ + Lock sync(_m); + if(_state & EndCalled) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "end_ method called more than once"); + } + _state |= EndCalled; + while(!(_state & Done)) + { + _m.wait(); + } + + if(_ex.get()) + { + _ex->ice_throw(); + } + return _state & OK; +} + +Ice::InputStream* +OutgoingAsyncBase::_startReadParams() +{ + _is.startEncapsulation(); + return &_is; +} + +void +OutgoingAsyncBase::_endReadParams() +{ + _is.endEncapsulation(); +} + +void +OutgoingAsyncBase::_readEmptyParams() +{ + _is.skipEmptyEncapsulation(); +} + +void +OutgoingAsyncBase::_readParamEncaps(const ::Ice::Byte*& encaps, ::Ice::Int& sz) +{ + _is.readEncapsulation(encaps, sz); +} + +void +OutgoingAsyncBase::_throwUserException() +{ + try + { + _is.startEncapsulation(); + _is.throwException(); + } + catch(const Ice::UserException&) + { + _is.endEncapsulation(); + throw; + } +} + +void +OutgoingAsyncBase::_scheduleCallback(const CallbackPtr& cb) +{ + // + // NOTE: for internal use only. This should only be called when the invocation has + // completed. Accessing _cachedConnection is not safe otherwise. + // + + class WorkItem : public DispatchWorkItem + { + public: + + WorkItem(const ConnectionPtr& connection, const CallbackPtr& cb) : + DispatchWorkItem(connection), _cb(cb) + { + } + + virtual void run() + { + _cb->run(); + } + + private: + + CallbackPtr _cb; + }; + + // + // CommunicatorDestroyedException is the only exception that can propagate directly from this method. + // + _instance->clientThreadPool()->dispatch(new WorkItem(_cachedConnection, cb)); +} + +#endif + +void +OutgoingAsyncBase::warning(const std::exception& exc) const +{ + if(_instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + { + Ice::Warning out(_instance->initializationData().logger); + const Ice::Exception* ex = dynamic_cast(&exc); + if(ex) + { + out << "Ice::Exception raised by AMI callback:\n" << *ex; + } + else + { + out << "std::exception raised by AMI callback:\n" << exc.what(); + } + } +} + +void +OutgoingAsyncBase::warning() const +{ + if(_instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + { + Ice::Warning out(_instance->initializationData().logger); + out << "unknown exception raised by AMI callback"; + } +} + +bool +ProxyOutgoingAsyncBase::exception(const Exception& exc) +{ + if(_childObserver) + { + _childObserver.failed(exc.ice_id()); + _childObserver.detach(); + } + + _cachedConnection = 0; + if(_proxy->_getReference()->getInvocationTimeout() == -2) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + } + + // + // NOTE: at this point, synchronization isn't needed, no other threads should be + // calling on the callback. + // + try + { + // + // It's important to let the retry queue do the retry even if + // the retry interval is 0. This method can be called with the + // connection locked so we can't just retry here. + // + _instance->retryQueue()->add(ICE_SHARED_FROM_THIS, _proxy->_handleException(exc, _handler, _mode, _sent, _cnt)); + return false; + } + catch(const Exception& ex) + { + return exceptionImpl(ex); // No retries, we're done + } +} + +void +ProxyOutgoingAsyncBase::cancelable(const CancellationHandlerPtr& handler) +{ + if(_proxy->_getReference()->getInvocationTimeout() == -2 && _cachedConnection) + { + const int timeout = _cachedConnection->timeout(); + if(timeout > 0) + { + _instance->timer()->schedule(ICE_SHARED_FROM_THIS, IceUtil::Time::milliSeconds(timeout)); + } + } + OutgoingAsyncBase::cancelable(handler); +} + +void +ProxyOutgoingAsyncBase::retryException(const Exception&) +{ + try + { + // + // It's important to let the retry queue do the retry. This is + // called from the connect request handler and the retry might + // require could end up waiting for the flush of the + // connection to be done. + // + _proxy->_updateRequestHandler(_handler, 0); // Clear request handler and always retry. + _instance->retryQueue()->add(ICE_SHARED_FROM_THIS, 0); + } + catch(const Ice::Exception& exc) + { + if(exception(exc)) + { + invokeExceptionAsync(); + } + } +} + +void +ProxyOutgoingAsyncBase::retry() +{ + invokeImpl(false); +} + +void +ProxyOutgoingAsyncBase::abort(const Ice::Exception& ex) +{ + assert(!_childObserver); + + if(exceptionImpl(ex)) + { + invokeExceptionAsync(); + } + else if(dynamic_cast(&ex)) + { + // + // If it's a communicator destroyed exception, don't swallow + // it but instead notify the user thread. Even if no callback + // was provided. + // + ex.ice_throw(); + } +} + +#ifndef ICE_CPP11_MAPPING +Ice::ObjectPrx +ProxyOutgoingAsyncBase::getProxy() const +{ + return _proxy; +} + +Ice::CommunicatorPtr +ProxyOutgoingAsyncBase::getCommunicator() const +{ + return _proxy->ice_getCommunicator(); +} +#endif + +ProxyOutgoingAsyncBase::ProxyOutgoingAsyncBase(const ObjectPrxPtr& prx) : + OutgoingAsyncBase(prx->_getReference()->getInstance()), + _proxy(prx), + _mode(ICE_ENUM(OperationMode, Normal)), + _cnt(0), + _sent(false) +{ +} + +ProxyOutgoingAsyncBase::~ProxyOutgoingAsyncBase() +{ +} + +void +ProxyOutgoingAsyncBase::invokeImpl(bool userThread) +{ + try + { + if(userThread) + { + int invocationTimeout = _proxy->_getReference()->getInvocationTimeout(); + if(invocationTimeout > 0) + { + _instance->timer()->schedule(ICE_SHARED_FROM_THIS, IceUtil::Time::milliSeconds(invocationTimeout)); + } + } + else + { + _observer.retried(); + } + + while(true) + { + try + { + _sent = false; + _handler = _proxy->_getRequestHandler(); + AsyncStatus status = _handler->sendAsyncRequest(ICE_SHARED_FROM_THIS); + if(status & AsyncStatusSent) + { + if(userThread) + { + _sentSynchronously = true; + if(status & AsyncStatusInvokeSentCallback) + { + invokeSent(); // Call the sent callback from the user thread. + } + } + else + { + if(status & AsyncStatusInvokeSentCallback) + { + invokeSentAsync(); // Call the sent callback from a client thread pool thread. + } + } + } + return; // We're done! + } + catch(const RetryException&) + { + _proxy->_updateRequestHandler(_handler, 0); // Clear request handler and always retry. + } + catch(const Exception& ex) + { + if(_childObserver) + { + _childObserver.failed(ex.ice_id()); + _childObserver.detach(); + } + int interval = _proxy->_handleException(ex, _handler, _mode, _sent, _cnt); + if(interval > 0) + { + _instance->retryQueue()->add(ICE_SHARED_FROM_THIS, interval); + return; + } + else + { + _observer.retried(); + } + } + } + } + catch(const Exception& ex) + { + // + // If called from the user thread we re-throw, the exception + // will be catch by the caller and abort(ex) will be called. + // + if(userThread) + { + throw; + } + else if(exceptionImpl(ex)) // No retries, we're done + { + invokeExceptionAsync(); + } + } +} + +bool +ProxyOutgoingAsyncBase::sentImpl(bool done) +{ + _sent = true; + if(done) + { + if(_proxy->_getReference()->getInvocationTimeout() != -1) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + } + } + return OutgoingAsyncBase::sentImpl(done); +} + +bool +ProxyOutgoingAsyncBase::exceptionImpl(const Exception& ex) +{ + if(_proxy->_getReference()->getInvocationTimeout() != -1) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + } + return OutgoingAsyncBase::exceptionImpl(ex); +} + +bool +ProxyOutgoingAsyncBase::responseImpl(bool ok, bool invoke) +{ + if(_proxy->_getReference()->getInvocationTimeout() != -1) + { + _instance->timer()->cancel(ICE_SHARED_FROM_THIS); + } + return OutgoingAsyncBase::responseImpl(ok, invoke); +} + +void +ProxyOutgoingAsyncBase::runTimerTask() +{ + if(_proxy->_getReference()->getInvocationTimeout() == -2) + { + cancel(ConnectionTimeoutException(__FILE__, __LINE__)); + } + else + { + cancel(InvocationTimeoutException(__FILE__, __LINE__)); + } +} + +OutgoingAsync::OutgoingAsync(const ObjectPrxPtr& prx, bool synchronous) : + ProxyOutgoingAsyncBase(prx), + _encoding(getCompatibleEncoding(prx->_getReference()->getEncoding())), + _synchronous(synchronous) +{ +} + +void +OutgoingAsync::prepare(const string& operation, OperationMode mode, const Context& context) +{ + checkSupportedProtocol(getCompatibleProtocol(_proxy->_getReference()->getProtocol())); + + _mode = mode; + _observer.attach(_proxy, operation, context); + + switch(_proxy->_getReference()->getMode()) + { + case Reference::ModeTwoway: + case Reference::ModeOneway: + case Reference::ModeDatagram: + { + _os.writeBlob(requestHdr, sizeof(requestHdr)); + break; + } + + case Reference::ModeBatchOneway: + case Reference::ModeBatchDatagram: + { + _proxy->_getBatchRequestQueue()->prepareBatchRequest(&_os); + break; + } + } + + Reference* ref = _proxy->_getReference().get(); + + _os.write(ref->getIdentity()); + + // + // For compatibility with the old FacetPath. + // + if(ref->getFacet().empty()) + { + _os.write(static_cast(0), static_cast(0)); + } + else + { + string facet = ref->getFacet(); + _os.write(&facet, &facet + 1); + } + + _os.write(operation, false); + + _os.write(static_cast(_mode)); + +#if defined(_MSC_VER) && (_MSC_VER <= 1600) + // + // COMPILERFIX v90 and v100 get confused with namespaces and we need to + // defined both Ice::noExplicitContext and IceProxy::Ice::noExplicitContext + // see comments in Ice/Proxy.h. + // + if(&context != &Ice::noExplicitContext && + &context != &IceProxy::Ice::noExplicitContext) +#else + if(&context != &Ice::noExplicitContext) +#endif + { + // + // Explicit context + // + _os.write(context); + } + else + { + // + // Implicit context + // + const ImplicitContextIPtr& implicitContext = ref->getInstance()->getImplicitContext(); + const Context& prxContext = ref->getContext()->getValue(); + if(implicitContext == 0) + { + _os.write(prxContext); + } + else + { + implicitContext->write(prxContext, &_os); + } + } +} + +bool +OutgoingAsync::sent() +{ + return ProxyOutgoingAsyncBase::sentImpl(!_proxy->ice_isTwoway()); // done = true if it's not a two-way proxy +} + +bool +OutgoingAsync::response() +{ + // + // NOTE: this method is called from ConnectionI.parseMessage + // with the connection locked. Therefore, it must not invoke + // any user callbacks. + // + assert(_proxy->ice_isTwoway()); // Can only be called for twoways. + + if(_childObserver) + { + _childObserver->reply(static_cast(_is.b.size() - headerSize - 4)); + _childObserver.detach(); + } + + Byte replyStatus; + try + { + _is.read(replyStatus); + + switch(replyStatus) + { + case replyOK: + { + break; + } + case replyUserException: + { + _observer.userException(); + break; + } + + case replyObjectNotExist: + case replyFacetNotExist: + case replyOperationNotExist: + { + Identity ident; + _is.read(ident); + + // + // For compatibility with the old FacetPath. + // + vector facetPath; + _is.read(facetPath); + string facet; + if(!facetPath.empty()) + { + if(facetPath.size() > 1) + { + throw MarshalException(__FILE__, __LINE__); + } + facet.swap(facetPath[0]); + } + + string operation; + _is.read(operation, false); + + IceInternal::UniquePtr ex; + switch(replyStatus) + { + case replyObjectNotExist: + { + ex.reset(new ObjectNotExistException(__FILE__, __LINE__)); + break; + } + + case replyFacetNotExist: + { + ex.reset(new FacetNotExistException(__FILE__, __LINE__)); + break; + } + + case replyOperationNotExist: + { + ex.reset(new OperationNotExistException(__FILE__, __LINE__)); + break; + } + + default: + { + assert(false); + break; + } + } + + ex->id = ident; + ex->facet = facet; + ex->operation = operation; + ex->ice_throw(); + break; + } + + case replyUnknownException: + case replyUnknownLocalException: + case replyUnknownUserException: + { + string unknown; + _is.read(unknown, false); + + IceInternal::UniquePtr ex; + switch(replyStatus) + { + case replyUnknownException: + { + ex.reset(new UnknownException(__FILE__, __LINE__)); + break; + } + + case replyUnknownLocalException: + { + ex.reset(new UnknownLocalException(__FILE__, __LINE__)); + break; + } + + case replyUnknownUserException: + { + ex.reset(new UnknownUserException(__FILE__, __LINE__)); + break; + } + + default: + { + assert(false); + break; + } + } + + ex->unknown = unknown; + ex->ice_throw(); + break; + } + + default: + { + throw UnknownReplyStatusException(__FILE__, __LINE__); + } + } + + return responseImpl(replyStatus == replyOK, true); + } + catch(const Exception& ex) + { + return exception(ex); + } +} + +AsyncStatus +OutgoingAsync::invokeRemote(const ConnectionIPtr& connection, bool compress, bool response) +{ + _cachedConnection = connection; + return connection->sendAsyncRequest(ICE_SHARED_FROM_THIS, compress, response, 0); +} + +AsyncStatus +OutgoingAsync::invokeCollocated(CollocatedRequestHandler* handler) +{ + return handler->invokeAsyncRequest(this, 0, _synchronous); +} + +void +OutgoingAsync::abort(const Exception& ex) +{ + const Reference::Mode mode = _proxy->_getReference()->getMode(); + if(mode == Reference::ModeBatchOneway || mode == Reference::ModeBatchDatagram) + { + // + // If we didn't finish a batch oneway or datagram request, we + // must notify the connection about that we give up ownership + // of the batch stream. + // + _proxy->_getBatchRequestQueue()->abortBatchRequest(&_os); + } + + ProxyOutgoingAsyncBase::abort(ex); +} + +void +OutgoingAsync::invoke(const string& operation) +{ + const Reference::Mode mode = _proxy->_getReference()->getMode(); + if(mode == Reference::ModeBatchOneway || mode == Reference::ModeBatchDatagram) + { + _sentSynchronously = true; + _proxy->_getBatchRequestQueue()->finishBatchRequest(&_os, _proxy, operation); + responseImpl(true, false); // Don't call sent/completed callback for batch AMI requests + return; + } + + // + // NOTE: invokeImpl doesn't throw so this can be called from the + // try block with the catch block calling abort(ex) in case of an + // exception. + // + invokeImpl(true); // userThread = true +} + +#ifdef ICE_CPP11_MAPPING +void +OutgoingAsync::invoke(const string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& context, + function write) +{ + try + { + prepare(operation, mode, context); + if(write) + { + _os.startEncapsulation(_encoding, format); + write(&_os); + _os.endEncapsulation(); + } + else + { + _os.writeEmptyEncapsulation(_encoding); + } + invoke(operation); + } + catch(const Ice::Exception& ex) + { + abort(ex); + } +} + +void +OutgoingAsync::throwUserException() +{ + try + { + _is.startEncapsulation(); + _is.throwException(); + } + catch(const UserException& ex) + { + _is.endEncapsulation(); + if(_userException) + { + _userException(ex); + } + throw UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } +} + +#endif + +#ifdef ICE_CPP11_MAPPING + +bool +LambdaInvoke::handleSent(bool, bool alreadySent) +{ + return _sent != nullptr && !alreadySent; // Invoke the sent callback only if not already invoked. +} + +bool +LambdaInvoke::handleException(const Ice::Exception&) +{ + return _exception != nullptr; // Invoke the callback +} + +bool +LambdaInvoke::handleResponse(bool) +{ + return _response != nullptr; +} + +void +LambdaInvoke::handleInvokeSent(bool sentSynchronously, OutgoingAsyncBase*) const +{ + _sent(sentSynchronously); +} + +void +LambdaInvoke::handleInvokeException(const Ice::Exception& ex, OutgoingAsyncBase*) const +{ + try + { + ex.ice_throw(); + } + catch(const Ice::Exception&) + { + _exception(current_exception()); + } +} + +void +LambdaInvoke::handleInvokeResponse(bool ok, OutgoingAsyncBase*) const +{ + _response(ok); +} + +#else // C++98 + +namespace +{ + +// +// Dummy class derived from CallbackBase +// We use this class for the dummyCallback extern pointer in OutgoingAsync. In turn, +// this allows us to test whether the user supplied a null delegate instance to the +// generated begin_ method without having to generate a separate test to throw IllegalArgumentException +// in the inlined versions of the begin_ method. In other words, this reduces the amount of generated +// object code. +// +class DummyCallback : public CallbackBase +{ +public: + + DummyCallback() + { + } + + virtual void + completed(const Ice::AsyncResultPtr&) const + { + assert(false); + } + + virtual CallbackBasePtr + verify(const Ice::LocalObjectPtr&) + { + // + // Called by the AsyncResult constructor to verify the delegate. The dummy + // delegate is passed when the user used a begin_ method without delegate. + // By returning 0 here, we tell the AsyncResult that no delegates was + // provided. + // + return 0; + } + + virtual void + sent(const AsyncResultPtr&) const + { + assert(false); + } + + virtual bool + hasSentCallback() const + { + assert(false); + return false; + } +}; + +} + +// +// This gives a pointer value to compare against in the generated +// begin_ method to decide whether the caller passed a null pointer +// versus the generated inline version of the begin_ method having +// passed a pointer to the dummy delegate. +// +CallbackBasePtr IceInternal::dummyCallback = new DummyCallback; + +CallbackBase::~CallbackBase() +{ + // Out of line to avoid weak vtable +} + +void +CallbackBase::checkCallback(bool obj, bool cb) +{ + if(!obj) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "callback object cannot be null"); + } + if(!cb) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "callback cannot be null"); + } +} + +GenericCallbackBase::~GenericCallbackBase() +{ + // Out of line to avoid weak vtable +} + +#endif diff --git a/Sources/IceCpp/OutputStream.cpp b/Sources/IceCpp/OutputStream.cpp new file mode 100644 index 0000000..7493116 --- /dev/null +++ b/Sources/IceCpp/OutputStream.cpp @@ -0,0 +1,1367 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +class StreamUTF8BufferI : public IceUtil::UTF8Buffer +{ +public: + + StreamUTF8BufferI(OutputStream& stream) : + _stream(stream) + { + } + + Ice::Byte* getMoreBytes(size_t howMany, Ice::Byte* firstUnused) + { + assert(howMany > 0); + + if(firstUnused != 0) + { + // + // Return unused bytes + // + _stream.resize(static_cast(firstUnused - _stream.b.begin())); + } + + // + // Index of first unused byte + // + Buffer::Container::size_type pos = _stream.b.size(); + + // + // Since resize may reallocate the buffer, when firstUnused != 0, the + // return value can be != firstUnused + // + _stream.resize(pos + howMany); + + return &_stream.b[pos]; + } + +private: + + OutputStream& _stream; +}; + +} + +Ice::OutputStream::OutputStream() : + _instance(0), + _closure(0), + _encoding(currentEncoding), + _format(ICE_ENUM(FormatType, CompactFormat)), + _currentEncaps(0) +{ +} + +Ice::OutputStream::OutputStream(const CommunicatorPtr& communicator) : + _closure(0), + _currentEncaps(0) +{ + initialize(communicator); +} + +Ice::OutputStream::OutputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding) : + _closure(0), + _currentEncaps(0) +{ + initialize(communicator, encoding); +} + +Ice::OutputStream::OutputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding, + const pair& buf) : + Buffer(buf.first, buf.second), + _closure(0), + _currentEncaps(0) +{ + initialize(communicator, encoding); + b.reset(); +} + +Ice::OutputStream::OutputStream(Instance* instance, const EncodingVersion& encoding) : + _closure(0), + _currentEncaps(0) +{ + initialize(instance, encoding); +} + +void +Ice::OutputStream::initialize(const CommunicatorPtr& communicator) +{ + assert(communicator); + Instance* instance = getInstance(communicator).get(); + initialize(instance, instance->defaultsAndOverrides()->defaultEncoding); +} + +void +Ice::OutputStream::initialize(const CommunicatorPtr& communicator, const EncodingVersion& encoding) +{ + assert(communicator); + initialize(getInstance(communicator).get(), encoding); +} + +void +Ice::OutputStream::initialize(Instance* instance, const EncodingVersion& encoding) +{ + assert(instance); + + _instance = instance; + _encoding = encoding; + + _format = _instance->defaultsAndOverrides()->defaultFormat; +} + +void +Ice::OutputStream::clear() +{ + while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps) + { + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + delete oldEncaps; + } +} + +void +Ice::OutputStream::setFormat(FormatType fmt) +{ + _format = fmt; +} + +void* +Ice::OutputStream::getClosure() const +{ + return _closure; +} + +void* +Ice::OutputStream::setClosure(void* p) +{ + void* prev = _closure; + _closure = p; + return prev; +} + +void +Ice::OutputStream::swap(OutputStream& other) +{ + swapBuffer(other); + + std::swap(_instance, other._instance); + std::swap(_closure, other._closure); + std::swap(_encoding, other._encoding); + std::swap(_format, other._format); + + // + // Swap is never called for streams that have encapsulations being written. However, + // encapsulations might still be set in case marshalling failed. We just + // reset the encapsulations if there are still some set. + // + resetEncapsulation(); + other.resetEncapsulation(); +} + +void +Ice::OutputStream::resetEncapsulation() +{ + while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps) + { + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + delete oldEncaps; + } + + _preAllocatedEncaps.reset(); +} + +void +Ice::OutputStream::startEncapsulation() +{ + // + // If no encoding version is specified, use the current write + // encapsulation encoding version if there's a current write + // encapsulation, otherwise, use the stream encoding version. + // + + if(_currentEncaps) + { + startEncapsulation(_currentEncaps->encoding, _currentEncaps->format); + } + else + { + startEncapsulation(_encoding, Ice::ICE_ENUM(FormatType, DefaultFormat)); + } +} + +void +Ice::OutputStream::writePendingValues() +{ + if(_currentEncaps && _currentEncaps->encoder) + { + _currentEncaps->encoder->writePendingValues(); + } + else if(getEncoding() == Ice::Encoding_1_0) + { + // + // If using the 1.0 encoding and no instances were written, we + // still write an empty sequence for pending instances if + // requested (i.e.: if this is called). + // + // This is required by the 1.0 encoding, even if no instances + // are written we do marshal an empty sequence if marshaled + // data types use classes. + // + writeSize(0); + } +} + +void +Ice::OutputStream::writeBlob(const vector& v) +{ + if(!v.empty()) + { + Container::size_type pos = b.size(); + resize(pos + v.size()); + memcpy(&b[pos], &v[0], v.size()); + } +} + +void +Ice::OutputStream::write(const Byte* begin, const Byte* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz)); + memcpy(&b[pos], begin, static_cast(sz)); + } +} + +void +Ice::OutputStream::write(const vector& v) +{ + Int sz = static_cast(v.size()); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz)); + copy(v.begin(), v.end(), b.begin() + pos); + } +} + +namespace +{ + +template +struct WriteBoolHelper +{ + static void write(const bool* begin, OutputStream::Container::size_type pos, OutputStream::Container& b, Int sz) + { + for(size_t idx = 0; idx < static_cast(sz); ++idx) + { + b[pos + idx] = static_cast(*(begin + idx)); + } + } +}; + +template<> +struct WriteBoolHelper<1> +{ + static void write(const bool* begin, OutputStream::Container::size_type pos, OutputStream::Container& b, Int sz) + { + memcpy(&b[pos], begin, static_cast(sz)); + } +}; + +} + +void +Ice::OutputStream::write(const bool* begin, const bool* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz)); + WriteBoolHelper::write(begin, pos, b, sz); + } +} + +void +Ice::OutputStream::write(Short v) +{ + Container::size_type pos = b.size(); + resize(pos + sizeof(Short)); + Byte* dest = &b[pos]; +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v) + sizeof(Short) - 1; + *dest++ = *src--; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::OutputStream::write(const Short* begin, const Short* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz) * sizeof(Short)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(begin) + sizeof(Short) - 1; + Byte* dest = &(*(b.begin() + pos)); + for(int j = 0 ; j < sz ; ++j) + { + *dest++ = *src--; + *dest++ = *src--; + src += 2 * sizeof(Short); + } +#else + memcpy(&b[pos], reinterpret_cast(begin), static_cast(sz) * sizeof(Short)); +#endif + } +} + +void +Ice::OutputStream::write(const Int* begin, const Int* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz) * sizeof(Int)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(begin) + sizeof(Int) - 1; + Byte* dest = &(*(b.begin() + pos)); + for(int j = 0 ; j < sz ; ++j) + { + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + src += 2 * sizeof(Int); + } +#else + memcpy(&b[pos], reinterpret_cast(begin), static_cast(sz) * sizeof(Int)); +#endif + } +} + +void +Ice::OutputStream::write(Long v) +{ + Container::size_type pos = b.size(); + resize(pos + sizeof(Long)); + Byte* dest = &b[pos]; +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v) + sizeof(Long) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::OutputStream::write(const Long* begin, const Long* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz) * sizeof(Long)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(begin) + sizeof(Long) - 1; + Byte* dest = &(*(b.begin() + pos)); + for(int j = 0 ; j < sz ; ++j) + { + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + src += 2 * sizeof(Long); + } +#else + memcpy(&b[pos], reinterpret_cast(begin), static_cast(sz) * sizeof(Long)); +#endif + } +} + +void +Ice::OutputStream::write(Float v) +{ + Container::size_type pos = b.size(); + resize(pos + sizeof(Float)); + Byte* dest = &b[pos]; +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v) + sizeof(Float) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::OutputStream::write(const Float* begin, const Float* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz) * sizeof(Float)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(begin) + sizeof(Float) - 1; + Byte* dest = &(*(b.begin() + pos)); + for(int j = 0 ; j < sz ; ++j) + { + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + src += 2 * sizeof(Float); + } +#else + memcpy(&b[pos], reinterpret_cast(begin), static_cast(sz) * sizeof(Float)); +#endif + } +} + +void +Ice::OutputStream::write(Double v) +{ + Container::size_type pos = b.size(); + resize(pos + sizeof(Double)); + Byte* dest = &b[pos]; +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v) + sizeof(Double) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif +} + +void +Ice::OutputStream::write(const Double* begin, const Double* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + static_cast(sz) * sizeof(Double)); +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(begin) + sizeof(Double) - 1; + Byte* dest = &(*(b.begin() + pos)); + for(int j = 0 ; j < sz ; ++j) + { + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + src += 2 * sizeof(Double); + } +#else + memcpy(&b[pos], reinterpret_cast(begin), static_cast(sz) * sizeof(Double)); +#endif + } +} + +// +// NOTE: This member function is intentionally omitted in order to +// cause a link error if it is used. This is for efficiency reasons: +// writing a const char * requires a traversal of the string to get +// the string length first, which takes O(n) time, whereas getting the +// string length from a std::string takes constant time. +// +/* +void +Ice::OutputStream::write(const char*) +{ +} +*/ + +void +Ice::OutputStream::writeConverted(const char* vdata, size_t vsize) +{ + // + // What is the size of the resulting UTF-8 encoded string? + // Impossible to tell, so we guess. If we don't guess correctly, + // we'll have to fix the mistake afterwards + // + try + { + Int guessedSize = static_cast(vsize); + writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. + + size_t firstIndex = b.size(); + StreamUTF8BufferI buffer(*this); + + Byte* lastByte = ICE_NULLPTR; + bool converted = false; + if(_instance) + { + const StringConverterPtr& stringConverter = _instance->getStringConverter(); + if(stringConverter) + { + lastByte = stringConverter->toUTF8(vdata, vdata + vsize, buffer); + converted = true; + } + } + else + { + StringConverterPtr stringConverter = getProcessStringConverter(); + if(stringConverter) + { + lastByte = stringConverter->toUTF8(vdata, vdata + vsize, buffer); + converted = true; + } + } + + if(!converted) + { + Container::size_type position = b.size(); + resize(position + vsize); + memcpy(&b[position], vdata, vsize); + return; + } + + if(lastByte != b.end()) + { + resize(static_cast(lastByte - b.begin())); + } + size_t lastIndex = b.size(); + + Int actualSize = static_cast(lastIndex - firstIndex); + + // + // Check against the guess + // + if(guessedSize != actualSize) + { + if(guessedSize <= 254 && actualSize > 254) + { + // + // Move the UTF-8 sequence 4 bytes further + // Use memmove instead of memcpy since the source and destination typically overlap. + // + resize(b.size() + 4); + memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, static_cast(actualSize)); + } + else if(guessedSize > 254 && actualSize <= 254) + { + // + // Move the UTF-8 sequence 4 bytes back + // + memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, static_cast(actualSize)); + resize(b.size() - 4); + } + + if(guessedSize <= 254) + { + rewriteSize(actualSize, b.begin() + firstIndex - 1); + } + else + { + rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + } + } + } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } +} + +void +Ice::OutputStream::write(const string* begin, const string* end, bool convert) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + for(int j = 0; j < sz; ++j) + { + write(begin[j], convert); + } + } +} + +void +Ice::OutputStream::write(const wstring& v) +{ + if(v.empty()) + { + writeSize(0); + return; + } + + // + // What is the size of the resulting UTF-8 encoded string? + // Impossible to tell, so we guess. If we don't guess correctly, + // we'll have to fix the mistake afterwards + // + try + { + Int guessedSize = static_cast(v.size()); + writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space. + + size_t firstIndex = b.size(); + StreamUTF8BufferI buffer(*this); + + Byte* lastByte = ICE_NULLPTR; + + // Note: wstringConverter is never null; when set to null, get returns the default unicode wstring converter + if(_instance) + { + lastByte = _instance->getWstringConverter()->toUTF8(v.data(), v.data() + v.size(), buffer); + } + else + { + lastByte = getProcessWstringConverter()->toUTF8(v.data(), v.data() + v.size(), buffer); + } + + if(lastByte != b.end()) + { + resize(static_cast(lastByte - b.begin())); + } + size_t lastIndex = b.size(); + + Int actualSize = static_cast(lastIndex - firstIndex); + + // + // Check against the guess + // + if(guessedSize != actualSize) + { + if(guessedSize <= 254 && actualSize > 254) + { + // + // Move the UTF-8 sequence 4 bytes further + // Use memmove instead of memcpy since the source and destination typically overlap. + // + resize(b.size() + 4); + memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, static_cast(actualSize)); + } + else if(guessedSize > 254 && actualSize <= 254) + { + // + // Move the UTF-8 sequence 4 bytes back + // + memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, static_cast(actualSize)); + resize(b.size() - 4); + } + + if(guessedSize <= 254) + { + rewriteSize(actualSize, b.begin() + firstIndex - 1); + } + else + { + rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4); + } + } + } + catch(const IceUtil::IllegalConversionException& ex) + { + throw StringConversionException(__FILE__, __LINE__, ex.reason()); + } +} + +void +Ice::OutputStream::write(const wstring* begin, const wstring* end) +{ + Int sz = static_cast(end - begin); + writeSize(sz); + if(sz > 0) + { + for(int j = 0; j < sz; ++j) + { + write(begin[j]); + } + } +} + +void +#ifdef ICE_CPP11_MAPPING +Ice::OutputStream::writeProxy(const shared_ptr& v) +#else +Ice::OutputStream::write(const ObjectPrx& v) +#endif +{ + if(v) + { + v->_write(*this); + } + else + { + Identity ident; + write(ident); + } +} + +void +Ice::OutputStream::writeEnum(Int v, Int maxValue) +{ + if(getEncoding() == Encoding_1_0) + { + if(maxValue < 127) + { + write(static_cast(v)); + } + else if(maxValue < 32767) + { + write(static_cast(v)); + } + else + { + write(v); + } + } + else + { + writeSize(v); + } +} + +void +Ice::OutputStream::writeException(const UserException& e) +{ + initEncaps(); + _currentEncaps->encoder->write(e); +} + +bool +Ice::OutputStream::writeOptImpl(Int tag, OptionalFormat type) +{ + if(getEncoding() == Encoding_1_0) + { + return false; // Optional members aren't supported with the 1.0 encoding. + } + + Byte v = static_cast(type); + if(tag < 30) + { + v |= static_cast(tag << 3); + write(v); + } + else + { + v |= 0xF0; // tag = 30 + write(v); + writeSize(tag); + } + return true; +} + +void +Ice::OutputStream::finished(vector& bytes) +{ + vector(b.begin(), b.end()).swap(bytes); +} + +pair +Ice::OutputStream::finished() +{ + if(b.empty()) + { + return pair(reinterpret_cast(0), reinterpret_cast(0)); + } + else + { + return pair(&b[0], &b[0] + b.size()); + } +} + +void +Ice::OutputStream::throwEncapsulationException(const char* file, int line) +{ + throw EncapsulationException(file, line); +} + +void +Ice::OutputStream::initEncaps() +{ + if(!_currentEncaps) // Lazy initialization. + { + _currentEncaps = &_preAllocatedEncaps; + _currentEncaps->start = b.size(); + _currentEncaps->encoding = _encoding; + } + + if(_currentEncaps->format == Ice::ICE_ENUM(FormatType, DefaultFormat)) + { + _currentEncaps->format = _format; + } + + if(!_currentEncaps->encoder) // Lazy initialization. + { + if(_currentEncaps->encoding == Encoding_1_0) + { + _currentEncaps->encoder = new EncapsEncoder10(this, _currentEncaps); + } + else + { + _currentEncaps->encoder = new EncapsEncoder11(this, _currentEncaps); + } + } +} + +Ice::OutputStream::EncapsEncoder::~EncapsEncoder() +{ + // Out of line to avoid weak vtable +} + +Int +Ice::OutputStream::EncapsEncoder::registerTypeId(const string& typeId) +{ + TypeIdMap::const_iterator p = _typeIdMap.find(typeId); + if(p != _typeIdMap.end()) + { + return p->second; + } + else + { + _typeIdMap.insert(make_pair(typeId, ++_typeIdIndex)); + return -1; + } +} + +void +Ice::OutputStream::EncapsEncoder10::write(const ValuePtr& v) +{ + // + // Object references are encoded as a negative integer in 1.0. + // + if(v) + { + _stream->write(-registerValue(v)); + } + else + { + _stream->write(0); + } +} + +void +Ice::OutputStream::EncapsEncoder10::write(const UserException& v) +{ + // + // User exception with the 1.0 encoding start with a boolean + // flag that indicates whether or not the exception uses + // classes. + // + // This allows reading the pending instances even if some part of + // the exception was sliced. + // + bool usesClasses = v._usesClasses(); + _stream->write(usesClasses); + v._write(_stream); + if(usesClasses) + { + writePendingValues(); + } +} + +void +Ice::OutputStream::EncapsEncoder10::startInstance(SliceType sliceType, const SlicedDataPtr&) +{ + _sliceType = sliceType; +} + +void +Ice::OutputStream::EncapsEncoder10::endInstance() +{ + if(_sliceType == ValueSlice) + { + // + // Write the Object slice. + // + startSlice(Object::ice_staticId(), -1, true); + _stream->writeSize(0); // For compatibility with the old AFM. + endSlice(); + } + _sliceType = NoSlice; +} + +void +Ice::OutputStream::EncapsEncoder10::startSlice(const string& typeId, int, bool /*last*/) +{ + // + // For instance slices, encode a boolean to indicate how the type ID + // is encoded and the type ID either as a string or index. For + // exception slices, always encode the type ID as a string. + // + if(_sliceType == ValueSlice) + { + Int index = registerTypeId(typeId); + if(index < 0) + { + _stream->write(false); + _stream->write(typeId, false); + } + else + { + _stream->write(true); + _stream->writeSize(index); + } + } + else + { + _stream->write(typeId, false); + } + + _stream->write(Int(0)); // Placeholder for the slice length. + + _writeSlice = _stream->b.size(); +} + +void +Ice::OutputStream::EncapsEncoder10::endSlice() +{ + // + // Write the slice length. + // + Int sz = static_cast(_stream->b.size() - _writeSlice + sizeof(Int)); + Byte* dest = &(*(_stream->b.begin() + _writeSlice - sizeof(Int))); + _stream->write(sz, dest); +} + +void +Ice::OutputStream::EncapsEncoder10::writePendingValues() +{ + while(!_toBeMarshaledMap.empty()) + { + // + // Consider the to be marshalled instances as marshalled now, + // this is necessary to avoid adding again the "to be + // marshalled instances" into _toBeMarshaledMap while writing + // instances. + // + _marshaledMap.insert(_toBeMarshaledMap.begin(), _toBeMarshaledMap.end()); + + PtrToIndexMap savedMap; + savedMap.swap(_toBeMarshaledMap); + _stream->writeSize(static_cast(savedMap.size())); + for(PtrToIndexMap::iterator p = savedMap.begin(); p != savedMap.end(); ++p) + { + // + // Ask the instance to marshal itself. Any new class + // instances that are triggered by the classes marshaled + // are added to toBeMarshaledMap. + // + _stream->write(p->second); + + try + { + p->first->ice_preMarshal(); + } + catch(const std::exception& ex) + { + Warning out(_stream->instance()->initializationData().logger); + out << "std::exception raised by ice_preMarshal:\n" << ex; + } + catch(...) + { + Warning out(_stream->instance()->initializationData().logger); + out << "unknown exception raised by ice_preMarshal"; + } + + p->first->_iceWrite(_stream); + } + } + _stream->writeSize(0); // Zero marker indicates end of sequence of sequences of instances. +} + +Int +Ice::OutputStream::EncapsEncoder10::registerValue(const ValuePtr& v) +{ + assert(v); + + // + // Look for this instance in the to-be-marshaled map. + // + PtrToIndexMap::const_iterator p = _toBeMarshaledMap.find(v); + if(p != _toBeMarshaledMap.end()) + { + return p->second; + } + + // + // Didn't find it, try the marshaled map next. + // + PtrToIndexMap::const_iterator q = _marshaledMap.find(v); + if(q != _marshaledMap.end()) + { + return q->second; + } + + // + // We haven't seen this instance previously, create a new + // index, and insert it into the to-be-marshaled map. + // + _toBeMarshaledMap.insert(make_pair(v, ++_valueIdIndex)); + return _valueIdIndex; +} + +void +Ice::OutputStream::EncapsEncoder11::write(const ValuePtr& v) +{ + if(!v) + { + _stream->writeSize(0); // Nil reference. + } + else if(_current && _encaps->format == ICE_ENUM(FormatType, SlicedFormat)) + { + // + // If writing an instance within a slice and using the sliced + // format, write an index from the instance indirection + // table. The indirect instance table is encoded at the end of + // each slice and is always read (even if the Slice is + // unknown). + // + PtrToIndexMap::const_iterator p = _current->indirectionMap.find(v); + if(p == _current->indirectionMap.end()) + { + _current->indirectionTable.push_back(v); + Int idx = static_cast(_current->indirectionTable.size()); // Position + 1 (0 is reserved for nil) + _current->indirectionMap.insert(make_pair(v, idx)); + _stream->writeSize(idx); + } + else + { + _stream->writeSize(p->second); + } + } + else + { + writeInstance(v); // Write the instance or a reference if already marshaled. + } +} + +void +Ice::OutputStream::EncapsEncoder11::write(const UserException& v) +{ + v._write(_stream); +} + +void +Ice::OutputStream::EncapsEncoder11::startInstance(SliceType sliceType, const SlicedDataPtr& data) +{ + if(!_current) + { + _current = &_preAllocatedInstanceData; + } + else + { + _current = _current->next ? _current->next : new InstanceData(_current); + } + _current->sliceType = sliceType; + _current->firstSlice = true; + + if(data) + { + writeSlicedData(data); + } +} + +void +Ice::OutputStream::EncapsEncoder11::endInstance() +{ + _current = _current->previous; +} + +void +Ice::OutputStream::EncapsEncoder11::startSlice(const string& typeId, int compactId, bool last) +{ + assert(_current->indirectionTable.empty() && _current->indirectionMap.empty()); + + _current->sliceFlagsPos = _stream->b.size(); + + _current->sliceFlags = 0; + if(_encaps->format == ICE_ENUM(FormatType, SlicedFormat)) + { + _current->sliceFlags |= FLAG_HAS_SLICE_SIZE; // Encode the slice size if using the sliced format. + } + if(last) + { + _current->sliceFlags |= FLAG_IS_LAST_SLICE; // This is the last slice. + } + + _stream->write(Byte(0)); // Placeholder for the slice flags + + // + // For instance slices, encode the flag and the type ID either as a + // string or index. For exception slices, always encode the type + // ID a string. + // + if(_current->sliceType == ValueSlice) + { + // + // Encode the type ID (only in the first slice for the compact + // encoding). + // + if(_encaps->format == ICE_ENUM(FormatType, SlicedFormat) || _current->firstSlice) + { + if(compactId >= 0) + { + _current->sliceFlags |= FLAG_HAS_TYPE_ID_COMPACT; + _stream->writeSize(compactId); + } + else + { + Int index = registerTypeId(typeId); + if(index < 0) + { + _current->sliceFlags |= FLAG_HAS_TYPE_ID_STRING; + _stream->write(typeId, false); + } + else + { + _current->sliceFlags |= FLAG_HAS_TYPE_ID_INDEX; + _stream->writeSize(index); + } + } + } + } + else + { + _stream->write(typeId, false); + } + + if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE) + { + _stream->write(Int(0)); // Placeholder for the slice length. + } + + _current->writeSlice = _stream->b.size(); + _current->firstSlice = false; +} + +void +Ice::OutputStream::EncapsEncoder11::endSlice() +{ + // + // Write the optional member end marker if some optional members + // were encoded. Note that the optional members are encoded before + // the indirection table and are included in the slice size. + // + if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) + { + _stream->write(OPTIONAL_END_MARKER); + } + + // + // Write the slice length if necessary. + // + if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE) + { + Int sz = static_cast(_stream->b.size() - _current->writeSlice + sizeof(Int)); + Byte* dest = &(*(_stream->b.begin() + _current->writeSlice - sizeof(Int))); + _stream->write(sz, dest); + } + + // + // Only write the indirection table if it contains entries. + // + if(!_current->indirectionTable.empty()) + { + assert(_encaps->format == ICE_ENUM(FormatType, SlicedFormat)); + _current->sliceFlags |= FLAG_HAS_INDIRECTION_TABLE; + + // + // Write the indirect instance table. + // + _stream->writeSize(static_cast(_current->indirectionTable.size())); + ValueList::const_iterator p; + for(p = _current->indirectionTable.begin(); p != _current->indirectionTable.end(); ++p) + { + writeInstance(*p); + } + _current->indirectionTable.clear(); + _current->indirectionMap.clear(); + } + + // + // Finally, update the slice flags. + // + Byte* dest = &(*(_stream->b.begin() + _current->sliceFlagsPos)); + *dest = _current->sliceFlags; +} + +bool +Ice::OutputStream::EncapsEncoder11::writeOptional(Ice::Int tag, Ice::OptionalFormat format) +{ + if(!_current) + { + return _stream->writeOptImpl(tag, format); + } + else + { + if(_stream->writeOptImpl(tag, format)) + { + _current->sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + return true; + } + else + { + return false; + } + } +} + +void +Ice::OutputStream::EncapsEncoder11::writeSlicedData(const SlicedDataPtr& slicedData) +{ + assert(slicedData); + + // + // We only remarshal preserved slices if we are using the sliced + // format. Otherwise, we ignore the preserved slices, which + // essentially "slices" the instance into the most-derived type + // known by the sender. + // + if(_encaps->format != ICE_ENUM(FormatType, SlicedFormat)) + { + return; + } + + for(SliceInfoSeq::const_iterator p = slicedData->slices.begin(); p != slicedData->slices.end(); ++p) + { + startSlice((*p)->typeId, (*p)->compactId, (*p)->isLastSlice); + + // + // Write the bytes associated with this slice. + // + _stream->writeBlob((*p)->bytes); + + if((*p)->hasOptionalMembers) + { + _current->sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + } + + // + // Make sure to also re-write the instance indirection table. + // + _current->indirectionTable = (*p)->instances; + + endSlice(); + } +} + +void +Ice::OutputStream::EncapsEncoder11::writeInstance(const ValuePtr& v) +{ + assert(v); + + // + // If the instance was already marshaled, just write it's ID. + // + PtrToIndexMap::const_iterator q = _marshaledMap.find(v); + if(q != _marshaledMap.end()) + { + _stream->writeSize(q->second); + return; + } + + // + // We haven't seen this instance previously, create a new ID, + // insert it into the marshaled map, and write the instance. + // + _marshaledMap.insert(make_pair(v, ++_valueIdIndex)); + + try + { + v->ice_preMarshal(); + } + catch(const std::exception& ex) + { + Warning out(_stream->instance()->initializationData().logger); + out << "std::exception raised by ice_preMarshal:\n" << ex; + } + catch(...) + { + Warning out(_stream->instance()->initializationData().logger); + out << "unknown exception raised by ice_preMarshal"; + } + + _stream->writeSize(1); // Object instance marker. + v->_iceWrite(_stream); +} diff --git a/Sources/IceCpp/OutputUtil.cpp b/Sources/IceCpp/OutputUtil.cpp new file mode 100644 index 0000000..2584cc8 --- /dev/null +++ b/Sources/IceCpp/OutputUtil.cpp @@ -0,0 +1,609 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace std; +using namespace IceUtil; +using namespace IceUtilInternal; + +namespace IceUtilInternal +{ + +NextLine nl; +StartBlock sb; +EndBlock eb; +StartPar spar; +EndPar epar; +StartAbrk sabrk; +EndAbrk eabrk; +Separator sp; +EndElement ee; +StartEscapes startEscapes; +EndEscapes endEscapes; + +} + +string +IceUtilInternal::int64ToString(Int64 val) +{ + char buf[64]; + +#if defined(_WIN32) + sprintf_s(buf, sizeof(buf), "%I64d", val); +#elif defined(__APPLE__) + // sprintf is deprecated with macOS Ventura + snprintf(buf, sizeof(buf), "%ld", val); // Avoids a format warning from GCC. +#else +# if defined(ICE_64) + sprintf(buf, "%ld", val); // Avoids a format warning from GCC. +# else + sprintf(buf, "%lld", val); +# endif +#endif + return string(buf); +} + +// ---------------------------------------------------------------------- +// OutputBase +// ---------------------------------------------------------------------- + +IceUtilInternal::OutputBase::OutputBase() : + _out(_fout), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(false), + _separator(true) +{ +} + +IceUtilInternal::OutputBase::OutputBase(ostream& os) : + _out(os), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(false), + _separator(true) +{ +} + +IceUtilInternal::OutputBase::OutputBase(const string& s) : + _out(_fout), + _pos(0), + _indent(0), + _indentSize(4), + _useTab(false), + _separator(true) +{ + open(s); +} + +IceUtilInternal::OutputBase::~OutputBase() +{ +} + +void +IceUtilInternal::OutputBase::open(const string& s) +{ + // + // Remove any existing file first. This prevents file name + // mismatches on case-insensitive OSs. + // + IceUtilInternal::unlink(s); + _fout.open(IceUtilInternal::streamFilename(s).c_str()); +} + +void +IceUtilInternal::OutputBase::close() +{ + if(_fout.is_open()) + { + _fout.close(); + } +} + +bool +IceUtilInternal::OutputBase::isOpen() +{ + return _fout.is_open(); +} + +void +IceUtilInternal::OutputBase::print(const string& s) +{ + size_t len = s.size(); + for(unsigned int i = 0; i < len; ++i) + { + if(s[i] == '\n') + { + _pos = 0; + } + else + { + ++_pos; + } + } + _out << s; +} + +void +IceUtilInternal::OutputBase::inc() +{ + _indent += _indentSize; +} + +void +IceUtilInternal::OutputBase::dec() +{ + assert(_indent >= _indentSize); + _indent -= _indentSize; +} + +void +IceUtilInternal::OutputBase::useCurrentPosAsIndent() +{ + _indentSave.push(_indent); + _indent = _pos; +} + +void +IceUtilInternal::OutputBase::zeroIndent() +{ + _indentSave.push(_indent); + _indent = 0; +} + +void +IceUtilInternal::OutputBase::restoreIndent() +{ + assert(!_indentSave.empty()); + _indent = _indentSave.top(); + _indentSave.pop(); +} + +int +IceUtilInternal::OutputBase::currIndent() +{ + return _indent; +} + +void +IceUtilInternal::OutputBase::setIndent(int indentSize) +{ + _indentSize = indentSize; +} + +void +IceUtilInternal::OutputBase::setUseTab(bool useTab) +{ + _useTab = useTab; +} + +void +IceUtilInternal::OutputBase::newline() +{ + _out << '\n'; + _pos = 0; + _separator = true; + + int indent = _indent; + + if(_useTab) + { + while(indent >= 8) + { + indent -= 8; + _out << '\t'; + _pos += 8; + } + } + else + { + while(indent >= _indentSize) + { + indent -= _indentSize; + _out << " "; + _pos += _indentSize; + } + } + + while(indent > 0) + { + --indent; + _out << ' '; + ++_pos; + } + + _out.flush(); +} + +void +IceUtilInternal::OutputBase::separator() +{ + if(_separator) + { + _out << '\n'; + } +} + +bool +IceUtilInternal::OutputBase::operator!() const +{ + return !_out; +} + +// ---------------------------------------------------------------------- +// Output +// ---------------------------------------------------------------------- + +IceUtilInternal::Output::Output(bool breakBeforeBlock, bool shortEmptyBlock) : + OutputBase(), + _blockStart("{"), + _blockEnd("}"), + _par(-1), + _breakBeforeBlock(breakBeforeBlock), + _shortEmptyBlock(shortEmptyBlock), + _emptyBlock(false) +{ +} + +IceUtilInternal::Output::Output(ostream& os, bool breakBeforeBlock, bool shortEmptyBlock) : + OutputBase(os), + _blockStart("{"), + _blockEnd("}"), + _par(-1), + _breakBeforeBlock(breakBeforeBlock), + _shortEmptyBlock(shortEmptyBlock), + _emptyBlock(false) +{ +} + +IceUtilInternal::Output::Output(const char* s, bool breakBeforeBlock, bool shortEmptyBlock) : + OutputBase(s), + _blockStart("{"), + _blockEnd("}"), + _par(-1), + _breakBeforeBlock(breakBeforeBlock), + _shortEmptyBlock(shortEmptyBlock), + _emptyBlock(false) +{ +} + +void +IceUtilInternal::Output::print(const string& s) +{ + _emptyBlock = false; + if(_par >= 0) + { + if(++_par > 1) // No comma for the first parameter. + { + _out << ", "; + } + } + OutputBase::print(s); +} + +void +IceUtilInternal::Output::sb() +{ + if(_blockStart.length()) + { + if(_breakBeforeBlock) + { + newline(); + } + else + { + _out << ' '; + } + _out << _blockStart; + } + ++_pos; + inc(); + _separator = false; + _emptyBlock = true; +} + +void +IceUtilInternal::Output::eb() +{ + dec(); + if(_emptyBlock && _shortEmptyBlock) + { + if(_blockEnd.length()) + { + _separator = true; + _out << _blockEnd; + } + } + else + { + if(_blockEnd.length()) + { + newline(); + _out << _blockEnd; + } + } + --_pos; +} + +void +IceUtilInternal::Output::spar(char c) +{ + _emptyBlock = false; + _out << c; + _par = 0; +} + +void +IceUtilInternal::Output::epar(char c) +{ + _par = -1; + _out << c; +} + +Output& +IceUtilInternal::operator<<(Output& out, ios_base& (*val)(ios_base&)) +{ + ostringstream s; + s << val; + out.print(s.str()); + return out; +} + +// ---------------------------------------------------------------------- +// XMLOutput +// ---------------------------------------------------------------------- + +IceUtilInternal::XMLOutput::XMLOutput() : + OutputBase(), + _se(false), + _text(false), + _escape(false) +{ +} + +IceUtilInternal::XMLOutput::XMLOutput(ostream& os) : + OutputBase(os), + _se(false), + _text(false), + _escape(false) +{ +} + +IceUtilInternal::XMLOutput::XMLOutput(const char* s) : + OutputBase(s), + _se(false), + _text(false), + _escape(false) +{ +} + +void +IceUtilInternal::XMLOutput::print(const string& s) +{ + if(_se) + { + _out << '>'; + _se = false; + } + _text = true; + + if(_escape) + { + OutputBase::print(escape(s)); + } + else + { + OutputBase::print(s); + } +} + +void +IceUtilInternal::XMLOutput::newline() +{ + if(_se) + { + _se = false; + _out << '>'; + } + OutputBase::newline(); +} + +void +IceUtilInternal::XMLOutput::startElement(const string& element) +{ + newline(); + + // + // If we're not in SGML mode the output of the '>' character is + // deferred until either the //end-element (in which case a /> is + // emitted) or until something //is displayed. + // + if(_escape) + { + _out << '<' << escape(element); + } + else + { + _out << '<' << element; + } + _se = true; + _text = false; + + string::size_type pos = element.find_first_of(" \t"); + if(pos == string::npos) + { + _elementStack.push(element); + } + else + { + _elementStack.push(element.substr(0, pos)); + } + + ++_pos; // TODO: ??? + inc(); + _separator = false; +} + +void +IceUtilInternal::XMLOutput::endElement() +{ + string element = _elementStack.top(); + _elementStack.pop(); + + dec(); + if(_se) + { + _out << ">'; + } + else + { + if(!_text) + { + newline(); + } + _out << "'; + } + --_pos; // TODO: ??? + + _se = false; + _text = false; +} + +void +IceUtilInternal::XMLOutput::attr(const string& name, const string& value) +{ + // + // Precondition: Attributes can only be attached to elements. + // + assert(_se); + _out << " " << name << "=\"" << escape(value) << '"'; +} + +void +IceUtilInternal::XMLOutput::startEscapes() +{ + _escape = true; +} + +void +IceUtilInternal::XMLOutput::endEscapes() +{ + _escape = false; +} + +string +IceUtilInternal::XMLOutput::currentElement() const +{ + if(_elementStack.size() > 0) + { + return _elementStack.top(); + } + else + { + return string(); + } +} + +string +IceUtilInternal::XMLOutput::escape(const string& input) const +{ + string v = input; + + // + // Find out whether there is a reserved character to avoid + // conversion if not necessary. + // + const string allReserved = "<>'\"&"; + if(v.find_first_of(allReserved) != string::npos) + { + // + // First convert all & to & + // + size_t pos = 0; + while((pos = v.find_first_of('&', pos)) != string::npos) + { + v.insert(pos+1, "amp;"); + pos += 4; + } + + // + // Next convert remaining reserved characters. + // + const string reserved = "<>'\""; + pos = 0; + while((pos = v.find_first_of(reserved, pos)) != string::npos) + { + string replace; + switch(v[pos]) + { + case '>': + replace = ">"; + break; + + case '<': + replace = "<"; + break; + + case '\'': + replace = "'"; + break; + + case '"': + replace = """; + break; + + default: + assert(false); + } + + v.erase(pos, 1); + v.insert(pos, replace); + pos += replace.size(); + } + } + return v; +} + +XMLOutput& +IceUtilInternal::operator<<(XMLOutput& out, ios_base& (*val)(ios_base&)) +{ + ostringstream s; + s << val; + out.print(s.str()); + return out; +} + +IceUtilInternal::StartElement::StartElement(const string& name) : + _name(name) +{ +} + +const string& +IceUtilInternal::StartElement::getName() const +{ + return _name; +} + +IceUtilInternal::Attribute::Attribute(const string& name, const string& value) : + _name(name), + _value(value) +{ +} + +const string& +IceUtilInternal::Attribute::getName() const +{ + return _name; +} + +const string& +IceUtilInternal::Attribute::getValue() const +{ + return _value; +} diff --git a/Sources/IceCpp/Plugin.cpp b/Sources/IceCpp/Plugin.cpp new file mode 100644 index 0000000..c930b31 --- /dev/null +++ b/Sources/IceCpp/Plugin.cpp @@ -0,0 +1,87 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Plugin.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::Plugin::~Plugin() +{ +} + +Ice::PluginManager::~PluginManager() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::Plugin::~Plugin() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Plugin* p) { return p; } +/// \endcond + +Ice::PluginManager::~PluginManager() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(PluginManager* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/PluginF.cpp b/Sources/IceCpp/PluginF.cpp new file mode 100644 index 0000000..d7a914a --- /dev/null +++ b/Sources/IceCpp/PluginF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PluginF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/PluginManagerI.cpp b/Sources/IceCpp/PluginManagerI.cpp new file mode 100644 index 0000000..63da0b2 --- /dev/null +++ b/Sources/IceCpp/PluginManagerI.cpp @@ -0,0 +1,503 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +const char * const Ice::PluginManagerI::_kindOfObject = "plugin"; + +namespace +{ + +map* factories = 0; +vector* loadOnInitialization = 0; + +class PluginFactoryDestroy +{ +public: + + ~PluginFactoryDestroy() + { + delete factories; + factories = 0; + + delete loadOnInitialization; + loadOnInitialization = 0; + } +}; +PluginFactoryDestroy destroy; + +} + +void +Ice::PluginManagerI::registerPluginFactory(const std::string& name, PluginFactory factory, bool loadOnInit) +{ + if(factories == 0) + { + factories = new map(); + } + + map::const_iterator p = factories->find(name); + if(p == factories->end()) + { + factories->insert(make_pair(name, factory)); + if(loadOnInit) + { + if(loadOnInitialization == 0) + { + loadOnInitialization = new vector(); + } + loadOnInitialization->push_back(name); + } + } +} + +void +Ice::PluginManagerI::initializePlugins() +{ + if(_initialized) + { + throw InitializationException(__FILE__, __LINE__, "plug-ins already initialized"); + } + + // + // Invoke initialize() on the plug-ins, in the order they were loaded. + // + vector initializedPlugins; + try + { + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) + { + try + { + p->plugin->initialize(); + } + catch(const Ice::PluginInitializationException&) + { + throw; + } + catch(const std::exception& ex) + { + ostringstream os; + os << "plugin `" << p->name << "' initialization failed:\n" << ex.what(); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + catch(...) + { + ostringstream os; + os << "plugin `" << p->name << "' initialization failed:\nunknown exception"; + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + initializedPlugins.push_back(p->plugin); + } + } + catch(...) + { + // + // Destroy the plug-ins that have been successfully initialized, in the + // reverse order. + // + for(vector::reverse_iterator p = initializedPlugins.rbegin(); p != initializedPlugins.rend(); ++p) + { + try + { + (*p)->destroy(); + } + catch(...) + { + // Ignore. + } + } + throw; + } + + _initialized = true; +} + +StringSeq +Ice::PluginManagerI::getPlugins() ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + StringSeq names; + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) + { + names.push_back(p->name); + } + return names; +} + +PluginPtr +Ice::PluginManagerI::getPlugin(const string& name) +{ + IceUtil::Mutex::Lock sync(*this); + + if(!_communicator) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + PluginPtr p = findPlugin(name); + if(p) + { + return p; + } + + throw NotRegisteredException(__FILE__, __LINE__, _kindOfObject, name); +} + +void +Ice::PluginManagerI::addPlugin(const string& name, const PluginPtr& plugin) +{ + IceUtil::Mutex::Lock sync(*this); + + if(!_communicator) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(findPlugin(name)) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, _kindOfObject, name); + } + + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); +} + +void +Ice::PluginManagerI::destroy() ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + if(_communicator) + { + if(_initialized) + { + + // + // Destroy the plug-ins that have been successfully initialized, in the + // reverse order. + // + for(PluginInfoList::reverse_iterator p = _plugins.rbegin(); p != _plugins.rend(); ++p) + { + try + { + p->plugin->destroy(); + } + catch(const std::exception& ex) + { + Warning out(getProcessLogger()); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << ex.what(); + } + catch(const std::string& str) + { + Warning out(getProcessLogger()); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << str; + } + catch(const char* msg) + { + Warning out(getProcessLogger()); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << msg; + } + catch(...) + { + Warning out(getProcessLogger()); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction"; + } + } + } + + _communicator = 0; + } + + _plugins.clear(); + _libraries = 0; +} + +Ice::PluginManagerI::PluginManagerI(const CommunicatorPtr& communicator, const DynamicLibraryListPtr& libraries) : + _communicator(communicator), + _libraries(libraries), + _initialized(false) +{ +} + +void +Ice::PluginManagerI::loadPlugins(int& argc, const char* argv[]) +{ + assert(_communicator); + + StringSeq cmdArgs = argsToStringSeq(argc, argv); + + const string prefix = "Ice.Plugin."; + PropertiesPtr properties = _communicator->getProperties(); + PropertyDict plugins = properties->getPropertiesForPrefix(prefix); + + // + // First, load static plugin factories which were setup to load on + // communicator initialization. If a matching plugin property is + // set, we load the plugin with the plugin specification. The + // entryPoint will be ignored but the rest of the plugin + // specification might be used. + // + if(loadOnInitialization) + { + for(vector::const_iterator p = loadOnInitialization->begin(); p != loadOnInitialization->end(); ++p) + { + string property = prefix + *p; + PropertyDict::iterator r = plugins.find(property + ".cpp"); + if(r == plugins.end()) + { + r = plugins.find(property); + } + else + { + plugins.erase(property); + } + + if(r != plugins.end()) + { + loadPlugin(*p, r->second, cmdArgs); + plugins.erase(r); + } + else + { + loadPlugin(*p, "", cmdArgs); + } + } + } + + // + // Next, load and initialize the plug-ins defined in the property + // set with the prefix "Ice.Plugin.". These properties should have + // the following format: + // + // Ice.Plugin.name[.]=entry_point [args] + // + // If the Ice.PluginLoadOrder property is defined, load the + // specified plug-ins in the specified order, then load any + // remaining plug-ins. + // + StringSeq loadOrder = properties->getPropertyAsList("Ice.PluginLoadOrder"); + for(StringSeq::const_iterator p = loadOrder.begin(); p != loadOrder.end(); ++p) + { + string name = *p; + + if(findPlugin(name)) + { + throw PluginInitializationException(__FILE__, __LINE__, "plug-in `" + name + "' already loaded"); + } + + string property = prefix + name; + PropertyDict::iterator r = plugins.find(property + ".cpp"); + if(r == plugins.end()) + { + r = plugins.find(property); + } + else + { + plugins.erase(property); + } + + if(r != plugins.end()) + { + loadPlugin(name, r->second, cmdArgs); + plugins.erase(r); + } + else + { + throw PluginInitializationException(__FILE__, __LINE__, "plug-in `" + name + "' not defined"); + } + } + + // + // Load any remaining plug-ins that weren't specified in PluginLoadOrder. + // + + while(!plugins.empty()) + { + PropertyDict::iterator p = plugins.begin(); + + string name = p->first.substr(prefix.size()); + + size_t dotPos = name.find_last_of('.'); + if(dotPos != string::npos) + { + string suffix = name.substr(dotPos + 1); + if(suffix == "java" || suffix == "clr") + { + // + // Ignored + // + plugins.erase(p); + } + else if(suffix == "cpp") + { + name = name.substr(0, dotPos); + loadPlugin(name, p->second, cmdArgs); + plugins.erase(p); + + plugins.erase(prefix + name); + } + else + { + // + // Name is just a regular name that happens to contain a dot + // + dotPos = string::npos; + } + } + + if(dotPos == string::npos) + { + // + // Is there a .cpp entry? + // + PropertyDict::iterator q = plugins.find(prefix + name + ".cpp"); + if(q != plugins.end()) + { + plugins.erase(p); + p = q; + } + + loadPlugin(name, p->second, cmdArgs); + plugins.erase(p); + } + } + + stringSeqToArgs(cmdArgs, argc, argv); +} + +void +Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, StringSeq& cmdArgs) +{ + assert(_communicator); + + string entryPoint; + StringSeq args; + if(!pluginSpec.empty()) + { + // + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. + // + try + { + args = IceUtilInternal::Options::split(pluginSpec); + } + catch(const IceUtilInternal::BadOptException& ex) + { + throw PluginInitializationException(__FILE__, __LINE__, "invalid arguments for plug-in `" + name + "':\n" + + ex.reason); + } + + assert(!args.empty()); + + // + // Shift the arguments. + // + entryPoint = args[0]; + args.erase(args.begin()); + + // + // Convert command-line options into properties. First we + // convert the options from the plug-in configuration, then + // we convert the options from the application command-line. + // + PropertiesPtr properties = _communicator->getProperties(); + args = properties->parseCommandLineOptions(name, args); + cmdArgs = properties->parseCommandLineOptions(name, cmdArgs); + } + + PluginFactory factory = 0; + DynamicLibraryPtr library; + + // + // Always check the static plugin factory table first, it takes + // precedence over the the entryPoint specified in the plugin + // property value. + // + if(factories) + { + map::const_iterator p = factories->find(name); + if(p != factories->end()) + { + factory = p->second; + } + } + + // + // If we didn't find the factory, get the factory using the entry + // point symbol. + // + if(!factory) + { + assert(!entryPoint.empty()); + library = new DynamicLibrary(); + DynamicLibrary::symbol_type sym = library->loadEntryPoint(entryPoint); + if(sym == 0) + { + ostringstream os; + string msg = library->getErrorMessage(); + os << "unable to load entry point `" << entryPoint << "'"; + if(!msg.empty()) + { + os << ": " + msg; + } + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + +#ifdef __IBMCPP__ + // xlC warns when casting a void* to function pointer +# pragma report(disable, "1540-0216") +#endif + + factory = reinterpret_cast(sym); + } + + // + // Invoke the factory function. No exceptions can be raised + // by the factory function because it's declared extern "C". + // + PluginPtr plugin(factory(_communicator, name, args)); + if(!plugin) + { + throw PluginInitializationException(__FILE__, __LINE__, "failure in entry point `" + entryPoint + "'"); + } + + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); + + if(library) + { + _libraries->add(library); + } +} + +Ice::PluginPtr +Ice::PluginManagerI::findPlugin(const string& name) const +{ + for(PluginInfoList::const_iterator p = _plugins.begin(); p != _plugins.end(); ++p) + { + if(name == p->name) + { + return p->plugin; + } + } + return 0; +} diff --git a/Sources/IceCpp/Process.cpp b/Sources/IceCpp/Process.cpp new file mode 100644 index 0000000..0eaaffd --- /dev/null +++ b/Sources/IceCpp/Process.cpp @@ -0,0 +1,471 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Process.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_Ice_Process_ids[2] = +{ + "::Ice::Object", + "::Ice::Process" +}; +const ::std::string iceC_Ice_Process_ops[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "shutdown", + "writeMessage" +}; +const ::std::string iceC_Ice_Process_shutdown_name = "shutdown"; +const ::std::string iceC_Ice_Process_writeMessage_name = "writeMessage"; + +} + +bool +Ice::Process::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Process_ids, iceC_Ice_Process_ids + 2, s); +} + +::std::vector<::std::string> +Ice::Process::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_Process_ids[0], &iceC_Ice_Process_ids[2]); +} + +::std::string +Ice::Process::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Process::ice_staticId() +{ + static const ::std::string typeId = "::Ice::Process"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::Process::_iceD_shutdown(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + inS.readEmptyParams(); + this->shutdown(current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Process::_iceD_writeMessage(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_message; + int iceP_fd; + istr->readAll(iceP_message, iceP_fd); + inS.endReadParams(); + this->writeMessage(::std::move(iceP_message), iceP_fd, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Process::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Process_ops, iceC_Ice_Process_ops + 6, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Process_ops) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_shutdown(in, current); + } + case 5: + { + return _iceD_writeMessage(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +Ice::ProcessPrx::_iceI_shutdown(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const Context& context) +{ + outAsync->invoke(iceC_Ice_Process_shutdown_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::ProcessPrx::_iceI_writeMessage(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_message, int iceP_fd, const Context& context) +{ + outAsync->invoke(iceC_Ice_Process_writeMessage_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_message, iceP_fd); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::ProcessPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::ProcessPrx::ice_staticId() +{ + return Process::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_Ice_Process_shutdown_name = "shutdown"; + +const ::std::string iceC_Ice_Process_writeMessage_name = "writeMessage"; + +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(Process* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Process>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Process; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::Process::_iceI_begin_shutdown(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Process_shutdown_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Process_shutdown_name, ::Ice::Normal, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_Process_shutdown_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::Process::end_shutdown(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_Ice_Process_shutdown_name); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Process::_iceI_begin_writeMessage(const ::std::string& iceP_message, ::Ice::Int iceP_fd, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Process_writeMessage_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Process_writeMessage_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_message); + ostr->write(iceP_fd); + result->endWriteParams(); + result->invoke(iceC_Ice_Process_writeMessage_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::Process::end_writeMessage(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_Ice_Process_writeMessage_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::Process::_newInstance() const +{ + return new Process; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::Process::ice_staticId() +{ + return ::Ice::Process::ice_staticId(); +} + +Ice::Process::~Process() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(Process* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Process_ids[2] = +{ + "::Ice::Object", + "::Ice::Process" +}; + +} + +bool +Ice::Process::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Process_ids, iceC_Ice_Process_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::Process::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_Process_ids[0], &iceC_Ice_Process_ids[2]); +} + +const ::std::string& +Ice::Process::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Process::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::Process"; + return typeId; +#else + return iceC_Ice_Process_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +Ice::Process::_iceD_shutdown(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + inS.readEmptyParams(); + this->shutdown(current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Process::_iceD_writeMessage(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_message; + Int iceP_fd; + istr->read(iceP_message); + istr->read(iceP_fd); + inS.endReadParams(); + this->writeMessage(iceP_message, iceP_fd, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Process_all[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "shutdown", + "writeMessage" +}; + +} + +/// \cond INTERNAL +bool +Ice::Process::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Process_all, iceC_Ice_Process_all + 6, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Process_all) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_shutdown(in, current); + } + case 5: + { + return _iceD_writeMessage(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::Process::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< Process, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::Process::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< Process, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(ProcessPtr& handle, const ObjectPtr& v) +{ + handle = ProcessPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Process::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ProcessF.cpp b/Sources/IceCpp/ProcessF.cpp new file mode 100644 index 0000000..2d2c49a --- /dev/null +++ b/Sources/IceCpp/ProcessF.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ProcessF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/Properties.cpp b/Sources/IceCpp/Properties.cpp new file mode 100644 index 0000000..1fc3050 --- /dev/null +++ b/Sources/IceCpp/Properties.cpp @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Properties.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::Properties::~Properties() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::Properties::~Properties() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(Properties* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/PropertiesAdmin.cpp b/Sources/IceCpp/PropertiesAdmin.cpp new file mode 100644 index 0000000..f11f095 --- /dev/null +++ b/Sources/IceCpp/PropertiesAdmin.cpp @@ -0,0 +1,603 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesAdmin.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_Ice_PropertiesAdmin_ids[2] = +{ + "::Ice::Object", + "::Ice::PropertiesAdmin" +}; +const ::std::string iceC_Ice_PropertiesAdmin_ops[] = +{ + "getPropertiesForPrefix", + "getProperty", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "setProperties" +}; +const ::std::string iceC_Ice_PropertiesAdmin_getProperty_name = "getProperty"; +const ::std::string iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name = "getPropertiesForPrefix"; +const ::std::string iceC_Ice_PropertiesAdmin_setProperties_name = "setProperties"; + +} + +bool +Ice::PropertiesAdmin::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_PropertiesAdmin_ids, iceC_Ice_PropertiesAdmin_ids + 2, s); +} + +::std::vector<::std::string> +Ice::PropertiesAdmin::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_PropertiesAdmin_ids[0], &iceC_Ice_PropertiesAdmin_ids[2]); +} + +::std::string +Ice::PropertiesAdmin::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::PropertiesAdmin::ice_staticId() +{ + static const ::std::string typeId = "::Ice::PropertiesAdmin"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_getProperty(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_key; + istr->readAll(iceP_key); + inS.endReadParams(); + ::std::string ret = this->getProperty(::std::move(iceP_key), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_getPropertiesForPrefix(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_prefix; + istr->readAll(iceP_prefix); + inS.endReadParams(); + PropertyDict ret = this->getPropertiesForPrefix(::std::move(iceP_prefix), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_setProperties(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + PropertyDict iceP_newProperties; + istr->readAll(iceP_newProperties); + inS.endReadParams(); + this->setProperties(::std::move(iceP_newProperties), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_PropertiesAdmin_ops, iceC_Ice_PropertiesAdmin_ops + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_PropertiesAdmin_ops) + { + case 0: + { + return _iceD_getPropertiesForPrefix(in, current); + } + case 1: + { + return _iceD_getProperty(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + case 6: + { + return _iceD_setProperties(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +Ice::PropertiesAdminPrx::_iceI_getProperty(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::string>>& outAsync, const ::std::string& iceP_key, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_PropertiesAdmin_getProperty_name); + outAsync->invoke(iceC_Ice_PropertiesAdmin_getProperty_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_key); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::PropertiesAdminPrx::_iceI_getPropertiesForPrefix(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::Ice::PropertyDict>>& outAsync, const ::std::string& iceP_prefix, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name); + outAsync->invoke(iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_prefix); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::PropertiesAdminPrx::_iceI_setProperties(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const PropertyDict& iceP_newProperties, const Context& context) +{ + outAsync->invoke(iceC_Ice_PropertiesAdmin_setProperties_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_newProperties); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::PropertiesAdminPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::PropertiesAdminPrx::ice_staticId() +{ + return PropertiesAdmin::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_Ice_PropertiesAdmin_getProperty_name = "getProperty"; + +const ::std::string iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name = "getPropertiesForPrefix"; + +const ::std::string iceC_Ice_PropertiesAdmin_setProperties_name = "setProperties"; + +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(PropertiesAdmin* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< PropertiesAdmin>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new PropertiesAdmin; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::PropertiesAdmin::_iceI_begin_getProperty(const ::std::string& iceP_key, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_PropertiesAdmin_getProperty_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_PropertiesAdmin_getProperty_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_PropertiesAdmin_getProperty_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_key); + result->endWriteParams(); + result->invoke(iceC_Ice_PropertiesAdmin_getProperty_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::std::string +IceProxy::Ice::PropertiesAdmin::end_getProperty(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_PropertiesAdmin_getProperty_name); + ::std::string ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::PropertiesAdmin::_iceI_begin_getPropertiesForPrefix(const ::std::string& iceP_prefix, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_prefix); + result->endWriteParams(); + result->invoke(iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::PropertyDict +IceProxy::Ice::PropertiesAdmin::end_getPropertiesForPrefix(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_PropertiesAdmin_getPropertiesForPrefix_name); + ::Ice::PropertyDict ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::PropertiesAdmin::_iceI_begin_setProperties(const ::Ice::PropertyDict& iceP_newProperties, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_PropertiesAdmin_setProperties_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_PropertiesAdmin_setProperties_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_newProperties); + result->endWriteParams(); + result->invoke(iceC_Ice_PropertiesAdmin_setProperties_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::PropertiesAdmin::end_setProperties(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_Ice_PropertiesAdmin_setProperties_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::PropertiesAdmin::_newInstance() const +{ + return new PropertiesAdmin; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::PropertiesAdmin::ice_staticId() +{ + return ::Ice::PropertiesAdmin::ice_staticId(); +} + +Ice::PropertiesAdmin::~PropertiesAdmin() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(PropertiesAdmin* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_PropertiesAdmin_ids[2] = +{ + "::Ice::Object", + "::Ice::PropertiesAdmin" +}; + +} + +bool +Ice::PropertiesAdmin::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_PropertiesAdmin_ids, iceC_Ice_PropertiesAdmin_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::PropertiesAdmin::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_PropertiesAdmin_ids[0], &iceC_Ice_PropertiesAdmin_ids[2]); +} + +const ::std::string& +Ice::PropertiesAdmin::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::PropertiesAdmin::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::PropertiesAdmin"; + return typeId; +#else + return iceC_Ice_PropertiesAdmin_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_getProperty(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_key; + istr->read(iceP_key); + inS.endReadParams(); + ::std::string ret = this->getProperty(iceP_key, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_getPropertiesForPrefix(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_prefix; + istr->read(iceP_prefix); + inS.endReadParams(); + PropertyDict ret = this->getPropertiesForPrefix(iceP_prefix, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceD_setProperties(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + PropertyDict iceP_newProperties; + istr->read(iceP_newProperties); + inS.endReadParams(); + this->setProperties(iceP_newProperties, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_PropertiesAdmin_all[] = +{ + "getPropertiesForPrefix", + "getProperty", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "setProperties" +}; + +} + +/// \cond INTERNAL +bool +Ice::PropertiesAdmin::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_PropertiesAdmin_all, iceC_Ice_PropertiesAdmin_all + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_PropertiesAdmin_all) + { + case 0: + { + return _iceD_getPropertiesForPrefix(in, current); + } + case 1: + { + return _iceD_getProperty(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + case 6: + { + return _iceD_setProperties(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::PropertiesAdmin::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< PropertiesAdmin, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::PropertiesAdmin::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< PropertiesAdmin, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(PropertiesAdminPtr& handle, const ObjectPtr& v) +{ + handle = PropertiesAdminPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(PropertiesAdmin::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/PropertiesAdminI.cpp b/Sources/IceCpp/PropertiesAdminI.cpp new file mode 100644 index 0000000..72a2241 --- /dev/null +++ b/Sources/IceCpp/PropertiesAdminI.cpp @@ -0,0 +1,265 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; + +namespace +{ + +const char* traceCategory = "Admin.Properties"; + +} + +#ifndef ICE_CPP11_MAPPING +PropertiesAdminUpdateCallback::~PropertiesAdminUpdateCallback() +{ + // Out of line to avoid weak vtable +} +#endif + +NativePropertiesAdmin::~NativePropertiesAdmin() +{ + // Out of line to avoid weak vtable +} + +namespace IceInternal +{ + +PropertiesAdminI::PropertiesAdminI(const InstancePtr& instance) : + _properties(instance->initializationData().properties), + _logger(instance->initializationData().logger) +{ +} + +string +#ifdef ICE_CPP11_MAPPING +PropertiesAdminI::getProperty(string name, const Current&) +#else +PropertiesAdminI::getProperty(const string& name, const Current&) +#endif +{ + Lock sync(*this); + return _properties->getProperty(name); +} + +PropertyDict +#ifdef ICE_CPP11_MAPPING +PropertiesAdminI::getPropertiesForPrefix(string prefix, const Current&) +#else +PropertiesAdminI::getPropertiesForPrefix(const string& prefix, const Current&) +#endif +{ + Lock sync(*this); + return _properties->getPropertiesForPrefix(prefix); +} + +void +#ifdef ICE_CPP11_MAPPING +PropertiesAdminI::setProperties(PropertyDict props, const Current&) +#else +PropertiesAdminI::setProperties(const PropertyDict& props, const Current&) +#endif +{ + Lock sync(*this); + + PropertyDict old = _properties->getPropertiesForPrefix(""); + PropertyDict::const_iterator p; + const int traceLevel = _properties->getPropertyAsInt("Ice.Trace.Admin.Properties"); + + // + // Compute the difference between the new property set and the existing property set: + // + // 1) Any properties in the new set that were not defined in the existing set. + // + // 2) Any properties that appear in both sets but with different values. + // + // 3) Any properties not present in the new set but present in the existing set. + // In other words, the property has been removed. + // + PropertyDict added, changed, removed; + for(p = props.begin(); p != props.end(); ++p) + { + PropertyDict::iterator q = old.find(p->first); + if(q == old.end()) + { + if(!p->second.empty()) + { + // + // This property is new. + // + added.insert(*p); + } + } + else + { + if(p->second != q->second) + { + if(p->second.empty()) + { + // + // This property was removed. + // + removed.insert(*p); + } + else + { + // + // This property has changed. + // + changed.insert(*p); + } + } + } + } + + if(traceLevel > 0 && (!added.empty() || !changed.empty() || !removed.empty())) + { + Trace out(_logger, traceCategory); + + out << "Summary of property changes"; + + if(!added.empty()) + { + out << "\nNew properties:"; + for(p = added.begin(); p != added.end(); ++p) + { + out << "\n " << p->first; + if(traceLevel > 1) + { + out << " = " << p->second; + } + } + } + + if(!changed.empty()) + { + out << "\nChanged properties:"; + for(p = changed.begin(); p != changed.end(); ++p) + { + out << "\n " << p->first; + if(traceLevel > 1) + { + out << " = " << p->second << " (old value = " << _properties->getProperty(p->first) << ")"; + } + } + } + + if(!removed.empty()) + { + out << "\nRemoved properties:"; + for(p = removed.begin(); p != removed.end(); ++p) + { + out << "\n " << p->first; + } + } + } + + // + // Update the property set. + // + + for(p = added.begin(); p != added.end(); ++p) + { + _properties->setProperty(p->first, p->second); + } + + for(p = changed.begin(); p != changed.end(); ++p) + { + _properties->setProperty(p->first, p->second); + } + + for(p = removed.begin(); p != removed.end(); ++p) + { + _properties->setProperty(p->first, ""); + } + + if(!_updateCallbacks.empty()) + { + PropertyDict changes = added; + changes.insert(changed.begin(), changed.end()); + changes.insert(removed.begin(), removed.end()); + + // Copy callbacks to allow callbacks to update callbacks +#ifdef ICE_CPP11_MAPPING + auto callbacks = _updateCallbacks; + for(const auto& cb : callbacks) +#else + vector callbacks = _updateCallbacks; + for(vector::const_iterator q = callbacks.begin(); q != callbacks.end(); ++q) +#endif + { + try + { +#ifdef ICE_CPP11_MAPPING + cb(changes); +#else + (*q)->updated(changes); +#endif + } + catch(const std::exception& ex) + { + if(_properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) + { + Warning out(_logger); + out << "properties admin update callback raised unexpected exception:\n" << ex; + } + } + catch(...) + { + if(_properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) + { + Warning out(_logger); + out << "properties admin update callback raised unexpected exception:\nunknown c++ exception"; + } + } + } + } +} + +#ifdef ICE_CPP11_MAPPING + +std::function +PropertiesAdminI::addUpdateCallback(std::function cb) +{ + Lock sync(*this); + + auto p = _updateCallbacks.insert(_updateCallbacks.end(), std::move(cb)); + auto propertiesAdmin = shared_from_this(); + + return [p, propertiesAdmin] { propertiesAdmin->removeUpdateCallback(p); }; +} + +void +PropertiesAdminI::removeUpdateCallback(std::list>::iterator p) +{ + Lock sync(*this); + _updateCallbacks.erase(p); +} + +#else + +void +PropertiesAdminI::addUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb) +{ + Lock sync(*this); + _updateCallbacks.push_back(cb); +} + +void +PropertiesAdminI::removeUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb) +{ + Lock sync(*this); + _updateCallbacks.erase(remove(_updateCallbacks.begin(), _updateCallbacks.end(), cb), _updateCallbacks.end()); +} + +#endif + +} diff --git a/Sources/IceCpp/PropertiesF.cpp b/Sources/IceCpp/PropertiesF.cpp new file mode 100644 index 0000000..75369c0 --- /dev/null +++ b/Sources/IceCpp/PropertiesF.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/PropertiesI.cpp b/Sources/IceCpp/PropertiesI.cpp new file mode 100644 index 0000000..72ca5d4 --- /dev/null +++ b/Sources/IceCpp/PropertiesI.cpp @@ -0,0 +1,739 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +string +Ice::PropertiesI::getProperty(const string& key) ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + map::iterator p = _properties.find(key); + if(p != _properties.end()) + { + p->second.used = true; + return p->second.value; + } + else + { + return string(); + } +} + +string +Ice::PropertiesI::getPropertyWithDefault(const string& key, const string& value) ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + map::iterator p = _properties.find(key); + if(p != _properties.end()) + { + p->second.used = true; + return p->second.value; + } + else + { + return value; + } +} + +Int +Ice::PropertiesI::getPropertyAsInt(const string& key) ICE_NOEXCEPT +{ + return getPropertyAsIntWithDefault(key, 0); +} + +Int +Ice::PropertiesI::getPropertyAsIntWithDefault(const string& key, Int value) ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + map::iterator p = _properties.find(key); + if(p != _properties.end()) + { + Int val = value; + p->second.used = true; + istringstream v(p->second.value); + if(!(v >> value) || !v.eof()) + { + Warning out(getProcessLogger()); + out << "numeric property " << key << " set to non-numeric value, defaulting to " << val; + return val; + } + } + + return value; +} + +Ice::StringSeq +Ice::PropertiesI::getPropertyAsList(const string& key) ICE_NOEXCEPT +{ + return getPropertyAsListWithDefault(key, StringSeq()); +} + +Ice::StringSeq +Ice::PropertiesI::getPropertyAsListWithDefault(const string& key, const StringSeq& value) ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + map::iterator p = _properties.find(key); + if(p != _properties.end()) + { + p->second.used = true; + + StringSeq result; + if(!IceUtilInternal::splitString(p->second.value, ", \t\r\n", result)) + { + Warning out(getProcessLogger()); + out << "mismatched quotes in property " << key << "'s value, returning default value"; + } + if(result.size() == 0) + { + result = value; + } + return result; + } + else + { + return value; + } +} + +PropertyDict +Ice::PropertiesI::getPropertiesForPrefix(const string& prefix) ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + PropertyDict result; + for(map::iterator p = _properties.begin(); p != _properties.end(); ++p) + { + if(prefix.empty() || p->first.compare(0, prefix.size(), prefix) == 0) + { + p->second.used = true; + result[p->first] = p->second.value; + } + } + + return result; +} + +void +Ice::PropertiesI::setProperty(const string& key, const string& value) +{ + // + // Trim whitespace + // + string currentKey = IceUtilInternal::trim(key); + if(currentKey.empty()) + { + throw InitializationException(__FILE__, __LINE__, "Attempt to set property with empty key"); + } + + // + // Check if the property is legal. + // + LoggerPtr logger = getProcessLogger(); + string::size_type dotPos = currentKey.find('.'); + if(dotPos != string::npos) + { + string prefix = currentKey.substr(0, dotPos); + for(int i = 0 ; IceInternal::PropertyNames::validProps[i].properties != 0; ++i) + { + string pattern(IceInternal::PropertyNames::validProps[i].properties[0].pattern); + + dotPos = pattern.find('.'); + + // + // Each top level prefix describes a non-empty + // namespace. Having a string without a prefix followed by a + // dot is an error. + // + assert(dotPos != string::npos); + + bool mismatchCase = false; + string otherKey; + string propPrefix = pattern.substr(0, dotPos); + if(IceUtilInternal::toUpper(propPrefix) != IceUtilInternal::toUpper(prefix)) + { + continue; + } + + bool found = false; + + for(int j = 0; j < IceInternal::PropertyNames::validProps[i].length && !found; ++j) + { + const IceInternal::Property& prop = IceInternal::PropertyNames::validProps[i].properties[j]; + found = IceUtilInternal::match(currentKey, prop.pattern); + + if(found && prop.deprecated) + { + logger->warning("deprecated property: " + currentKey); + if(prop.deprecatedBy != 0) + { + currentKey = prop.deprecatedBy; + } + } + + if(!found && IceUtilInternal::match(IceUtilInternal::toUpper(currentKey), + IceUtilInternal::toUpper(prop.pattern))) + { + found = true; + mismatchCase = true; + otherKey = prop.pattern; + break; + } + } + if(!found) + { + logger->warning("unknown property: `" + currentKey + "'"); + } + else if(mismatchCase) + { + logger->warning("unknown property: `" + currentKey + "'; did you mean `" + otherKey + "'"); + } + } + } + + IceUtil::Mutex::Lock sync(*this); + + // + // Set or clear the property. + // + if(!value.empty()) + { + PropertyValue pv(value, false); + map::const_iterator p = _properties.find(currentKey); + if(p != _properties.end()) + { + pv.used = p->second.used; + } + _properties[currentKey] = pv; + } + else + { + _properties.erase(currentKey); + } +} + +StringSeq +Ice::PropertiesI::getCommandLineOptions() ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + StringSeq result; + result.reserve(_properties.size()); + for(map::const_iterator p = _properties.begin(); p != _properties.end(); ++p) + { + result.push_back("--" + p->first + "=" + p->second.value); + } + return result; +} + +StringSeq +Ice::PropertiesI::parseCommandLineOptions(const string& prefix, const StringSeq& options) +{ + string pfx = prefix; + if(!pfx.empty() && pfx[pfx.size() - 1] != '.') + { + pfx += '.'; + } + pfx = "--" + pfx; + + StringSeq result; + for(StringSeq::size_type i = 0; i < options.size(); i++) + { + string opt = options[i]; + + if(opt.find(pfx) == 0) + { + if(opt.find('=') == string::npos) + { + opt += "=1"; + } + + parseLine(opt.substr(2), 0); + } + else + { + result.push_back(opt); + } + } + return result; +} + +StringSeq +Ice::PropertiesI::parseIceCommandLineOptions(const StringSeq& options) +{ + StringSeq args = options; + for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) + { + args = parseCommandLineOptions(*i, args); + } + return args; + +} + +void +Ice::PropertiesI::load(const std::string& file) +{ + StringConverterPtr stringConverter = getProcessStringConverter(); + +#if defined (_WIN32) + if(file.find("HKCU\\") == 0 || file.find("HKLM\\") == 0) + { + HKEY key = file.find("HKCU\\") == 0 ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + HKEY iceKey; + const wstring keyName = stringToWstring(file, stringConverter).substr(file.find("\\") + 1).c_str(); + LONG err; + if((err = RegOpenKeyExW(key, keyName.c_str(), 0, KEY_QUERY_VALUE, &iceKey)) != ERROR_SUCCESS) + { + throw InitializationException(__FILE__, __LINE__, "could not open Windows registry key `" + file + "':\n" + + IceUtilInternal::errorToString(err)); + } + + DWORD maxNameSize; // Size in characters not including terminating null character. + DWORD maxDataSize; // Size in bytes + DWORD numValues; + try + { + err = RegQueryInfoKey(iceKey, ICE_NULLPTR, ICE_NULLPTR, ICE_NULLPTR, ICE_NULLPTR, ICE_NULLPTR, ICE_NULLPTR, + &numValues, &maxNameSize, &maxDataSize, ICE_NULLPTR, ICE_NULLPTR); + if(err != ERROR_SUCCESS) + { + throw InitializationException(__FILE__, __LINE__, "could not open Windows registry key `" + file + + "':\n" + IceUtilInternal::errorToString(err)); + } + + for(DWORD i = 0; i < numValues; ++i) + { + vector nameBuf(maxNameSize + 1); + vector dataBuf(maxDataSize); + DWORD keyType; + DWORD nameBufSize = static_cast(nameBuf.size()); + DWORD dataBufSize = static_cast(dataBuf.size()); + err = RegEnumValueW(iceKey, i, &nameBuf[0], &nameBufSize, ICE_NULLPTR, &keyType, &dataBuf[0], &dataBufSize); + if(err != ERROR_SUCCESS || nameBufSize == 0) + { + ostringstream os; + os << "could not read Windows registry property name, key: `" + file + "', index: " << i << ":\n"; + if(nameBufSize == 0) + { + os << "property name can't be the empty string"; + } + else + { + os << IceUtilInternal::errorToString(err); + } + getProcessLogger()->warning(os.str()); + continue; + } + string name = wstringToString( + wstring(reinterpret_cast(&nameBuf[0]), nameBufSize), stringConverter); + if(keyType != REG_SZ && keyType != REG_EXPAND_SZ) + { + ostringstream os; + os << "unsupported type for Windows registry property `" + name + "' key: `" + file + "'"; + getProcessLogger()->warning(os.str()); + continue; + } + + string value; + wstring valueW = wstring(reinterpret_cast(&dataBuf[0]), (dataBufSize / sizeof(wchar_t)) - 1); + if(keyType == REG_SZ) + { + value = wstringToString(valueW, stringConverter); + } + else // keyType == REG_EXPAND_SZ + { + vector expandedValue(1024); + DWORD sz = ExpandEnvironmentStringsW(valueW.c_str(), &expandedValue[0], + static_cast(expandedValue.size())); + if(sz >= expandedValue.size()) + { + expandedValue.resize(sz + 1); + if(ExpandEnvironmentStringsW(valueW.c_str(), &expandedValue[0], + static_cast(expandedValue.size())) == 0) + { + ostringstream os; + os << "could not expand variable in property `" << name << "', key: `" + file + "':\n"; + os << IceUtilInternal::lastErrorToString(); + getProcessLogger()->warning(os.str()); + continue; + } + } + value = wstringToString(wstring(&expandedValue[0], sz -1), stringConverter); + } + setProperty(name, value); + } + } + catch(...) + { + RegCloseKey(iceKey); + throw; + } + RegCloseKey(iceKey); + } + else +#endif + { + ifstream in(IceUtilInternal::streamFilename(file).c_str()); + if(!in) + { + throw FileException(__FILE__, __LINE__, getSystemErrno(), file); + } + + string line; + bool firstLine = true; + while(getline(in, line)) + { + // + // Skip UTF8 BOM if present. + // + if(firstLine) + { + const unsigned char UTF8_BOM[3] = {0xEF, 0xBB, 0xBF}; + if(line.size() >= 3 && + static_cast(line[0]) == UTF8_BOM[0] && + static_cast(line[1]) == UTF8_BOM[1] && + static_cast(line[2]) == UTF8_BOM[2]) + { + line = line.substr(3); + } + firstLine = false; + } + parseLine(line, stringConverter); + } + } +} + +PropertiesPtr +Ice::PropertiesI::clone() ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + return ICE_MAKE_SHARED(PropertiesI, this); +} + +set +Ice::PropertiesI::getUnusedProperties() +{ + IceUtil::Mutex::Lock sync(*this); + set unusedProperties; + for(map::const_iterator p = _properties.begin(); p != _properties.end(); ++p) + { + if(!p->second.used) + { + unusedProperties.insert(p->first); + } + } + return unusedProperties; +} + +Ice::PropertiesI::PropertiesI(const PropertiesI* p) : + _properties(p->_properties) +{ +} + +Ice::PropertiesI::PropertiesI() +{ +} + +Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults) +{ + if(defaults != 0) + { + _properties = static_cast(defaults.get())->_properties; + } + + StringSeq::iterator q = args.begin(); + + map::iterator p = _properties.find("Ice.ProgramName"); + if(p == _properties.end()) + { + if(q != args.end()) + { + // + // Use the first argument as the value for Ice.ProgramName. Replace + // any backslashes in this value with forward slashes, in case this + // value is used by the event logger. + // + string name = *q; + replace(name.begin(), name.end(), '\\', '/'); + + PropertyValue pv(name, true); + _properties["Ice.ProgramName"] = pv; + } + } + else + { + p->second.used = true; + } + + StringSeq tmp; + + bool loadConfigFiles = false; + while(q != args.end()) + { + string s = *q; + if(s.find("--Ice.Config") == 0) + { + if(s.find('=') == string::npos) + { + s += "=1"; + } + parseLine(s.substr(2), 0); + loadConfigFiles = true; + } + else + { + tmp.push_back(s); + } + ++q; + } + args = tmp; + + if(!loadConfigFiles) + { + // + // If Ice.Config is not set, load from ICE_CONFIG (if set) + // + loadConfigFiles = (_properties.find("Ice.Config") == _properties.end()); + } + + if(loadConfigFiles) + { + loadConfig(); + } + + args = parseIceCommandLineOptions(args); +} + +void +Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& converter) +{ + string key; + string value; + + enum ParseState { Key , Value }; + ParseState state = Key; + + string whitespace; + string escapedspace; + bool finished = false; + for(string::size_type i = 0; i < line.size(); ++i) + { + char c = line[i]; + switch(state) + { + case Key: + { + switch(c) + { + case '\\': + if(i < line.length() - 1) + { + c = line[++i]; + switch(c) + { + case '\\': + case '#': + case '=': + key += whitespace; + whitespace.clear(); + key += c; + break; + + case ' ': + if(key.length() != 0) + { + whitespace += c; + } + break; + + default: + key += whitespace; + whitespace.clear(); + key += '\\'; + key += c; + break; + } + } + else + { + key += whitespace; + key += c; + } + break; + + case ' ': + case '\t': + case '\r': + case '\n': + if(key.length() != 0) + { + whitespace += c; + } + break; + + case '=': + whitespace.clear(); + state = Value; + break; + + case '#': + finished = true; + break; + + default: + key += whitespace; + whitespace.clear(); + key += c; + break; + } + break; + } + + case Value: + { + switch(c) + { + case '\\': + if(i < line.length() - 1) + { + c = line[++i]; + switch(c) + { + case '\\': + case '#': + case '=': + value += value.length() == 0 ? escapedspace : whitespace; + whitespace.clear(); + escapedspace.clear(); + value += c; + break; + + case ' ': + whitespace += c; + escapedspace += c; + break; + + default: + value += value.length() == 0 ? escapedspace : whitespace; + whitespace.clear(); + escapedspace.clear(); + value += '\\'; + value += c; + break; + } + } + else + { + value += value.length() == 0 ? escapedspace : whitespace; + value += c; + } + break; + + case ' ': + case '\t': + case '\r': + case '\n': + if(value.length() != 0) + { + whitespace += c; + } + break; + + case '#': + finished = true; + break; + + default: + value += value.length() == 0 ? escapedspace : whitespace; + whitespace.clear(); + escapedspace.clear(); + value += c; + break; + } + break; + } + } + if(finished) + { + break; + } + } + value += escapedspace; + + if((state == Key && key.length() != 0) || (state == Value && key.length() == 0)) + { + getProcessLogger()->warning("invalid config file entry: \"" + line + "\""); + return; + } + else if(key.length() == 0) + { + return; + } + + key = UTF8ToNative(key, converter); + value = UTF8ToNative(value, converter); + + setProperty(key, value); +} + +void +Ice::PropertiesI::loadConfig() +{ + string value = getProperty("Ice.Config"); + if(value.empty() || value == "1") + { +#ifdef _WIN32 + vector v(256); + DWORD ret = GetEnvironmentVariableW(L"ICE_CONFIG", &v[0], static_cast(v.size())); + if(ret >= v.size()) + { + v.resize(ret + 1); + ret = GetEnvironmentVariableW(L"ICE_CONFIG", &v[0], static_cast(v.size())); + } + if(ret > 0) + { + value = wstringToString(wstring(&v[0], ret), getProcessStringConverter()); + } + else + { + value = ""; + } +#else + const char* s = getenv("ICE_CONFIG"); + if(s && *s != '\0') + { + value = s; + } +#endif + } + + if(!value.empty()) + { + vector files; + IceUtilInternal::splitString(value, ",", files); + for(vector::const_iterator i = files.begin(); i != files.end(); ++i) + { + load(IceUtilInternal::trim(*i)); + } + + PropertyValue pv(value, true); + _properties["Ice.Config"] = pv; + } +} diff --git a/Sources/IceCpp/PropertyNames.cpp b/Sources/IceCpp/PropertyNames.cpp new file mode 100644 index 0000000..9324e94 --- /dev/null +++ b/Sources/IceCpp/PropertyNames.cpp @@ -0,0 +1,1429 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Jan 7 10:30:00 2022 + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! + +#include + +const IceInternal::Property IcePropsData[] = +{ + IceInternal::Property("Ice.AcceptClassCycles", false, 0), + IceInternal::Property("Ice.ACM.Client", true, 0), + IceInternal::Property("Ice.ACM.Server", true, 0), + IceInternal::Property("Ice.ACM.Timeout", false, 0), + IceInternal::Property("Ice.ACM.Heartbeat", false, 0), + IceInternal::Property("Ice.ACM.Close", false, 0), + IceInternal::Property("Ice.ACM", false, 0), + IceInternal::Property("Ice.ACM.Client.Timeout", false, 0), + IceInternal::Property("Ice.ACM.Client.Heartbeat", false, 0), + IceInternal::Property("Ice.ACM.Client.Close", false, 0), + IceInternal::Property("Ice.ACM.Client", false, 0), + IceInternal::Property("Ice.ACM.Server.Timeout", false, 0), + IceInternal::Property("Ice.ACM.Server.Heartbeat", false, 0), + IceInternal::Property("Ice.ACM.Server.Close", false, 0), + IceInternal::Property("Ice.ACM.Server", false, 0), + IceInternal::Property("Ice.Admin.ACM.Timeout", false, 0), + IceInternal::Property("Ice.Admin.ACM.Heartbeat", false, 0), + IceInternal::Property("Ice.Admin.ACM.Close", false, 0), + IceInternal::Property("Ice.Admin.ACM", false, 0), + IceInternal::Property("Ice.Admin.AdapterId", false, 0), + IceInternal::Property("Ice.Admin.Endpoints", false, 0), + IceInternal::Property("Ice.Admin.Locator.EndpointSelection", false, 0), + IceInternal::Property("Ice.Admin.Locator.ConnectionCached", false, 0), + IceInternal::Property("Ice.Admin.Locator.PreferSecure", false, 0), + IceInternal::Property("Ice.Admin.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("Ice.Admin.Locator.InvocationTimeout", false, 0), + IceInternal::Property("Ice.Admin.Locator.Locator", false, 0), + IceInternal::Property("Ice.Admin.Locator.Router", false, 0), + IceInternal::Property("Ice.Admin.Locator.CollocationOptimized", false, 0), + IceInternal::Property("Ice.Admin.Locator.Context.*", false, 0), + IceInternal::Property("Ice.Admin.Locator", false, 0), + IceInternal::Property("Ice.Admin.PublishedEndpoints", false, 0), + IceInternal::Property("Ice.Admin.ReplicaGroupId", false, 0), + IceInternal::Property("Ice.Admin.Router.EndpointSelection", false, 0), + IceInternal::Property("Ice.Admin.Router.ConnectionCached", false, 0), + IceInternal::Property("Ice.Admin.Router.PreferSecure", false, 0), + IceInternal::Property("Ice.Admin.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("Ice.Admin.Router.InvocationTimeout", false, 0), + IceInternal::Property("Ice.Admin.Router.Locator", false, 0), + IceInternal::Property("Ice.Admin.Router.Router", false, 0), + IceInternal::Property("Ice.Admin.Router.CollocationOptimized", false, 0), + IceInternal::Property("Ice.Admin.Router.Context.*", false, 0), + IceInternal::Property("Ice.Admin.Router", false, 0), + IceInternal::Property("Ice.Admin.ProxyOptions", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.Size", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.SizeMax", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.StackSize", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.Serialize", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("Ice.Admin.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("Ice.Admin.MessageSizeMax", false, 0), + IceInternal::Property("Ice.Admin.DelayCreation", false, 0), + IceInternal::Property("Ice.Admin.Enabled", false, 0), + IceInternal::Property("Ice.Admin.Facets", false, 0), + IceInternal::Property("Ice.Admin.InstanceName", false, 0), + IceInternal::Property("Ice.Admin.Logger.KeepLogs", false, 0), + IceInternal::Property("Ice.Admin.Logger.KeepTraces", false, 0), + IceInternal::Property("Ice.Admin.Logger.Properties", false, 0), + IceInternal::Property("Ice.Admin.ServerId", false, 0), + IceInternal::Property("Ice.BackgroundLocatorCacheUpdates", false, 0), + IceInternal::Property("Ice.BatchAutoFlush", true, 0), + IceInternal::Property("Ice.BatchAutoFlushSize", false, 0), + IceInternal::Property("Ice.ChangeUser", false, 0), + IceInternal::Property("Ice.ClassGraphDepthMax", false, 0), + IceInternal::Property("Ice.ClientAccessPolicyProtocol", false, 0), + IceInternal::Property("Ice.Compression.Level", false, 0), + IceInternal::Property("Ice.CollectObjects", false, 0), + IceInternal::Property("Ice.Config", false, 0), + IceInternal::Property("Ice.ConsoleListener", false, 0), + IceInternal::Property("Ice.Default.CollocationOptimized", false, 0), + IceInternal::Property("Ice.Default.EncodingVersion", false, 0), + IceInternal::Property("Ice.Default.EndpointSelection", false, 0), + IceInternal::Property("Ice.Default.Host", false, 0), + IceInternal::Property("Ice.Default.Locator.EndpointSelection", false, 0), + IceInternal::Property("Ice.Default.Locator.ConnectionCached", false, 0), + IceInternal::Property("Ice.Default.Locator.PreferSecure", false, 0), + IceInternal::Property("Ice.Default.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("Ice.Default.Locator.InvocationTimeout", false, 0), + IceInternal::Property("Ice.Default.Locator.Locator", false, 0), + IceInternal::Property("Ice.Default.Locator.Router", false, 0), + IceInternal::Property("Ice.Default.Locator.CollocationOptimized", false, 0), + IceInternal::Property("Ice.Default.Locator.Context.*", false, 0), + IceInternal::Property("Ice.Default.Locator", false, 0), + IceInternal::Property("Ice.Default.LocatorCacheTimeout", false, 0), + IceInternal::Property("Ice.Default.InvocationTimeout", false, 0), + IceInternal::Property("Ice.Default.Package", false, 0), + IceInternal::Property("Ice.Default.PreferSecure", false, 0), + IceInternal::Property("Ice.Default.Protocol", false, 0), + IceInternal::Property("Ice.Default.Router.EndpointSelection", false, 0), + IceInternal::Property("Ice.Default.Router.ConnectionCached", false, 0), + IceInternal::Property("Ice.Default.Router.PreferSecure", false, 0), + IceInternal::Property("Ice.Default.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("Ice.Default.Router.InvocationTimeout", false, 0), + IceInternal::Property("Ice.Default.Router.Locator", false, 0), + IceInternal::Property("Ice.Default.Router.Router", false, 0), + IceInternal::Property("Ice.Default.Router.CollocationOptimized", false, 0), + IceInternal::Property("Ice.Default.Router.Context.*", false, 0), + IceInternal::Property("Ice.Default.Router", false, 0), + IceInternal::Property("Ice.Default.SlicedFormat", false, 0), + IceInternal::Property("Ice.Default.SourceAddress", false, 0), + IceInternal::Property("Ice.Default.Timeout", false, 0), + IceInternal::Property("Ice.EventLog.Source", false, 0), + IceInternal::Property("Ice.FactoryAssemblies", false, 0), + IceInternal::Property("Ice.HTTPProxyHost", false, 0), + IceInternal::Property("Ice.HTTPProxyPort", false, 0), + IceInternal::Property("Ice.ImplicitContext", false, 0), + IceInternal::Property("Ice.InitPlugins", false, 0), + IceInternal::Property("Ice.IPv4", false, 0), + IceInternal::Property("Ice.IPv6", false, 0), + IceInternal::Property("Ice.LogFile", false, 0), + IceInternal::Property("Ice.LogFile.SizeMax", false, 0), + IceInternal::Property("Ice.LogStdErr.Convert", false, 0), + IceInternal::Property("Ice.MessageSizeMax", false, 0), + IceInternal::Property("Ice.Nohup", false, 0), + IceInternal::Property("Ice.NullHandleAbort", false, 0), + IceInternal::Property("Ice.Override.CloseTimeout", false, 0), + IceInternal::Property("Ice.Override.Compress", false, 0), + IceInternal::Property("Ice.Override.ConnectTimeout", false, 0), + IceInternal::Property("Ice.Override.Timeout", false, 0), + IceInternal::Property("Ice.Override.Secure", false, 0), + IceInternal::Property("Ice.Package.*", false, 0), + IceInternal::Property("Ice.Plugin.*", false, 0), + IceInternal::Property("Ice.PluginLoadOrder", false, 0), + IceInternal::Property("Ice.PreferIPv6Address", false, 0), + IceInternal::Property("Ice.PreloadAssemblies", false, 0), + IceInternal::Property("Ice.PrintAdapterReady", false, 0), + IceInternal::Property("Ice.PrintProcessId", false, 0), + IceInternal::Property("Ice.PrintStackTraces", false, 0), + IceInternal::Property("Ice.ProgramName", false, 0), + IceInternal::Property("Ice.RetryIntervals", false, 0), + IceInternal::Property("Ice.ServerIdleTime", false, 0), + IceInternal::Property("Ice.SOCKSProxyHost", false, 0), + IceInternal::Property("Ice.SOCKSProxyPort", false, 0), + IceInternal::Property("Ice.StdErr", false, 0), + IceInternal::Property("Ice.StdOut", false, 0), + IceInternal::Property("Ice.SyslogFacility", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.Size", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.SizeMax", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.SizeWarn", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.StackSize", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.Serialize", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.ThreadIdleTime", false, 0), + IceInternal::Property("Ice.ThreadPool.Client.ThreadPriority", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.Size", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.SizeMax", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.SizeWarn", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.StackSize", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.Serialize", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.ThreadIdleTime", false, 0), + IceInternal::Property("Ice.ThreadPool.Server.ThreadPriority", false, 0), + IceInternal::Property("Ice.ThreadPriority", false, 0), + IceInternal::Property("Ice.ToStringMode", false, 0), + IceInternal::Property("Ice.Trace.Admin.Properties", false, 0), + IceInternal::Property("Ice.Trace.Admin.Logger", false, 0), + IceInternal::Property("Ice.Trace.Locator", false, 0), + IceInternal::Property("Ice.Trace.Network", false, 0), + IceInternal::Property("Ice.Trace.Protocol", false, 0), + IceInternal::Property("Ice.Trace.Retry", false, 0), + IceInternal::Property("Ice.Trace.Slicing", false, 0), + IceInternal::Property("Ice.Trace.ThreadPool", false, 0), + IceInternal::Property("Ice.UDP.RcvSize", false, 0), + IceInternal::Property("Ice.UDP.SndSize", false, 0), + IceInternal::Property("Ice.TCP.Backlog", false, 0), + IceInternal::Property("Ice.TCP.RcvSize", false, 0), + IceInternal::Property("Ice.TCP.SndSize", false, 0), + IceInternal::Property("Ice.UseApplicationClassLoader", false, 0), + IceInternal::Property("Ice.UseOSLog", false, 0), + IceInternal::Property("Ice.UseSyslog", false, 0), + IceInternal::Property("Ice.UseSystemdJournal", false, 0), + IceInternal::Property("Ice.Warn.AMICallback", false, 0), + IceInternal::Property("Ice.Warn.Connections", false, 0), + IceInternal::Property("Ice.Warn.Datagrams", false, 0), + IceInternal::Property("Ice.Warn.Dispatch", false, 0), + IceInternal::Property("Ice.Warn.Endpoints", false, 0), + IceInternal::Property("Ice.Warn.UnknownProperties", false, 0), + IceInternal::Property("Ice.Warn.UnusedProperties", false, 0), + IceInternal::Property("Ice.CacheMessageBuffers", false, 0), + IceInternal::Property("Ice.ThreadInterruptSafe", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceProps(IcePropsData, + sizeof(IcePropsData)/sizeof(IcePropsData[0])); + +const IceInternal::Property IceMXPropsData[] = +{ + IceInternal::Property("IceMX.Metrics.*.GroupBy", false, 0), + IceInternal::Property("IceMX.Metrics.*.Map", false, 0), + IceInternal::Property("IceMX.Metrics.*.RetainDetached", false, 0), + IceInternal::Property("IceMX.Metrics.*.Accept", false, 0), + IceInternal::Property("IceMX.Metrics.*.Reject", false, 0), + IceInternal::Property("IceMX.Metrics.*", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceMXProps(IceMXPropsData, + sizeof(IceMXPropsData)/sizeof(IceMXPropsData[0])); + +const IceInternal::Property IceDiscoveryPropsData[] = +{ + IceInternal::Property("IceDiscovery.Multicast.ACM.Timeout", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ACM.Heartbeat", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ACM.Close", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ACM", false, 0), + IceInternal::Property("IceDiscovery.Multicast.AdapterId", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Endpoints", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.Locator", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.Router", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Locator", false, 0), + IceInternal::Property("IceDiscovery.Multicast.PublishedEndpoints", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ReplicaGroupId", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.Locator", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.Router", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Multicast.Router", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ProxyOptions", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.Size", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceDiscovery.Multicast.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceDiscovery.Multicast.MessageSizeMax", false, 0), + IceInternal::Property("IceDiscovery.Reply.ACM.Timeout", false, 0), + IceInternal::Property("IceDiscovery.Reply.ACM.Heartbeat", false, 0), + IceInternal::Property("IceDiscovery.Reply.ACM.Close", false, 0), + IceInternal::Property("IceDiscovery.Reply.ACM", false, 0), + IceInternal::Property("IceDiscovery.Reply.AdapterId", false, 0), + IceInternal::Property("IceDiscovery.Reply.Endpoints", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.Locator", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.Router", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Reply.Locator", false, 0), + IceInternal::Property("IceDiscovery.Reply.PublishedEndpoints", false, 0), + IceInternal::Property("IceDiscovery.Reply.ReplicaGroupId", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.Locator", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.Router", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Reply.Router", false, 0), + IceInternal::Property("IceDiscovery.Reply.ProxyOptions", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.Size", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceDiscovery.Reply.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceDiscovery.Reply.MessageSizeMax", false, 0), + IceInternal::Property("IceDiscovery.Locator.ACM.Timeout", false, 0), + IceInternal::Property("IceDiscovery.Locator.ACM.Heartbeat", false, 0), + IceInternal::Property("IceDiscovery.Locator.ACM.Close", false, 0), + IceInternal::Property("IceDiscovery.Locator.ACM", false, 0), + IceInternal::Property("IceDiscovery.Locator.AdapterId", false, 0), + IceInternal::Property("IceDiscovery.Locator.Endpoints", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.Locator", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.Router", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Locator.Locator", false, 0), + IceInternal::Property("IceDiscovery.Locator.PublishedEndpoints", false, 0), + IceInternal::Property("IceDiscovery.Locator.ReplicaGroupId", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.EndpointSelection", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.ConnectionCached", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.PreferSecure", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.Locator", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.Router", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router.Context.*", false, 0), + IceInternal::Property("IceDiscovery.Locator.Router", false, 0), + IceInternal::Property("IceDiscovery.Locator.ProxyOptions", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.Size", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceDiscovery.Locator.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceDiscovery.Locator.MessageSizeMax", false, 0), + IceInternal::Property("IceDiscovery.Lookup", false, 0), + IceInternal::Property("IceDiscovery.Timeout", false, 0), + IceInternal::Property("IceDiscovery.RetryCount", false, 0), + IceInternal::Property("IceDiscovery.LatencyMultiplier", false, 0), + IceInternal::Property("IceDiscovery.Address", false, 0), + IceInternal::Property("IceDiscovery.Port", false, 0), + IceInternal::Property("IceDiscovery.Interface", false, 0), + IceInternal::Property("IceDiscovery.DomainId", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceDiscoveryProps(IceDiscoveryPropsData, + sizeof(IceDiscoveryPropsData)/sizeof(IceDiscoveryPropsData[0])); + +const IceInternal::Property IceLocatorDiscoveryPropsData[] = +{ + IceInternal::Property("IceLocatorDiscovery.Reply.ACM.Timeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ACM.Heartbeat", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ACM.Close", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ACM", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.AdapterId", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Endpoints", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.PreferSecure", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator.Context.*", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.PublishedEndpoints", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ReplicaGroupId", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.EndpointSelection", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.ConnectionCached", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.PreferSecure", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router.Context.*", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ProxyOptions", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.Size", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceLocatorDiscovery.Reply.MessageSizeMax", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ACM.Timeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ACM.Heartbeat", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ACM.Close", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ACM", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.AdapterId", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Endpoints", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.PreferSecure", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator.Context.*", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.PublishedEndpoints", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ReplicaGroupId", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.EndpointSelection", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.ConnectionCached", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.PreferSecure", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.Locator", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router.Context.*", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.Router", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ProxyOptions", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.Size", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceLocatorDiscovery.Locator.MessageSizeMax", false, 0), + IceInternal::Property("IceLocatorDiscovery.Lookup", false, 0), + IceInternal::Property("IceLocatorDiscovery.Timeout", false, 0), + IceInternal::Property("IceLocatorDiscovery.RetryCount", false, 0), + IceInternal::Property("IceLocatorDiscovery.RetryDelay", false, 0), + IceInternal::Property("IceLocatorDiscovery.Address", false, 0), + IceInternal::Property("IceLocatorDiscovery.Port", false, 0), + IceInternal::Property("IceLocatorDiscovery.Interface", false, 0), + IceInternal::Property("IceLocatorDiscovery.InstanceName", false, 0), + IceInternal::Property("IceLocatorDiscovery.Trace.Lookup", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceLocatorDiscoveryProps(IceLocatorDiscoveryPropsData, + sizeof(IceLocatorDiscoveryPropsData)/sizeof(IceLocatorDiscoveryPropsData[0])); + +const IceInternal::Property IceBoxPropsData[] = +{ + IceInternal::Property("IceBox.InheritProperties", false, 0), + IceInternal::Property("IceBox.InstanceName", true, 0), + IceInternal::Property("IceBox.LoadOrder", false, 0), + IceInternal::Property("IceBox.PrintServicesReady", false, 0), + IceInternal::Property("IceBox.Service.*", false, 0), + IceInternal::Property("IceBox.ServiceManager.AdapterId", true, 0), + IceInternal::Property("IceBox.ServiceManager.Endpoints", true, 0), + IceInternal::Property("IceBox.ServiceManager.Locator", true, 0), + IceInternal::Property("IceBox.ServiceManager.PublishedEndpoints", true, 0), + IceInternal::Property("IceBox.ServiceManager.ReplicaGroupId", true, 0), + IceInternal::Property("IceBox.ServiceManager.Router", true, 0), + IceInternal::Property("IceBox.ServiceManager.ThreadPool.Size", true, 0), + IceInternal::Property("IceBox.ServiceManager.ThreadPool.SizeMax", true, 0), + IceInternal::Property("IceBox.ServiceManager.ThreadPool.SizeWarn", true, 0), + IceInternal::Property("IceBox.ServiceManager.ThreadPool.StackSize", true, 0), + IceInternal::Property("IceBox.Trace.ServiceObserver", false, 0), + IceInternal::Property("IceBox.UseSharedCommunicator.*", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceBoxProps(IceBoxPropsData, + sizeof(IceBoxPropsData)/sizeof(IceBoxPropsData[0])); + +const IceInternal::Property IceBoxAdminPropsData[] = +{ + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.EndpointSelection", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.ConnectionCached", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.PreferSecure", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.InvocationTimeout", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.Locator", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.Router", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.CollocationOptimized", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy.Context.*", false, 0), + IceInternal::Property("IceBoxAdmin.ServiceManager.Proxy", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceBoxAdminProps(IceBoxAdminPropsData, + sizeof(IceBoxAdminPropsData)/sizeof(IceBoxAdminPropsData[0])); + +const IceInternal::Property IceBridgePropsData[] = +{ + IceInternal::Property("IceBridge.Source.ACM.Timeout", false, 0), + IceInternal::Property("IceBridge.Source.ACM.Heartbeat", false, 0), + IceInternal::Property("IceBridge.Source.ACM.Close", false, 0), + IceInternal::Property("IceBridge.Source.ACM", false, 0), + IceInternal::Property("IceBridge.Source.AdapterId", false, 0), + IceInternal::Property("IceBridge.Source.Endpoints", false, 0), + IceInternal::Property("IceBridge.Source.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceBridge.Source.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceBridge.Source.Locator.PreferSecure", false, 0), + IceInternal::Property("IceBridge.Source.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceBridge.Source.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceBridge.Source.Locator.Locator", false, 0), + IceInternal::Property("IceBridge.Source.Locator.Router", false, 0), + IceInternal::Property("IceBridge.Source.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceBridge.Source.Locator.Context.*", false, 0), + IceInternal::Property("IceBridge.Source.Locator", false, 0), + IceInternal::Property("IceBridge.Source.PublishedEndpoints", false, 0), + IceInternal::Property("IceBridge.Source.ReplicaGroupId", false, 0), + IceInternal::Property("IceBridge.Source.Router.EndpointSelection", false, 0), + IceInternal::Property("IceBridge.Source.Router.ConnectionCached", false, 0), + IceInternal::Property("IceBridge.Source.Router.PreferSecure", false, 0), + IceInternal::Property("IceBridge.Source.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceBridge.Source.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceBridge.Source.Router.Locator", false, 0), + IceInternal::Property("IceBridge.Source.Router.Router", false, 0), + IceInternal::Property("IceBridge.Source.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceBridge.Source.Router.Context.*", false, 0), + IceInternal::Property("IceBridge.Source.Router", false, 0), + IceInternal::Property("IceBridge.Source.ProxyOptions", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.Size", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceBridge.Source.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceBridge.Source.MessageSizeMax", false, 0), + IceInternal::Property("IceBridge.Target.Endpoints", false, 0), + IceInternal::Property("IceBridge.InstanceName", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceBridgeProps(IceBridgePropsData, + sizeof(IceBridgePropsData)/sizeof(IceBridgePropsData[0])); + +const IceInternal::Property IceGridAdminPropsData[] = +{ + IceInternal::Property("IceGridAdmin.AuthenticateUsingSSL", false, 0), + IceInternal::Property("IceGridAdmin.MetricsConfig", false, 0), + IceInternal::Property("IceGridAdmin.Username", false, 0), + IceInternal::Property("IceGridAdmin.Password", false, 0), + IceInternal::Property("IceGridAdmin.Replica", false, 0), + IceInternal::Property("IceGridAdmin.Host", false, 0), + IceInternal::Property("IceGridAdmin.Port", false, 0), + IceInternal::Property("IceGridAdmin.InstanceName", false, 0), + IceInternal::Property("IceGridAdmin.Server.ACM.Timeout", false, 0), + IceInternal::Property("IceGridAdmin.Server.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGridAdmin.Server.ACM.Close", false, 0), + IceInternal::Property("IceGridAdmin.Server.ACM", false, 0), + IceInternal::Property("IceGridAdmin.Server.AdapterId", false, 0), + IceInternal::Property("IceGridAdmin.Server.Endpoints", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Server.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Server.PublishedEndpoints", false, 0), + IceInternal::Property("IceGridAdmin.Server.ReplicaGroupId", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.Router", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Server.Router", false, 0), + IceInternal::Property("IceGridAdmin.Server.ProxyOptions", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.Size", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGridAdmin.Server.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGridAdmin.Server.MessageSizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Address", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Interface", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Lookup", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ACM.Timeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ACM.Close", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ACM", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.AdapterId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Endpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.PublishedEndpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ReplicaGroupId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ProxyOptions", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.Size", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Reply.MessageSizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Timeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Close", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.AdapterId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Endpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.PublishedEndpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ReplicaGroupId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ProxyOptions", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Size", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.MessageSizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Trace.Observers", false, 0), + IceInternal::Property("IceGridAdmin.Trace.SaveToRegistry", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceGridAdminProps(IceGridAdminPropsData, + sizeof(IceGridAdminPropsData)/sizeof(IceGridAdminPropsData[0])); + +const IceInternal::Property IceGridPropsData[] = +{ + IceInternal::Property("IceGrid.AdminRouter.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ACM.Close", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ACM", false, 0), + IceInternal::Property("IceGrid.AdminRouter.AdapterId", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Endpoints", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.Router", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Locator", false, 0), + IceInternal::Property("IceGrid.AdminRouter.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.Locator", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.Router", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.AdminRouter.Router", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.AdminRouter.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.AdminRouter.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.InstanceName", false, 0), + IceInternal::Property("IceGrid.Node.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Node.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Node.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Node.ACM", false, 0), + IceInternal::Property("IceGrid.Node.AdapterId", false, 0), + IceInternal::Property("IceGrid.Node.Endpoints", false, 0), + IceInternal::Property("IceGrid.Node.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Node.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Node.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Node.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Node.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Node.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Node.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Node.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Node.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Node.Locator", false, 0), + IceInternal::Property("IceGrid.Node.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Node.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Node.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Node.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Node.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Node.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Node.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Node.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Node.Router.Router", false, 0), + IceInternal::Property("IceGrid.Node.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Node.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Node.Router", false, 0), + IceInternal::Property("IceGrid.Node.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Node.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Node.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Node.AllowRunningServersAsRoot", false, 0), + IceInternal::Property("IceGrid.Node.AllowEndpointsOverride", false, 0), + IceInternal::Property("IceGrid.Node.CollocateRegistry", false, 0), + IceInternal::Property("IceGrid.Node.Data", false, 0), + IceInternal::Property("IceGrid.Node.DisableOnFailure", false, 0), + IceInternal::Property("IceGrid.Node.Name", false, 0), + IceInternal::Property("IceGrid.Node.Output", false, 0), + IceInternal::Property("IceGrid.Node.ProcessorSocketCount", false, 0), + IceInternal::Property("IceGrid.Node.PrintServersReady", false, 0), + IceInternal::Property("IceGrid.Node.PropertiesOverride", false, 0), + IceInternal::Property("IceGrid.Node.RedirectErrToOut", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Activator", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Adapter", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Admin", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Patch", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Replica", false, 0), + IceInternal::Property("IceGrid.Node.Trace.Server", false, 0), + IceInternal::Property("IceGrid.Node.UserAccounts", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.Locator", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.Router", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper.Context.*", false, 0), + IceInternal::Property("IceGrid.Node.UserAccountMapper", false, 0), + IceInternal::Property("IceGrid.Node.WaitTime", false, 0), + IceInternal::Property("IceGrid.Registry.AdminCryptPasswords", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.Router", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.AdminPermissionsVerifier", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionFilters", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.Router", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSessionManager.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.Router", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.AdminSSLPermissionsVerifier", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.Client.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Client.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Client.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.Client.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.Client.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.CryptPasswords", false, 0), + IceInternal::Property("IceGrid.Registry.DefaultTemplates", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Enabled", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Address", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Port", false, 0), + IceInternal::Property("IceGrid.Registry.Discovery.Interface", false, 0), + IceInternal::Property("IceGrid.Registry.DynamicRegistration", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.Internal.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.LMDB.MapSize", false, 0), + IceInternal::Property("IceGrid.Registry.LMDB.Path", false, 0), + IceInternal::Property("IceGrid.Registry.NodeSessionTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.Router", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.PermissionsVerifier", false, 0), + IceInternal::Property("IceGrid.Registry.ReplicaName", false, 0), + IceInternal::Property("IceGrid.Registry.ReplicaSessionTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.RequireNodeCertCN", false, 0), + IceInternal::Property("IceGrid.Registry.RequireReplicaCertCN", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.Server.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Server.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.Server.Router", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.Server.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.Server.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.SessionFilters", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ACM.Timeout", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ACM.Close", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ACM", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.AdapterId", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Endpoints", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.Router", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.PublishedEndpoints", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ReplicaGroupId", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.Router", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.Router", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ProxyOptions", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.Size", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGrid.Registry.SessionManager.MessageSizeMax", false, 0), + IceInternal::Property("IceGrid.Registry.SessionTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.Router", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier.Context.*", false, 0), + IceInternal::Property("IceGrid.Registry.SSLPermissionsVerifier", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Admin", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Application", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Adapter", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Discovery", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Locator", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Node", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Object", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Patch", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Replica", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Server", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Session", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Subscriber", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.Topic", false, 0), + IceInternal::Property("IceGrid.Registry.Trace.TopicManager", false, 0), + IceInternal::Property("IceGrid.Registry.UserAccounts", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceGridProps(IceGridPropsData, + sizeof(IceGridPropsData)/sizeof(IceGridPropsData[0])); + +const IceInternal::Property IcePatch2PropsData[] = +{ + IceInternal::Property("IcePatch2.ACM.Timeout", false, 0), + IceInternal::Property("IcePatch2.ACM.Heartbeat", false, 0), + IceInternal::Property("IcePatch2.ACM.Close", false, 0), + IceInternal::Property("IcePatch2.ACM", false, 0), + IceInternal::Property("IcePatch2.AdapterId", false, 0), + IceInternal::Property("IcePatch2.Endpoints", false, 0), + IceInternal::Property("IcePatch2.Locator.EndpointSelection", false, 0), + IceInternal::Property("IcePatch2.Locator.ConnectionCached", false, 0), + IceInternal::Property("IcePatch2.Locator.PreferSecure", false, 0), + IceInternal::Property("IcePatch2.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IcePatch2.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IcePatch2.Locator.Locator", false, 0), + IceInternal::Property("IcePatch2.Locator.Router", false, 0), + IceInternal::Property("IcePatch2.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IcePatch2.Locator.Context.*", false, 0), + IceInternal::Property("IcePatch2.Locator", false, 0), + IceInternal::Property("IcePatch2.PublishedEndpoints", false, 0), + IceInternal::Property("IcePatch2.ReplicaGroupId", false, 0), + IceInternal::Property("IcePatch2.Router.EndpointSelection", false, 0), + IceInternal::Property("IcePatch2.Router.ConnectionCached", false, 0), + IceInternal::Property("IcePatch2.Router.PreferSecure", false, 0), + IceInternal::Property("IcePatch2.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IcePatch2.Router.InvocationTimeout", false, 0), + IceInternal::Property("IcePatch2.Router.Locator", false, 0), + IceInternal::Property("IcePatch2.Router.Router", false, 0), + IceInternal::Property("IcePatch2.Router.CollocationOptimized", false, 0), + IceInternal::Property("IcePatch2.Router.Context.*", false, 0), + IceInternal::Property("IcePatch2.Router", false, 0), + IceInternal::Property("IcePatch2.ProxyOptions", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.Size", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.StackSize", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.Serialize", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IcePatch2.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IcePatch2.MessageSizeMax", false, 0), + IceInternal::Property("IcePatch2.Directory", false, 0), + IceInternal::Property("IcePatch2.InstanceName", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IcePatch2Props(IcePatch2PropsData, + sizeof(IcePatch2PropsData)/sizeof(IcePatch2PropsData[0])); + +const IceInternal::Property IcePatch2ClientPropsData[] = +{ + IceInternal::Property("IcePatch2Client.ChunkSize", false, 0), + IceInternal::Property("IcePatch2Client.Directory", false, 0), + IceInternal::Property("IcePatch2Client.Proxy", false, 0), + IceInternal::Property("IcePatch2Client.Remove", false, 0), + IceInternal::Property("IcePatch2Client.Thorough", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IcePatch2ClientProps(IcePatch2ClientPropsData, + sizeof(IcePatch2ClientPropsData)/sizeof(IcePatch2ClientPropsData[0])); + +const IceInternal::Property IceSSLPropsData[] = +{ + IceInternal::Property("IceSSL.Alias", false, 0), + IceInternal::Property("IceSSL.CAs", false, 0), + IceInternal::Property("IceSSL.CertAuthDir", true, "IceSSL.CAs"), + IceInternal::Property("IceSSL.CertAuthFile", true, "IceSSL.CAs"), + IceInternal::Property("IceSSL.CertStore", false, 0), + IceInternal::Property("IceSSL.CertStoreLocation", false, 0), + IceInternal::Property("IceSSL.CertFile", false, 0), + IceInternal::Property("IceSSL.CertVerifier", false, 0), + IceInternal::Property("IceSSL.CheckCertName", false, 0), + IceInternal::Property("IceSSL.CheckCRL", false, 0), + IceInternal::Property("IceSSL.Ciphers", false, 0), + IceInternal::Property("IceSSL.CertificateRevocationListFiles", false, 0), + IceInternal::Property("IceSSL.DefaultDir", false, 0), + IceInternal::Property("IceSSL.DH.*", false, 0), + IceInternal::Property("IceSSL.DHParams", false, 0), + IceInternal::Property("IceSSL.EntropyDaemon", false, 0), + IceInternal::Property("IceSSL.FindCert", false, 0), + IceInternal::Property("IceSSL.FindCert.*", true, 0), + IceInternal::Property("IceSSL.InitOpenSSL", false, 0), + IceInternal::Property("IceSSL.KeyFile", false, 0), + IceInternal::Property("IceSSL.Keychain", false, 0), + IceInternal::Property("IceSSL.KeychainPassword", false, 0), + IceInternal::Property("IceSSL.Keystore", false, 0), + IceInternal::Property("IceSSL.KeystorePassword", false, 0), + IceInternal::Property("IceSSL.KeystoreType", false, 0), + IceInternal::Property("IceSSL.Password", false, 0), + IceInternal::Property("IceSSL.PasswordCallback", false, 0), + IceInternal::Property("IceSSL.PasswordRetryMax", false, 0), + IceInternal::Property("IceSSL.Protocols", false, 0), + IceInternal::Property("IceSSL.ProtocolVersionMax", false, 0), + IceInternal::Property("IceSSL.ProtocolVersionMin", false, 0), + IceInternal::Property("IceSSL.Random", false, 0), + IceInternal::Property("IceSSL.RevocationCheck", false, 0), + IceInternal::Property("IceSSL.RevocationCheckCacheOnly", false, 0), + IceInternal::Property("IceSSL.SchannelStrongCrypto", false, 0), + IceInternal::Property("IceSSL.Trace.Security", false, 0), + IceInternal::Property("IceSSL.TrustOnly", false, 0), + IceInternal::Property("IceSSL.TrustOnly.Client", false, 0), + IceInternal::Property("IceSSL.TrustOnly.Server", false, 0), + IceInternal::Property("IceSSL.TrustOnly.Server.*", false, 0), + IceInternal::Property("IceSSL.Truststore", false, 0), + IceInternal::Property("IceSSL.TruststorePassword", false, 0), + IceInternal::Property("IceSSL.TruststoreType", false, 0), + IceInternal::Property("IceSSL.UsePlatformCAs", false, 0), + IceInternal::Property("IceSSL.VerifyDepthMax", false, 0), + IceInternal::Property("IceSSL.VerifyPeer", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceSSLProps(IceSSLPropsData, + sizeof(IceSSLPropsData)/sizeof(IceSSLPropsData[0])); + +const IceInternal::Property IceStormAdminPropsData[] = +{ + IceInternal::Property("IceStormAdmin.TopicManager.*", false, 0), + IceInternal::Property("IceStormAdmin.Host", false, 0), + IceInternal::Property("IceStormAdmin.Port", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceStormAdminProps(IceStormAdminPropsData, + sizeof(IceStormAdminPropsData)/sizeof(IceStormAdminPropsData[0])); + +const IceInternal::Property IceBTPropsData[] = +{ + IceInternal::Property("IceBT.RcvSize", false, 0), + IceInternal::Property("IceBT.SndSize", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::IceBTProps(IceBTPropsData, + sizeof(IceBTPropsData)/sizeof(IceBTPropsData[0])); + +const IceInternal::Property Glacier2PropsData[] = +{ + IceInternal::Property("Glacier2.AddConnectionContext", false, 0), + IceInternal::Property("Glacier2.Client.ACM.Timeout", false, 0), + IceInternal::Property("Glacier2.Client.ACM.Heartbeat", false, 0), + IceInternal::Property("Glacier2.Client.ACM.Close", false, 0), + IceInternal::Property("Glacier2.Client.ACM", false, 0), + IceInternal::Property("Glacier2.Client.AdapterId", false, 0), + IceInternal::Property("Glacier2.Client.Endpoints", false, 0), + IceInternal::Property("Glacier2.Client.Locator.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.Client.Locator.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.Client.Locator.PreferSecure", false, 0), + IceInternal::Property("Glacier2.Client.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.Client.Locator.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.Client.Locator.Locator", false, 0), + IceInternal::Property("Glacier2.Client.Locator.Router", false, 0), + IceInternal::Property("Glacier2.Client.Locator.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.Client.Locator.Context.*", false, 0), + IceInternal::Property("Glacier2.Client.Locator", false, 0), + IceInternal::Property("Glacier2.Client.PublishedEndpoints", false, 0), + IceInternal::Property("Glacier2.Client.ReplicaGroupId", false, 0), + IceInternal::Property("Glacier2.Client.Router.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.Client.Router.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.Client.Router.PreferSecure", false, 0), + IceInternal::Property("Glacier2.Client.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.Client.Router.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.Client.Router.Locator", false, 0), + IceInternal::Property("Glacier2.Client.Router.Router", false, 0), + IceInternal::Property("Glacier2.Client.Router.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.Client.Router.Context.*", false, 0), + IceInternal::Property("Glacier2.Client.Router", false, 0), + IceInternal::Property("Glacier2.Client.ProxyOptions", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.Size", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.SizeMax", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.StackSize", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.Serialize", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("Glacier2.Client.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("Glacier2.Client.MessageSizeMax", false, 0), + IceInternal::Property("Glacier2.Client.AlwaysBatch", false, 0), + IceInternal::Property("Glacier2.Client.Buffered", false, 0), + IceInternal::Property("Glacier2.Client.ForwardContext", false, 0), + IceInternal::Property("Glacier2.Client.SleepTime", false, 0), + IceInternal::Property("Glacier2.Client.Trace.Override", false, 0), + IceInternal::Property("Glacier2.Client.Trace.Reject", false, 0), + IceInternal::Property("Glacier2.Client.Trace.Request", false, 0), + IceInternal::Property("Glacier2.CryptPasswords", false, 0), + IceInternal::Property("Glacier2.Filter.Address.Reject", false, 0), + IceInternal::Property("Glacier2.Filter.Address.Accept", false, 0), + IceInternal::Property("Glacier2.Filter.ProxySizeMax", false, 0), + IceInternal::Property("Glacier2.Filter.Category.Accept", false, 0), + IceInternal::Property("Glacier2.Filter.Category.AcceptUser", false, 0), + IceInternal::Property("Glacier2.Filter.AdapterId.Accept", false, 0), + IceInternal::Property("Glacier2.Filter.Identity.Accept", false, 0), + IceInternal::Property("Glacier2.InstanceName", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.Locator", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.Router", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier.Context.*", false, 0), + IceInternal::Property("Glacier2.PermissionsVerifier", false, 0), + IceInternal::Property("Glacier2.ReturnClientProxy", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.PreferSecure", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.Locator", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.Router", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier.Context.*", false, 0), + IceInternal::Property("Glacier2.SSLPermissionsVerifier", false, 0), + IceInternal::Property("Glacier2.RoutingTable.MaxSize", false, 0), + IceInternal::Property("Glacier2.Server.ACM.Timeout", false, 0), + IceInternal::Property("Glacier2.Server.ACM.Heartbeat", false, 0), + IceInternal::Property("Glacier2.Server.ACM.Close", false, 0), + IceInternal::Property("Glacier2.Server.ACM", false, 0), + IceInternal::Property("Glacier2.Server.AdapterId", false, 0), + IceInternal::Property("Glacier2.Server.Endpoints", false, 0), + IceInternal::Property("Glacier2.Server.Locator.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.Server.Locator.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.Server.Locator.PreferSecure", false, 0), + IceInternal::Property("Glacier2.Server.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.Server.Locator.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.Server.Locator.Locator", false, 0), + IceInternal::Property("Glacier2.Server.Locator.Router", false, 0), + IceInternal::Property("Glacier2.Server.Locator.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.Server.Locator.Context.*", false, 0), + IceInternal::Property("Glacier2.Server.Locator", false, 0), + IceInternal::Property("Glacier2.Server.PublishedEndpoints", false, 0), + IceInternal::Property("Glacier2.Server.ReplicaGroupId", false, 0), + IceInternal::Property("Glacier2.Server.Router.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.Server.Router.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.Server.Router.PreferSecure", false, 0), + IceInternal::Property("Glacier2.Server.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.Server.Router.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.Server.Router.Locator", false, 0), + IceInternal::Property("Glacier2.Server.Router.Router", false, 0), + IceInternal::Property("Glacier2.Server.Router.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.Server.Router.Context.*", false, 0), + IceInternal::Property("Glacier2.Server.Router", false, 0), + IceInternal::Property("Glacier2.Server.ProxyOptions", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.Size", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.SizeMax", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.StackSize", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.Serialize", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("Glacier2.Server.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("Glacier2.Server.MessageSizeMax", false, 0), + IceInternal::Property("Glacier2.Server.AlwaysBatch", false, 0), + IceInternal::Property("Glacier2.Server.Buffered", false, 0), + IceInternal::Property("Glacier2.Server.ForwardContext", false, 0), + IceInternal::Property("Glacier2.Server.SleepTime", false, 0), + IceInternal::Property("Glacier2.Server.Trace.Override", false, 0), + IceInternal::Property("Glacier2.Server.Trace.Request", false, 0), + IceInternal::Property("Glacier2.SessionManager.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.SessionManager.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.SessionManager.PreferSecure", false, 0), + IceInternal::Property("Glacier2.SessionManager.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.SessionManager.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.SessionManager.Locator", false, 0), + IceInternal::Property("Glacier2.SessionManager.Router", false, 0), + IceInternal::Property("Glacier2.SessionManager.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.SessionManager.Context.*", false, 0), + IceInternal::Property("Glacier2.SessionManager", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.EndpointSelection", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.ConnectionCached", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.PreferSecure", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.LocatorCacheTimeout", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.InvocationTimeout", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.Locator", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.Router", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.CollocationOptimized", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager.Context.*", false, 0), + IceInternal::Property("Glacier2.SSLSessionManager", false, 0), + IceInternal::Property("Glacier2.SessionTimeout", false, 0), + IceInternal::Property("Glacier2.Trace.RoutingTable", false, 0), + IceInternal::Property("Glacier2.Trace.Session", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::Glacier2Props(Glacier2PropsData, + sizeof(Glacier2PropsData)/sizeof(Glacier2PropsData[0])); + +const IceInternal::Property Glacier2CryptPermissionsVerifierPropsData[] = +{ + IceInternal::Property("Glacier2CryptPermissionsVerifier.*.PermissionsVerifier", false, 0), + IceInternal::Property("Glacier2CryptPermissionsVerifier.*.AdminPermissionsVerifier", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::Glacier2CryptPermissionsVerifierProps(Glacier2CryptPermissionsVerifierPropsData, + sizeof(Glacier2CryptPermissionsVerifierPropsData)/sizeof(Glacier2CryptPermissionsVerifierPropsData[0])); + +const IceInternal::Property FreezePropsData[] = +{ + IceInternal::Property("Freeze.DbEnv.*.CheckpointPeriod", false, 0), + IceInternal::Property("Freeze.DbEnv.*.DbHome", false, 0), + IceInternal::Property("Freeze.DbEnv.*.DbPrivate", false, 0), + IceInternal::Property("Freeze.DbEnv.*.DbRecoverFatal", false, 0), + IceInternal::Property("Freeze.DbEnv.*.EncodingVersion", false, 0), + IceInternal::Property("Freeze.DbEnv.*.LockFile", false, 0), + IceInternal::Property("Freeze.DbEnv.*.OldLogsAutoDelete", false, 0), + IceInternal::Property("Freeze.DbEnv.*.PeriodicCheckpointMinSize", false, 0), + IceInternal::Property("Freeze.Evictor.*.BtreeMinKey", false, 0), + IceInternal::Property("Freeze.Evictor.*.Checksum", false, 0), + IceInternal::Property("Freeze.Evictor.*.MaxTxSize", false, 0), + IceInternal::Property("Freeze.Evictor.*.PageSize", false, 0), + IceInternal::Property("Freeze.Evictor.*.PopulateEmptyIndices", false, 0), + IceInternal::Property("Freeze.Evictor.*.RollbackOnUserException", false, 0), + IceInternal::Property("Freeze.Evictor.*.SavePeriod", false, 0), + IceInternal::Property("Freeze.Evictor.*.SaveSizeTrigger", false, 0), + IceInternal::Property("Freeze.Evictor.*.StreamTimeout", false, 0), + IceInternal::Property("Freeze.Map.*.BtreeMinKey", false, 0), + IceInternal::Property("Freeze.Map.*.Checksum", false, 0), + IceInternal::Property("Freeze.Map.*.PageSize", false, 0), + IceInternal::Property("Freeze.Trace.DbEnv", false, 0), + IceInternal::Property("Freeze.Trace.Evictor", false, 0), + IceInternal::Property("Freeze.Trace.Map", false, 0), + IceInternal::Property("Freeze.Trace.Transaction", false, 0), + IceInternal::Property("Freeze.Warn.Deadlocks", false, 0), + IceInternal::Property("Freeze.Warn.Rollback", false, 0), +}; + +const IceInternal::PropertyArray + IceInternal::PropertyNames::FreezeProps(FreezePropsData, + sizeof(FreezePropsData)/sizeof(FreezePropsData[0])); + +const IceInternal::PropertyArray IceInternal::PropertyNames::validProps[] = +{ + IceProps, + IceMXProps, + IceDiscoveryProps, + IceLocatorDiscoveryProps, + IceBoxProps, + IceBoxAdminProps, + IceBridgeProps, + IceGridAdminProps, + IceGridProps, + IcePatch2Props, + IcePatch2ClientProps, + IceSSLProps, + IceStormAdminProps, + IceBTProps, + Glacier2Props, + Glacier2CryptPermissionsVerifierProps, + FreezeProps, + IceInternal::PropertyArray(0,0) +}; + +const char* IceInternal::PropertyNames::clPropNames[] = +{ + "Ice", + "IceMX", + "IceDiscovery", + "IceLocatorDiscovery", + "IceBox", + "IceBoxAdmin", + "IceBridge", + "IceGridAdmin", + "IceGrid", + "IcePatch2", + "IcePatch2Client", + "IceSSL", + "IceStormAdmin", + "IceBT", + "Glacier2", + "Glacier2CryptPermissionsVerifier", + "Freeze", + 0 +}; diff --git a/Sources/IceCpp/Protocol.cpp b/Sources/IceCpp/Protocol.cpp new file mode 100644 index 0000000..34005af --- /dev/null +++ b/Sources/IceCpp/Protocol.cpp @@ -0,0 +1,124 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +namespace IceInternal +{ + +const Ice::Byte magic[] = { 0x49, 0x63, 0x65, 0x50 }; // 'I', 'c', 'e', 'P' + +const Ice::Byte requestHdr[] = +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + protocolEncodingMajor, + protocolEncodingMinor, + requestMsg, + 0, // Compression status + 0, 0, 0, 0, // Message size (placeholder) + 0, 0, 0, 0 // Request id (placeholder) +}; + +const Ice::Byte requestBatchHdr[] = +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + protocolEncodingMajor, + protocolEncodingMinor, + requestBatchMsg, + 0, // Compression status + 0, 0, 0, 0, // Message size (place holder) + 0, 0, 0, 0 // Number of requests in batch (placeholder) +}; + +const Ice::Byte replyHdr[] = +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + protocolEncodingMajor, + protocolEncodingMinor, + replyMsg, + 0, // Compression status + 0, 0, 0, 0 // Message size (placeholder) +}; + +void +stringToMajorMinor(const std::string& str, Ice::Byte& major, Ice::Byte& minor) +{ + std::string::size_type pos = str.find_first_of("."); + if(pos == std::string::npos) + { + throw Ice::VersionParseException(__FILE__, __LINE__, "malformed version value `" + str + "'"); + } + + std::istringstream majStr(str.substr(0, pos)); + Ice::Int majVersion; + if(!(majStr >> majVersion) || !majStr.eof()) + { + throw Ice::VersionParseException(__FILE__, __LINE__, "invalid major version value `" + str + "'"); + } + + std::istringstream minStr(str.substr(pos + 1, std::string::npos)); + Ice::Int minVersion; + if(!(minStr >> minVersion) || !minStr.eof()) + { + throw Ice::VersionParseException(__FILE__, __LINE__, "invalid minor version value `" + str + "'"); + } + + if(majVersion < 1 || majVersion > 255 || minVersion < 0 || minVersion > 255) + { + throw Ice::VersionParseException(__FILE__, __LINE__, "range error in version `" + str + "'"); + } + + major = static_cast(majVersion); + minor = static_cast(minVersion); +} + +void +throwUnsupportedProtocolException(const char* f, int l, const Ice::ProtocolVersion& v, const Ice::ProtocolVersion& s) +{ + throw Ice::UnsupportedProtocolException(f, l, "", v, s); +} + +void +throwUnsupportedEncodingException(const char* f, int l, const Ice::EncodingVersion& v, const Ice::EncodingVersion& s) +{ + throw Ice::UnsupportedEncodingException(f, l, "", v, s); +} + +} + +namespace Ice +{ + +const EncodingVersion currentEncoding = { IceInternal::encodingMajor, IceInternal::encodingMinor }; +const ProtocolVersion currentProtocol = { IceInternal::protocolMajor, IceInternal::protocolMinor }; +// +// The encoding to use for protocol messages, this version is tied to +// the protocol version. +// + +const EncodingVersion currentProtocolEncoding = { IceInternal::protocolEncodingMajor, + IceInternal::protocolEncodingMinor }; + +const ProtocolVersion Protocol_1_0 = { 1, 0 }; + +const EncodingVersion Encoding_1_0 = { 1, 0 }; +const EncodingVersion Encoding_1_1 = { 1, 1 }; + +} diff --git a/Sources/IceCpp/ProtocolInstance.cpp b/Sources/IceCpp/ProtocolInstance.cpp new file mode 100644 index 0000000..c9dbac3 --- /dev/null +++ b/Sources/IceCpp/ProtocolInstance.cpp @@ -0,0 +1,131 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(ProtocolInstance* p) { return p; } + +IceInternal::ProtocolInstance::~ProtocolInstance() +{ + // Out of line to avoid weak vtable +} + +IceInternal::ProtocolInstance::ProtocolInstance(const CommunicatorPtr& com, Short type, const string& protocol, + bool secure) : + _instance(getInstance(com)), + _traceLevel(_instance->traceLevels()->network), + _traceCategory(_instance->traceLevels()->networkCat), + _properties(_instance->initializationData().properties), + _protocol(protocol), + _type(type), + _secure(secure) +{ +} + +IceInternal::ProtocolInstance::ProtocolInstance(const InstancePtr& instance, Short type, const string& protocol, + bool secure) : + _instance(instance), + _traceLevel(_instance->traceLevels()->network), + _traceCategory(_instance->traceLevels()->networkCat), + _properties(_instance->initializationData().properties), + _protocol(protocol), + _type(type), + _secure(secure) +{ +} + +const LoggerPtr& +IceInternal::ProtocolInstance::logger() const +{ + return _instance->initializationData().logger; +} + +EndpointFactoryPtr +IceInternal::ProtocolInstance::getEndpointFactory(Ice::Short type) const +{ + return _instance->endpointFactoryManager()->get(type); +} + +BufSizeWarnInfo +IceInternal::ProtocolInstance::getBufSizeWarn(Short type) +{ + return _instance->getBufSizeWarn(type); +} + +void +IceInternal::ProtocolInstance::setSndBufSizeWarn(Short type, int size) +{ + _instance->setSndBufSizeWarn(type, size); +} + +void +IceInternal::ProtocolInstance::setRcvBufSizeWarn(Short type, int size) +{ + _instance->setRcvBufSizeWarn(type, size); +} + +bool +IceInternal::ProtocolInstance::preferIPv6() const +{ + return _instance->preferIPv6(); +} + +ProtocolSupport +IceInternal::ProtocolInstance::protocolSupport() const +{ + return _instance->protocolSupport(); +} + +const string& +IceInternal::ProtocolInstance::defaultHost() const +{ + return _instance->defaultsAndOverrides()->defaultHost; +} + +const Address& +IceInternal::ProtocolInstance::defaultSourceAddress() const +{ + return _instance->defaultsAndOverrides()->defaultSourceAddress; +} + +const EncodingVersion& +IceInternal::ProtocolInstance::defaultEncoding() const +{ + return _instance->defaultsAndOverrides()->defaultEncoding; +} + +int +IceInternal::ProtocolInstance::defaultTimeout() const +{ + return _instance->defaultsAndOverrides()->defaultTimeout; +} + +NetworkProxyPtr +IceInternal::ProtocolInstance::networkProxy() const +{ + return _instance->networkProxy(); +} + +size_t +IceInternal::ProtocolInstance::messageSizeMax() const +{ + return _instance->messageSizeMax(); +} + +void +IceInternal::ProtocolInstance::resolve(const string& host, int port, EndpointSelectionType type, + const IPEndpointIPtr& endpt, const EndpointI_connectorsPtr& cb) const +{ + _instance->endpointHostResolver()->resolve(host, port, type, endpt, cb); +} diff --git a/Sources/IceCpp/ProtocolPluginFacade.cpp b/Sources/IceCpp/ProtocolPluginFacade.cpp new file mode 100644 index 0000000..ccfbd9c --- /dev/null +++ b/Sources/IceCpp/ProtocolPluginFacade.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(ProtocolPluginFacade* p) { return p; } + +IceInternal::ProtocolPluginFacade::~ProtocolPluginFacade() +{ + // Out of line to avoid weak vtable +} + +ProtocolPluginFacadePtr +IceInternal::getProtocolPluginFacade(const CommunicatorPtr& communicator) +{ + return new ProtocolPluginFacade(communicator); +} + +CommunicatorPtr +IceInternal::ProtocolPluginFacade::getCommunicator() const +{ + return _communicator; +} + +void +IceInternal::ProtocolPluginFacade::addEndpointFactory(const EndpointFactoryPtr& factory) const +{ + _instance->endpointFactoryManager()->add(factory); +} + +EndpointFactoryPtr +IceInternal::ProtocolPluginFacade::getEndpointFactory(Ice::Short type) const +{ + return _instance->endpointFactoryManager()->get(type); +} + +IceInternal::ProtocolPluginFacade::ProtocolPluginFacade(const CommunicatorPtr& communicator) : + _instance(getInstance(communicator)), + _communicator(communicator) +{ +} diff --git a/Sources/IceCpp/Proxy.cpp b/Sources/IceCpp/Proxy.cpp new file mode 100644 index 0000000..76b03fa --- /dev/null +++ b/Sources/IceCpp/Proxy.cpp @@ -0,0 +1,1601 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // To convert from ConnectionIPtr to ConnectionPtr in ice_getConnection(). +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace Ice +{ + +const Context noExplicitContext; + +} + +#if defined(_MSC_VER) && (_MSC_VER <= 1600) +// +// COMPILERFIX v90 and v100 get confused with namespaces and complains that +// ::Ice::noExplicitContext isn't defined in IceProxy namespace. +// +namespace IceProxy +{ + +namespace Ice +{ + +const Context noExplicitContext; + +} + +} +#endif + +namespace +{ + +const string ice_ping_name = "ice_ping"; +const string ice_ids_name = "ice_ids"; +const string ice_id_name = "ice_id"; +const string ice_isA_name = "ice_isA"; +const string ice_invoke_name = "ice_invoke"; +const string ice_getConnection_name = "ice_getConnection"; +const string ice_flushBatchRequests_name = "ice_flushBatchRequests"; + +} + +ProxyFlushBatchAsync::ProxyFlushBatchAsync(const ObjectPrxPtr& proxy) : ProxyOutgoingAsyncBase(proxy) +{ +} + +AsyncStatus +ProxyFlushBatchAsync::invokeRemote(const ConnectionIPtr& connection, bool compress, bool) +{ + if(_batchRequestNum == 0) + { + if(sent()) + { + return static_cast(AsyncStatusSent | AsyncStatusInvokeSentCallback); + } + else + { + return AsyncStatusSent; + } + } + _cachedConnection = connection; + return connection->sendAsyncRequest(ICE_SHARED_FROM_THIS, compress, false, _batchRequestNum); +} + +AsyncStatus +ProxyFlushBatchAsync::invokeCollocated(CollocatedRequestHandler* handler) +{ + if(_batchRequestNum == 0) + { + if(sent()) + { + return static_cast(AsyncStatusSent | AsyncStatusInvokeSentCallback); + } + else + { + return AsyncStatusSent; + } + } + return handler->invokeAsyncRequest(this, _batchRequestNum, false); +} + +void +ProxyFlushBatchAsync::invoke(const string& operation) +{ + checkSupportedProtocol(getCompatibleProtocol(_proxy->_getReference()->getProtocol())); + _observer.attach(_proxy, operation, ::Ice::noExplicitContext); + bool compress; // Ignore for proxy flushBatchRequests + _batchRequestNum = _proxy->_getBatchRequestQueue()->swap(&_os, compress); + invokeImpl(true); // userThread = true +} + +ProxyGetConnection::ProxyGetConnection(const ObjectPrxPtr& prx) : ProxyOutgoingAsyncBase(prx) +{ +} + +AsyncStatus +ProxyGetConnection::invokeRemote(const ConnectionIPtr& connection, bool, bool) +{ + _cachedConnection = connection; + if(responseImpl(true, true)) + { + invokeResponseAsync(); + } + return AsyncStatusSent; +} + +AsyncStatus +ProxyGetConnection::invokeCollocated(CollocatedRequestHandler*) +{ + if(responseImpl(true, true)) + { + invokeResponseAsync(); + } + return AsyncStatusSent; +} + +Ice::ConnectionPtr +ProxyGetConnection::getConnection() const +{ + return _cachedConnection; +} + +void +ProxyGetConnection::invoke(const string& operation) +{ + _observer.attach(_proxy, operation, ::Ice::noExplicitContext); + invokeImpl(true); // userThread = true +} + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +bool +operator<(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return lhs._reference < rhs._reference; +} + +bool +operator==(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return lhs._reference == rhs._reference; +} + +} + +void +Ice::ObjectPrx::_iceI_isA(const shared_ptr>& outAsync, + const string& typeId, + const Context& ctx) +{ + _checkTwowayOnly(ice_isA_name); + outAsync->invoke(ice_isA_name, OperationMode::Nonmutating, ICE_ENUM(FormatType, DefaultFormat), ctx, + [&](Ice::OutputStream* os) + { + os->write(typeId, false); + }, + nullptr); +} + +void +Ice::ObjectPrx::_iceI_ping(const shared_ptr>& outAsync, const Context& ctx) +{ + outAsync->invoke(ice_ping_name, OperationMode::Nonmutating, ICE_ENUM(FormatType, DefaultFormat), ctx, nullptr, nullptr); +} + +void +Ice::ObjectPrx::_iceI_ids(const shared_ptr>>& outAsync, const Context& ctx) +{ + _checkTwowayOnly(ice_ids_name); + outAsync->invoke(ice_ids_name, OperationMode::Nonmutating, ICE_ENUM(FormatType, DefaultFormat), ctx, nullptr, nullptr, + [](Ice::InputStream* stream) + { + vector v; + stream->read(v, false); // no conversion + return v; + }); +} + +void +Ice::ObjectPrx::_iceI_id(const shared_ptr>& outAsync, const Context& ctx) +{ + _checkTwowayOnly(ice_id_name); + outAsync->invoke(ice_id_name, OperationMode::Nonmutating, ICE_ENUM(FormatType, DefaultFormat), ctx, nullptr, nullptr, + [](Ice::InputStream* stream) + { + string v; + stream->read(v, false); // no conversion + return v; + }); +} + +void +Ice::ObjectPrx::_iceI_getConnection(const shared_ptr& outAsync) +{ + outAsync->invoke(ice_getConnection_name); +} + +void +Ice::ObjectPrx::_iceI_flushBatchRequests(const shared_ptr& outAsync) +{ + outAsync->invoke(ice_flushBatchRequests_name); +} + +void +Ice::ObjectPrx::_checkTwowayOnly(const string& name) const +{ + // + // No mutex lock necessary, there is nothing mutable in this operation. + // + if(!ice_isTwoway()) + { + throw Ice::TwowayOnlyException(__FILE__, __LINE__, name); + } +} + +shared_ptr +Ice::ObjectPrx::_newInstance() const +{ + return createProxy(); +} + +ostream& +Ice::operator<<(ostream& os, const Ice::ObjectPrx& p) +{ + return os << p.ice_toString(); +} + +#else // C++98 mapping + +::Ice::ObjectPrxPtr +IceInternal::checkedCastImpl(const ObjectPrxPtr& b, const string& f, const string& typeId, const Context& context) +{ + if(b != ICE_NULLPTR) + { + ObjectPrxPtr bb = b->ice_facet(f); + try + { + if(bb->ice_isA(typeId, context)) + { + return bb; + } +#ifndef NDEBUG + else + { + assert(typeId != "::Ice::Object"); + } +#endif + } + catch(const FacetNotExistException&) + { + } + } + return ICE_NULLPTR; +} + +bool +IceProxy::Ice::Object::operator==(const Object& r) const +{ + return _reference == r._reference; +} + +bool +IceProxy::Ice::Object::operator<(const Object& r) const +{ + return _reference < r._reference; +} + +Ice::AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_isA(const string& typeId, + const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool sync) +{ + _checkTwowayOnly(ice_isA_name, sync); + OutgoingAsyncPtr result = new CallbackOutgoing(this, ice_isA_name, del, cookie, sync); + try + { + result->prepare(ice_isA_name, Nonmutating, ctx); + ::Ice::OutputStream* ostr = result->startWriteParams(ICE_ENUM(FormatType, DefaultFormat)); + ostr->write(typeId, false); + result->endWriteParams(); + result->invoke(ice_isA_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +bool +IceProxy::Ice::Object::end_ice_isA(const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_isA_name); + bool ok = result->_waitForResponse(); + if(!ok) + { + try + { + result->_throwUserException(); + } + catch(const UserException& ex) + { + throw UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + bool ret; + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_ping(const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool sync) +{ + OutgoingAsyncPtr result = new CallbackOutgoing(this, ice_ping_name, del, cookie, sync); + try + { + result->prepare(ice_ping_name, Nonmutating, ctx); + result->writeEmptyParams(); + result->invoke(ice_ping_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::Object::end_ice_ping(const AsyncResultPtr& result) +{ + _end(result, ice_ping_name); +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_ids(const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool sync) +{ + _checkTwowayOnly(ice_ids_name, sync); + OutgoingAsyncPtr result = new CallbackOutgoing(this, ice_ids_name, del, cookie, sync); + try + { + result->prepare(ice_ids_name, Nonmutating, ctx); + result->writeEmptyParams(); + result->invoke(ice_ids_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +vector +IceProxy::Ice::Object::end_ice_ids(const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_ids_name); + bool ok = result->_waitForResponse(); + if(!ok) + { + try + { + result->_throwUserException(); + } + catch(const UserException& ex) + { + throw UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + vector ret; + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret, false); + result->_endReadParams(); + return ret; +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_id(const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool sync) +{ + _checkTwowayOnly(ice_id_name, sync); + OutgoingAsyncPtr result = new CallbackOutgoing(this, ice_id_name, del, cookie, sync); + try + { + result->prepare(ice_id_name, Nonmutating, ctx); + result->writeEmptyParams(); + result->invoke(ice_id_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +string +IceProxy::Ice::Object::end_ice_id(const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_id_name); + bool ok = result->_waitForResponse(); + if(!ok) + { + try + { + result->_throwUserException(); + } + catch(const UserException& ex) + { + throw UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + string ret; + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret, false); + result->_endReadParams(); + return ret; +} + +bool +IceProxy::Ice::Object::ice_invoke(const string& operation, + OperationMode mode, + const vector& inEncaps, + vector& outEncaps, + const Context& context) +{ + pair inPair; + if(inEncaps.empty()) + { + inPair.first = inPair.second = 0; + } + else + { + inPair.first = &inEncaps[0]; + inPair.second = inPair.first + inEncaps.size(); + } + return ice_invoke(operation, mode, inPair, outEncaps, context); +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_invoke(const string& operation, + OperationMode mode, + const vector& inEncaps, + const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool /*sync*/) +{ + pair inPair; + if(inEncaps.empty()) + { + inPair.first = inPair.second = 0; + } + else + { + inPair.first = &inEncaps[0]; + inPair.second = inPair.first + inEncaps.size(); + } + return _iceI_begin_ice_invoke(operation, mode, inPair, ctx, del, cookie); +} + +bool +IceProxy::Ice::Object::end_ice_invoke(vector& outEncaps, const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_invoke_name); + bool ok = result->_waitForResponse(); + if(_reference->getMode() == Reference::ModeTwoway) + { + const Byte* v; + Int sz; + result->_readParamEncaps(v, sz); + vector(v, v + sz).swap(outEncaps); + } + return ok; +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_invoke(const string& operation, + OperationMode mode, + const pair& inEncaps, + const Context& ctx, + const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie, + bool sync) +{ + OutgoingAsyncPtr result = new CallbackOutgoing(this, ice_invoke_name, del, cookie, sync); + try + { + result->prepare(operation, mode, ctx); + result->writeParamEncaps(inEncaps.first, static_cast(inEncaps.second - inEncaps.first)); + result->invoke(operation); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +bool +IceProxy::Ice::Object::_iceI_end_ice_invoke(pair& outEncaps, const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_invoke_name); + bool ok = result->_waitForResponse(); + if(_reference->getMode() == Reference::ModeTwoway) + { + Int sz; + result->_readParamEncaps(outEncaps.first, sz); + outEncaps.second = outEncaps.first + sz; + } + return ok; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_flushBatchRequests(const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie) +{ + class ProxyFlushBatchAsyncWithCallback : public ProxyFlushBatchAsync, public CallbackCompletion + { + public: + + ProxyFlushBatchAsyncWithCallback(const ::Ice::ObjectPrx& proxy, + const CallbackBasePtr& cb, + const ::Ice::LocalObjectPtr& cookie) : + ProxyFlushBatchAsync(proxy), CallbackCompletion(cb, cookie) + { + _cookie = cookie; + } + + virtual const std::string& + getOperation() const + { + return ice_flushBatchRequests_name; + } + }; + + ProxyFlushBatchAsyncPtr result = new ProxyFlushBatchAsyncWithCallback(this, del, cookie); + try + { + result->invoke(ice_flushBatchRequests_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::Object::end_ice_flushBatchRequests(const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_flushBatchRequests_name); + result->_waitForResponse(); +} + +void +IceProxy::Ice::Object::_end(const ::Ice::AsyncResultPtr& result, const std::string& operation) const +{ + AsyncResult::_check(result, this, operation); + bool ok = result->_waitForResponse(); + if(_reference->getMode() == Reference::ModeTwoway) + { + if(!ok) + { + try + { + result->_throwUserException(); + } + catch(const UserException& ex) + { + throw UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); + } +} + +namespace IceProxy +{ + +namespace Ice +{ + +ostream& +operator<<(ostream& os, const ::IceProxy::Ice::Object& p) +{ + return os << p.ice_toString(); +} + +} + +} + +IceProxy::Ice::Object* +IceProxy::Ice::Object::_newInstance() const +{ + return new Object; +} + +AsyncResultPtr +IceProxy::Ice::Object::_iceI_begin_ice_getConnection(const ::IceInternal::CallbackBasePtr& del, + const ::Ice::LocalObjectPtr& cookie) +{ + class ProxyGetConnectionWithCallback : public ProxyGetConnection, public CallbackCompletion + { + public: + + ProxyGetConnectionWithCallback(const ::Ice::ObjectPrx& proxy, + const ::IceInternal::CallbackBasePtr& cb, + const ::Ice::LocalObjectPtr& cookie) : + ProxyGetConnection(proxy), CallbackCompletion(cb, cookie) + { + _cookie = cookie; + } + + virtual const std::string& + getOperation() const + { + return ice_getConnection_name; + } + }; + + ProxyGetConnectionPtr result = new ProxyGetConnectionWithCallback(this, del, cookie); + try + { + result->invoke(ice_getConnection_name); + } + catch(const Exception& ex) + { + result->abort(ex); + } + return result; +} + +ConnectionPtr +IceProxy::Ice::Object::end_ice_getConnection(const AsyncResultPtr& result) +{ + AsyncResult::_check(result, this, ice_getConnection_name); + result->_waitForResponse(); + return result->getConnection(); +} + +void +IceProxy::Ice::Object::_checkTwowayOnly(const string& name, bool sync) const +{ + // + // No mutex lock necessary, there is nothing mutable in this operation. + // + if(!ice_isTwoway()) + { + if(sync) + { + throw TwowayOnlyException(__FILE__, __LINE__, name); + } + else + { + throw IceUtil::IllegalArgumentException(__FILE__, + __LINE__, + "`" + name + "' can only be called with a twoway proxy"); + } + } +} + +#endif + +#ifdef ICE_CPP11_MAPPING +# define ICE_OBJECT_PRX Ice::ObjectPrx +# define CONST_POINTER_CAST_OBJECT_PRX const_pointer_cast(shared_from_this()) +#else +# define ICE_OBJECT_PRX IceProxy::Ice::Object +# define CONST_POINTER_CAST_OBJECT_PRX ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)) +#endif + +// +// methods common for both C++11/C++98 mappings +// + +Identity +ICE_OBJECT_PRX::ice_getIdentity() const +{ + return _reference->getIdentity(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_identity(const Identity& newIdentity) const +{ + if(newIdentity.name.empty()) + { + throw IllegalIdentityException(__FILE__, __LINE__); + } + if(newIdentity == _reference->getIdentity()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { +#ifdef ICE_CPP11_MAPPING + auto proxy = createProxy(); +#else + ObjectPrxPtr proxy = new IceProxy::Ice::Object; +#endif + proxy->setup(_reference->changeIdentity(newIdentity)); + return proxy; + } +} + +Context +ICE_OBJECT_PRX::ice_getContext() const +{ + return _reference->getContext()->getValue(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_context(const Context& newContext) const +{ + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeContext(newContext)); + return proxy; +} + +const string& +ICE_OBJECT_PRX::ice_getFacet() const +{ + return _reference->getFacet(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_facet(const string& newFacet) const +{ + if(newFacet == _reference->getFacet()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { +#ifdef ICE_CPP11_MAPPING + auto proxy = createProxy(); +#else + ObjectPrx proxy = new IceProxy::Ice::Object; +#endif + proxy->setup(_reference->changeFacet(newFacet)); + return proxy; + } +} + +string +ICE_OBJECT_PRX::ice_getAdapterId() const +{ + return _reference->getAdapterId(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_adapterId(const string& newAdapterId) const +{ + if(newAdapterId == _reference->getAdapterId()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeAdapterId(newAdapterId)); + return proxy; + } +} + +EndpointSeq +ICE_OBJECT_PRX::ice_getEndpoints() const +{ + vector endpoints = _reference->getEndpoints(); + EndpointSeq retSeq; + for(vector::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + retSeq.push_back(ICE_DYNAMIC_CAST(Endpoint, *p)); + } + return retSeq; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_endpoints(const EndpointSeq& newEndpoints) const +{ + vector endpoints; + for(EndpointSeq::const_iterator p = newEndpoints.begin(); p != newEndpoints.end(); ++p) + { + endpoints.push_back(ICE_DYNAMIC_CAST(EndpointI, *p)); + } + + if(endpoints == _reference->getEndpoints()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeEndpoints(endpoints)); + return proxy; + } +} + +Int +ICE_OBJECT_PRX::ice_getLocatorCacheTimeout() const +{ + return _reference->getLocatorCacheTimeout(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_locatorCacheTimeout(Int newTimeout) const +{ + if(newTimeout < -1) + { + ostringstream s; + s << "invalid value passed to ice_locatorCacheTimeout: " << newTimeout; +#ifdef ICE_CPP11_MAPPING + throw invalid_argument(s.str()); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, s.str()); +#endif + } + if(newTimeout == _reference->getLocatorCacheTimeout()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeLocatorCacheTimeout(newTimeout)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isConnectionCached() const +{ + return _reference->getCacheConnection(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_connectionCached(bool newCache) const +{ + if(newCache == _reference->getCacheConnection()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeCacheConnection(newCache)); + return proxy; + } +} + +EndpointSelectionType +ICE_OBJECT_PRX::ice_getEndpointSelection() const +{ + return _reference->getEndpointSelection(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_endpointSelection(EndpointSelectionType newType) const +{ + if(newType == _reference->getEndpointSelection()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeEndpointSelection(newType)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isSecure() const +{ + return _reference->getSecure(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_secure(bool b) const +{ + if(b == _reference->getSecure()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeSecure(b)); + return proxy; + } +} + +::Ice::EncodingVersion +ICE_OBJECT_PRX::ice_getEncodingVersion() const +{ + return _reference->getEncoding(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_encodingVersion(const ::Ice::EncodingVersion& encoding) const +{ + if(encoding == _reference->getEncoding()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeEncoding(encoding)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isPreferSecure() const +{ + return _reference->getPreferSecure(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_preferSecure(bool b) const +{ + if(b == _reference->getPreferSecure()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changePreferSecure(b)); + return proxy; + } +} + +RouterPrxPtr +ICE_OBJECT_PRX::ice_getRouter() const +{ + RouterInfoPtr ri = _reference->getRouterInfo(); +#ifdef ICE_CPP11_MAPPING + return ri ? ri->getRouter() : nullptr; +#else + return ri ? ri->getRouter() : RouterPrxPtr(); +#endif +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_router(const RouterPrxPtr& router) const +{ + ReferencePtr ref = _reference->changeRouter(router); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +LocatorPrxPtr +ICE_OBJECT_PRX::ice_getLocator() const +{ + LocatorInfoPtr ri = _reference->getLocatorInfo(); +#ifdef ICE_CPP11_MAPPING + return ri ? ri->getLocator() : nullptr; +#else + return ri ? ri->getLocator() : LocatorPrxPtr(); +#endif +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_locator(const LocatorPrxPtr& locator) const +{ + ReferencePtr ref = _reference->changeLocator(locator); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isCollocationOptimized() const +{ + return _reference->getCollocationOptimized(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_collocationOptimized(bool b) const +{ + if(b == _reference->getCollocationOptimized()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeCollocationOptimized(b)); + return proxy; + } +} + +Int +ICE_OBJECT_PRX::ice_getInvocationTimeout() const +{ + return _reference->getInvocationTimeout(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_invocationTimeout(Int newTimeout) const +{ + if(newTimeout < 1 && newTimeout != -1 && newTimeout != -2) + { + ostringstream s; + s << "invalid value passed to ice_invocationTimeout: " << newTimeout; +#ifdef ICE_CPP11_MAPPING + throw invalid_argument(s.str()); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, s.str()); +#endif + } + if(newTimeout == _reference->getInvocationTimeout()) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeInvocationTimeout(newTimeout)); + return proxy; + } +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_twoway() const +{ + if(_reference->getMode() == Reference::ModeTwoway) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeMode(Reference::ModeTwoway)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isTwoway() const +{ + return _reference->getMode() == Reference::ModeTwoway; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_oneway() const +{ + if(_reference->getMode() == Reference::ModeOneway) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeMode(Reference::ModeOneway)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isOneway() const +{ + return _reference->getMode() == Reference::ModeOneway; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_batchOneway() const +{ + if(_reference->getMode() == Reference::ModeBatchOneway) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeMode(Reference::ModeBatchOneway)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isBatchOneway() const +{ + return _reference->getMode() == Reference::ModeBatchOneway; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_datagram() const +{ + if(_reference->getMode() == Reference::ModeDatagram) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeMode(Reference::ModeDatagram)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isDatagram() const +{ + return _reference->getMode() == Reference::ModeDatagram; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_batchDatagram() const +{ + if(_reference->getMode() == Reference::ModeBatchDatagram) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(_reference->changeMode(Reference::ModeBatchDatagram)); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isBatchDatagram() const +{ + return _reference->getMode() == Reference::ModeBatchDatagram; +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_compress(bool b) const +{ + ReferencePtr ref = _reference->changeCompress(b); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +IceUtil::Optional +ICE_OBJECT_PRX::ice_getCompress() const +{ + return _reference->getCompress(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_timeout(int t) const +{ + if(t < 1 && t != -1) + { + ostringstream s; + s << "invalid value passed to ice_timeout: " << t; +#ifdef ICE_CPP11_MAPPING + throw invalid_argument(s.str()); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, s.str()); +#endif + } + ReferencePtr ref = _reference->changeTimeout(t); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +IceUtil::Optional +ICE_OBJECT_PRX::ice_getTimeout() const +{ + return _reference->getTimeout(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_connectionId(const string& id) const +{ + ReferencePtr ref = _reference->changeConnectionId(id); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +string +ICE_OBJECT_PRX::ice_getConnectionId() const +{ + return _reference->getConnectionId(); +} + +ObjectPrxPtr +ICE_OBJECT_PRX::ice_fixed(const ::Ice::ConnectionPtr& connection) const +{ + if(!connection) + { +#ifdef ICE_CPP11_MAPPING + throw invalid_argument("invalid null connection passed to ice_fixed"); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "invalid null connection passed to ice_fixed"); +#endif + } + ::Ice::ConnectionIPtr impl = ICE_DYNAMIC_CAST(::Ice::ConnectionI, connection); + if(!impl) + { +#ifdef ICE_CPP11_MAPPING + throw invalid_argument("invalid connection passed to ice_fixed"); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "invalid connection passed to ice_fixed"); +#endif + } + ReferencePtr ref = _reference->changeConnection(impl); + if(ref == _reference) + { + return CONST_POINTER_CAST_OBJECT_PRX; + } + else + { + ObjectPrxPtr proxy = _newInstance(); + proxy->setup(ref); + return proxy; + } +} + +bool +ICE_OBJECT_PRX::ice_isFixed() const +{ + return FixedReferencePtr::dynamicCast(_reference); +} + +ConnectionPtr +ICE_OBJECT_PRX::ice_getCachedConnection() const +{ + RequestHandlerPtr handler; + { + IceUtil::Mutex::Lock sync(_mutex); + handler = _requestHandler; + } + + if(handler) + { + try + { + return handler->getConnection(); + } + catch(const LocalException&) + { + } + } + return 0; +} + +void +ICE_OBJECT_PRX::setup(const ReferencePtr& ref) +{ + // + // No need to synchronize "*this", as this operation is only + // called upon initialization. + // + + assert(!_reference); + assert(!_requestHandler); + + _reference = ref; +} + +int +ICE_OBJECT_PRX::_handleException(const Exception& ex, + const RequestHandlerPtr& handler, + OperationMode mode, + bool sent, + int& cnt) +{ + _updateRequestHandler(handler, 0); // Clear the request handler + + // + // We only retry local exception, system exceptions aren't retried. + // + // A CloseConnectionException indicates graceful server shutdown, and is therefore + // always repeatable without violating "at-most-once". That's because by sending a + // close connection message, the server guarantees that all outstanding requests + // can safely be repeated. + // + // An ObjectNotExistException can always be retried as well without violating + // "at-most-once" (see the implementation of the checkRetryAfterException method + // of the ProxyFactory class for the reasons why it can be useful). + // + // If the request didn't get sent or if it's non-mutating or idempotent it can + // also always be retried if the retry count isn't reached. + // + const LocalException* localEx = dynamic_cast(&ex); + if(localEx && (!sent || + mode == ICE_ENUM(OperationMode, Nonmutating) || mode == ICE_ENUM(OperationMode, Idempotent) || + dynamic_cast(&ex) || + dynamic_cast(&ex))) + { + try + { + return _reference->getInstance()->proxyFactory()->checkRetryAfterException(*localEx, _reference, cnt); + } + catch(const CommunicatorDestroyedException&) + { + // + // The communicator is already destroyed, so we cannot retry. + // + ex.ice_throw(); + } + } + else + { + ex.ice_throw(); // Retry could break at-most-once semantics, don't retry. + } + return 0; // Keep the compiler happy. +} + +::IceInternal::RequestHandlerPtr +ICE_OBJECT_PRX::_getRequestHandler() +{ + RequestHandlerPtr handler; + if(_reference->getCacheConnection()) + { + IceUtil::Mutex::Lock sync(_mutex); + if(_requestHandler) + { + return _requestHandler; + } + } + return _reference->getRequestHandler(ICE_SHARED_FROM_THIS); +} + +IceInternal::BatchRequestQueuePtr +ICE_OBJECT_PRX::_getBatchRequestQueue() +{ + IceUtil::Mutex::Lock sync(_mutex); + if(!_batchRequestQueue) + { + _batchRequestQueue = _reference->getBatchRequestQueue(); + } + return _batchRequestQueue; +} + +::IceInternal::RequestHandlerPtr +ICE_OBJECT_PRX::_setRequestHandler(const ::IceInternal::RequestHandlerPtr& handler) +{ + if(_reference->getCacheConnection()) + { + IceUtil::Mutex::Lock sync(_mutex); + if(!_requestHandler) + { + _requestHandler = handler; + } + return _requestHandler; + } + return handler; +} + +void +ICE_OBJECT_PRX::_updateRequestHandler(const ::IceInternal::RequestHandlerPtr& previous, + const ::IceInternal::RequestHandlerPtr& handler) +{ + if(_reference->getCacheConnection() && previous) + { + IceUtil::Mutex::Lock sync(_mutex); + if(_requestHandler && _requestHandler.get() != handler.get()) + { + // + // Update the request handler only if "previous" is the same + // as the current request handler. This is called after + // connection binding by the connect request handler. We only + // replace the request handler if the current handler is the + // connect request handler. + // + _requestHandler = _requestHandler->update(previous, handler); + } + } +} + +void +ICE_OBJECT_PRX::_copyFrom(const ObjectPrxPtr& from) +{ + IceUtil::Mutex::Lock sync(from->_mutex); + _reference = from->_reference; + _requestHandler = from->_requestHandler; +} + +CommunicatorPtr +ICE_OBJECT_PRX::ice_getCommunicator() const +{ + return _reference->getCommunicator(); +} + +string +ICE_OBJECT_PRX::ice_toString() const +{ + // + // Returns the stringified proxy. There's no need to convert the + // string to a native string: a stringified proxy only contains + // printable ASCII which is a subset of all native character sets. + // + return _reference->toString(); +} + +Int +ICE_OBJECT_PRX::_hash() const +{ + return _reference->hash(); +} + +void +ICE_OBJECT_PRX::_write(OutputStream& os) const +{ + os.write(_getReference()->getIdentity()); + _getReference()->streamWrite(&os); +} + +bool +Ice::proxyIdentityLess(const ObjectPrxPtr& lhs, const ObjectPrxPtr& rhs) +{ + if(!lhs && !rhs) + { + return false; + } + else if(!lhs && rhs) + { + return true; + } + else if(lhs && !rhs) + { + return false; + } + else + { + return lhs->ice_getIdentity() < rhs->ice_getIdentity(); + } +} + +bool +Ice::proxyIdentityEqual(const ObjectPrxPtr& lhs, const ObjectPrxPtr& rhs) +{ + if(!lhs && !rhs) + { + return true; + } + else if(!lhs && rhs) + { + return false; + } + else if(lhs && !rhs) + { + return false; + } + else + { + return lhs->ice_getIdentity() == rhs->ice_getIdentity(); + } +} + +bool +Ice::proxyIdentityAndFacetLess(const ObjectPrxPtr& lhs, const ObjectPrxPtr& rhs) +{ + if(!lhs && !rhs) + { + return false; + } + else if(!lhs && rhs) + { + return true; + } + else if(lhs && !rhs) + { + return false; + } + else + { + Identity lhsIdentity = lhs->ice_getIdentity(); + Identity rhsIdentity = rhs->ice_getIdentity(); + + if(lhsIdentity < rhsIdentity) + { + return true; + } + else if(rhsIdentity < lhsIdentity) + { + return false; + } + + string lhsFacet = lhs->ice_getFacet(); + string rhsFacet = rhs->ice_getFacet(); + + if(lhsFacet < rhsFacet) + { + return true; + } + else if(rhsFacet < lhsFacet) + { + return false; + } + + return false; + } +} + +bool +Ice::proxyIdentityAndFacetEqual(const ObjectPrxPtr& lhs, const ObjectPrxPtr& rhs) +{ + if(!lhs && !rhs) + { + return true; + } + else if(!lhs && rhs) + { + return false; + } + else if(lhs && !rhs) + { + return false; + } + else + { + Identity lhsIdentity = lhs->ice_getIdentity(); + Identity rhsIdentity = rhs->ice_getIdentity(); + + if(lhsIdentity == rhsIdentity) + { + string lhsFacet = lhs->ice_getFacet(); + string rhsFacet = rhs->ice_getFacet(); + + if(lhsFacet == rhsFacet) + { + return true; + } + } + + return false; + } +} diff --git a/Sources/IceCpp/ProxyFactory.cpp b/Sources/IceCpp/ProxyFactory.cpp new file mode 100644 index 0000000..7389f25 --- /dev/null +++ b/Sources/IceCpp/ProxyFactory.cpp @@ -0,0 +1,300 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(ProxyFactory* p) { return p; } + +ObjectPrxPtr +IceInternal::ProxyFactory::stringToProxy(const string& str) const +{ + ReferencePtr ref = _instance->referenceFactory()->create(str, ""); + return referenceToProxy(ref); +} + +string +IceInternal::ProxyFactory::proxyToString(const ObjectPrxPtr& proxy) const +{ + if(proxy) + { + return proxy->_getReference()->toString(); + } + else + { + return ""; + } +} + +ObjectPrxPtr +IceInternal::ProxyFactory::propertyToProxy(const string& prefix) const +{ + string proxy = _instance->initializationData().properties->getProperty(prefix); + ReferencePtr ref = _instance->referenceFactory()->create(proxy, prefix); + return referenceToProxy(ref); +} + +PropertyDict +IceInternal::ProxyFactory::proxyToProperty(const ObjectPrxPtr& proxy, const string& prefix) const +{ + if(proxy) + { + return proxy->_getReference()->toProperty(prefix); + } + else + { + return PropertyDict(); + } +} + +ObjectPrxPtr +IceInternal::ProxyFactory::streamToProxy(InputStream* s) const +{ + Identity ident; + s->read(ident); + + ReferencePtr ref = _instance->referenceFactory()->create(ident, s); + return referenceToProxy(ref); +} + +ObjectPrxPtr +IceInternal::ProxyFactory::referenceToProxy(const ReferencePtr& ref) const +{ + if(ref) + { +#ifdef ICE_CPP11_MAPPING + auto proxy = createProxy(); +#else + ObjectPrx proxy = new ::IceProxy::Ice::Object(); +#endif + proxy->setup(ref); + return proxy; + } + else + { + return ICE_NULLPTR; + } +} + +int +IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, const ReferencePtr& ref, int& cnt) const +{ + TraceLevelsPtr traceLevels = _instance->traceLevels(); + LoggerPtr logger = _instance->initializationData().logger; + + // + // We don't retry batch requests because the exception might have + // caused all the requests batched with the connection to be + // aborted and we want the application to be notified. + // + if(ref->getMode() == Reference::ModeBatchOneway || ref->getMode() == Reference::ModeBatchDatagram) + { + ex.ice_throw(); + } + + // + // If it's a fixed proxy, retrying isn't useful as the proxy is tied to + // the connection and the request will fail with the exception. + // + if(dynamic_cast(ref.get())) + { + ex.ice_throw(); + } + + const ObjectNotExistException* one = dynamic_cast(&ex); + if(one) + { + if(ref->getRouterInfo() && one->operation == "ice_add_proxy") + { + // + // If we have a router, an ObjectNotExistException with an + // operation name "ice_add_proxy" indicates to the client + // that the router isn't aware of the proxy (for example, + // because it was evicted by the router). In this case, we + // must *always* retry, so that the missing proxy is added + // to the router. + // + + ref->getRouterInfo()->clearCache(ref); + + if(traceLevels->retry >= 1) + { + Trace out(logger, traceLevels->retryCat); + out << "retrying operation call to add proxy to router\n" << ex; + } + + return 0; // We must always retry, so we don't look at the retry count. + } + else if(ref->isIndirect()) + { + // + // We retry ObjectNotExistException if the reference is + // indirect. + // + + if(ref->isWellKnown()) + { + LocatorInfoPtr li = ref->getLocatorInfo(); + if(li) + { + li->clearCache(ref); + } + } + } + else + { + // + // For all other cases, we don't retry + // ObjectNotExistException. + // + ex.ice_throw(); + } + } + else if(dynamic_cast(&ex)) + { + // + // We don't retry other *NotExistException, which are all + // derived from RequestFailedException. + // + ex.ice_throw(); + } + + // + // There is no point in retrying an operation that resulted in a + // MarshalException. This must have been raised locally (because + // if it happened in a server it would result in an + // UnknownLocalException instead), which means there was a problem + // in this process that will not change if we try again. + // + // The most likely cause for a MarshalException is exceeding the + // maximum message size, which is represented by the subclass + // MemoryLimitException. For example, a client can attempt to send + // a message that exceeds the maximum memory size, or accumulate + // enough batch requests without flushing that the maximum size is + // reached. + // + // This latter case is especially problematic, because if we were + // to retry a batch request after a MarshalException, we would in + // fact silently discard the accumulated requests and allow new + // batch requests to accumulate. If the subsequent batched + // requests do not exceed the maximum message size, it appears to + // the client that all of the batched requests were accepted, when + // in reality only the last few are actually sent. + // + if(dynamic_cast(&ex)) + { + ex.ice_throw(); + } + + // + // Don't retry if the communicator is destroyed, object adapter is deactivated, + // or connection is manually closed. + // + if(dynamic_cast(&ex) || + dynamic_cast(&ex) || + dynamic_cast(&ex)) + { + ex.ice_throw(); + } + + // + // Don't retry invocation timeouts. + // + if(dynamic_cast(&ex) || dynamic_cast(&ex)) + { + ex.ice_throw(); + } + + ++cnt; + assert(cnt > 0); + + int interval = -1; + if(cnt == static_cast(_retryIntervals.size() + 1) && dynamic_cast(&ex)) + { + // + // A close connection exception is always retried at least once, even if the retry + // limit is reached. + // + interval = 0; + } + else if(cnt > static_cast(_retryIntervals.size())) + { + if(traceLevels->retry >= 1) + { + Trace out(logger, traceLevels->retryCat); + out << "cannot retry operation call because retry limit has been exceeded\n" << ex; + } + ex.ice_throw(); + } + else + { + interval = _retryIntervals[static_cast(cnt - 1)]; + } + + if(traceLevels->retry >= 1) + { + Trace out(logger, traceLevels->retryCat); + out << "retrying operation call"; + if(interval > 0) + { + out << " in " << interval << "ms"; + } + out << " because of exception\n" << ex; + } + return interval; +} + +IceInternal::ProxyFactory::ProxyFactory(const InstancePtr& instance) : + _instance(instance) +{ + StringSeq retryValues = _instance->initializationData().properties->getPropertyAsList("Ice.RetryIntervals"); + if(retryValues.size() == 0) + { + _retryIntervals.push_back(0); + } + else + { + for(StringSeq::const_iterator p = retryValues.begin(); p != retryValues.end(); ++p) + { + istringstream value(*p); + + int v; + if(!(value >> v) || !value.eof()) + { + v = 0; + } + + // + // If -1 is the first value, no retry and wait intervals. + // + if(v == -1 && _retryIntervals.empty()) + { + break; + } + + _retryIntervals.push_back(v > 0 ? v : 0); + } + } +} + +IceInternal::ProxyFactory::~ProxyFactory() +{ +} diff --git a/Sources/IceCpp/Random.cpp b/Sources/IceCpp/Random.cpp new file mode 100644 index 0000000..b0b9b01 --- /dev/null +++ b/Sources/IceCpp/Random.cpp @@ -0,0 +1,180 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifdef _WIN32 +# define _CRT_RAND_S +#endif + +#include +#include +#include + +#ifndef _WIN32 +# include +# include +#endif + +using namespace std; +using namespace IceUtil; + +#if !defined(_WIN32) +namespace +{ + +// +// The static mutex is required to lazy initialize the file +// descriptor for /dev/urandom (Unix) +// +// Also, unfortunately on Linux (at least up to 2.6.9), concurrent +// access to /dev/urandom can return the same value. Search for +// "Concurrent access to /dev/urandom" in the linux-kernel mailing +// list archive for additional details. Since /dev/urandom on other +// platforms is usually a port from Linux, this problem could be +// widespread. Therefore, we serialize access to /dev/urandom using a +// static mutex. +// +Mutex* staticMutex = 0; +int fd = -1; + +// +// Callback to use with pthread_atfork to reset the "/dev/urandom" +// fd state. We don't need to close the fd here as that is done +// during static destruction. +// +extern "C" +{ + +void childAtFork() +{ + if(fd != -1) + { + fd = -1; + } +} + +} + +class Init +{ +public: + + Init() + { + staticMutex = new IceUtil::Mutex; + + // + // Register a callback to reset the "/dev/urandom" fd + // state after fork. + // + pthread_atfork(0, 0, &childAtFork); + } + + ~Init() + { + if(fd != -1) + { + close(fd); + fd = -1; + } + delete staticMutex; + staticMutex = 0; + } +}; + +Init init; + +} +#endif + +void +IceUtilInternal::generateRandom(char* buffer, size_t size) +{ +#ifdef _WIN32 + int i = 0; + const size_t randSize = sizeof(unsigned int); + + while(size - i >= randSize) + { + unsigned int r = 0; + errno_t err = rand_s(&r); + if(err != 0) + { + throw SyscallException(__FILE__, __LINE__, errno); + } + memcpy(buffer + i, &r, randSize); + i += randSize; + } + + if(size - i > 0) + { + assert(size - i < randSize); + unsigned int r = 0; + errno_t err = rand_s(&r); + if(err != 0) + { + throw SyscallException(__FILE__, __LINE__, errno); + } + memcpy(buffer + i, &r, size - i); + } +#else + // + // Serialize access to /dev/urandom; see comment above. + // + IceUtilInternal::MutexPtrLock lock(staticMutex); + if(fd == -1) + { + fd = open("/dev/urandom", O_RDONLY); + if(fd == -1) + { + throw SyscallException(__FILE__, __LINE__, errno); + } + } + + // + // Limit the number of attempts to 20 reads to avoid + // a potential "for ever" loop + // + int reads = 0; + size_t index = 0; + while(reads <= 20 && index != size) + { + ssize_t bytesRead = read(fd, buffer + index, size - index); + + if(bytesRead == -1 && errno != EINTR) + { + throw SyscallException(__FILE__, __LINE__, errno); + } + else + { + index += static_cast(bytesRead); + reads++; + } + } + + if(index != size) + { + throw SyscallException(__FILE__, __LINE__, 0); + } +#endif +} + +unsigned int +IceUtilInternal::random(int limit) +{ + unsigned int r; +#ifdef _WIN32 + errno_t err = rand_s(&r); + if(err != 0) + { + throw SyscallException(__FILE__, __LINE__, errno); + } +#else + generateRandom(reinterpret_cast(&r), sizeof(unsigned int)); +#endif + if(limit > 0) + { + r = r % static_cast(limit); + } + return r; +} diff --git a/Sources/IceCpp/RecMutex.cpp b/Sources/IceCpp/RecMutex.cpp new file mode 100644 index 0000000..94a61b3 --- /dev/null +++ b/Sources/IceCpp/RecMutex.cpp @@ -0,0 +1,238 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; + +IceUtil::RecMutex::RecMutex() : + _count(0) +{ +#ifdef _WIN32 + init(PrioNone); +#else + init(getDefaultMutexProtocol()); +#endif +} + +IceUtil::RecMutex::RecMutex(const IceUtil::MutexProtocol protocol) : + _count(0) +{ + init(protocol); +} + +#ifdef _WIN32 + +void +IceUtil::RecMutex::init(const MutexProtocol) +{ + InitializeCriticalSection(&_mutex); +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); + DeleteCriticalSection(&_mutex); +} + +void +IceUtil::RecMutex::lock() const +{ + EnterCriticalSection(&_mutex); + if(++_count > 1) + { + LeaveCriticalSection(&_mutex); + } +} + +bool +IceUtil::RecMutex::tryLock() const +{ + if(!TryEnterCriticalSection(&_mutex)) + { + return false; + } + if(++_count > 1) + { + LeaveCriticalSection(&_mutex); + } + return true; +} + +void +IceUtil::RecMutex::unlock() const +{ + if(--_count == 0) + { + LeaveCriticalSection(&_mutex); + } +} + +# ifdef ICE_HAS_WIN32_CONDVAR +void +IceUtil::RecMutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; + state.count = _count; + _count = 0; +} + +void +IceUtil::RecMutex::lock(LockState& state) const +{ + _count = state.count; +} +# else +void +IceUtil::RecMutex::unlock(LockState& state) const +{ + state.count = _count; + _count = 0; + LeaveCriticalSection(&_mutex); +} + +void +IceUtil::RecMutex::lock(LockState& state) const +{ + EnterCriticalSection(&_mutex); + _count = state.count; +} +# endif + +#else + +void +IceUtil::RecMutex::init(ICE_MAYBE_UNUSED const MutexProtocol protocol) +{ + int rc; + pthread_mutexattr_t attr; + rc = pthread_mutexattr_init(&attr); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + +#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 + if(PrioInherit == protocol) + { + rc = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); + assert(rc == 0); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } +#endif + + rc = pthread_mutex_init(&_mutex, &attr); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + rc = pthread_mutexattr_destroy(&attr); + assert(rc == 0); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); +#ifndef NDEBUG + int rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); +#else + pthread_mutex_destroy(&_mutex); +#endif +} + +void +IceUtil::RecMutex::lock() const +{ + int rc = pthread_mutex_lock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + if(++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + } +} + +bool +IceUtil::RecMutex::tryLock() const +{ + int rc = pthread_mutex_trylock(&_mutex); + bool result = (rc == 0); + if(!result) + { + if(rc != EBUSY) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + else if(++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + return result; +} + +void +IceUtil::RecMutex::unlock() const +{ + if(--_count == 0) + { +#ifndef NDEBUG + int rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); +#else + pthread_mutex_unlock(&_mutex); +#endif + } +} + +void +IceUtil::RecMutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; + state.count = _count; + _count = 0; +} + +void +IceUtil::RecMutex::lock(LockState& state) const +{ + _count = state.count; +} + +#endif + +bool +IceUtil::RecMutex::willUnlock() const +{ + return _count == 1; +} diff --git a/Sources/IceCpp/Reference.cpp b/Sources/IceCpp/Reference.cpp new file mode 100644 index 0000000..a604279 --- /dev/null +++ b/Sources/IceCpp/Reference.cpp @@ -0,0 +1,2046 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#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 + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(IceInternal::Reference* p) { return p; } + +namespace +{ + +IceUtil::Mutex* hashMutex = 0; + +class Init +{ +public: + + Init() + { + hashMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete hashMutex; + hashMutex = 0; + } +}; + +Init init; + +} + +CommunicatorPtr +IceInternal::Reference::getCommunicator() const +{ + return _communicator; +} + +ReferencePtr +IceInternal::Reference::changeContext(const Context& newContext) const +{ + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_context = new SharedContext(newContext); + return r; +} + +ReferencePtr +IceInternal::Reference::changeMode(Mode newMode) const +{ + if(newMode == _mode) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_mode = newMode; + return r; +} + +ReferencePtr +IceInternal::Reference::changeSecure(bool newSecure) const +{ + if(newSecure == _secure) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_secure = newSecure; + return r; +} + +ReferencePtr +IceInternal::Reference::changeIdentity(const Identity& newIdentity) const +{ + if(newIdentity == _identity) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_identity = newIdentity; + return r; +} + +ReferencePtr +IceInternal::Reference::changeFacet(const string& newFacet) const +{ + if(newFacet == _facet) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_facet = newFacet; + return r; +} + +ReferencePtr +IceInternal::Reference::changeInvocationTimeout(int invocationTimeout) const +{ + if(_invocationTimeout == invocationTimeout) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_invocationTimeout = invocationTimeout; + return r; +} + +ReferencePtr +IceInternal::Reference::changeEncoding(const Ice::EncodingVersion& encoding) const +{ + if(_encoding == encoding) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_encoding = encoding; + return r; +} + +ReferencePtr +IceInternal::Reference::changeCompress(bool newCompress) const +{ + if(_overrideCompress && newCompress == _compress) + { + return ReferencePtr(const_cast(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_compress = newCompress; + r->_overrideCompress = true; + return r; +} + +bool +IceInternal::Reference::getCompressOverride(bool& compress) const +{ + DefaultsAndOverridesPtr defaultsAndOverrides = getInstance()->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else if(_overrideCompress) + { + compress = _compress; + } + else + { + return false; + } + return true; +} + +Int +Reference::hash() const +{ + IceUtilInternal::MutexPtrLock lock(hashMutex); + if(!_hashInitialized) + { + _hashValue = hashInit(); + _hashInitialized = true; + } + return _hashValue; +} + +void +IceInternal::Reference::streamWrite(OutputStream* s) const +{ + // + // Don't write the identity here. Operations calling streamWrite + // write the identity. + // + + // + // For compatibility with the old FacetPath. + // + if(_facet.empty()) + { + s->write(static_cast(0), static_cast(0)); + } + else + { + s->write(&_facet, &_facet + 1); + } + + s->write(static_cast(_mode)); + + s->write(_secure); + + if(s->getEncoding() != Ice::Encoding_1_0) + { + s->write(_protocol); + s->write(_encoding); + } + + // Derived class writes the remainder of the reference. +} + +string +IceInternal::Reference::toString() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + + ToStringMode toStringMode = _instance->toStringMode(); + const string separators = " :@"; + + string id = Ice::identityToString(_identity, toStringMode); + + // + // If the encoded identity string contains characters which + // the reference parser uses as separators, then we enclose + // the identity string in quotes. + // + + if(id.find_first_of(separators) != string::npos) + { + s << '"' << id << '"'; + } + else + { + s << id; + } + + if(!_facet.empty()) + { + s << " -f "; + + string fs = escapeString(_facet, "", toStringMode); + // + // If the encoded facet string contains characters which + // the reference parser uses as separators, then we enclose + // the facet string in quotes. + // + if(fs.find_first_of(separators) != string::npos) + { + s << '"' << fs << '"'; + } + else + { + s << fs; + } + } + + switch(_mode) + { + case ModeTwoway: + { + s << " -t"; + break; + } + + case ModeOneway: + { + s << " -o"; + break; + } + + case ModeBatchOneway: + { + s << " -O"; + break; + } + + case ModeDatagram: + { + s << " -d"; + break; + } + + case ModeBatchDatagram: + { + s << " -D"; + break; + } + } + + if(_secure) + { + s << " -s"; + } + + if(_protocol != Ice::Protocol_1_0) + { + // + // We only print the protocol if it's not 1.0. It's fine as + // long as we don't add Ice.Default.ProtocolVersion, a + // stringified proxy will convert back to the same proxy with + // stringToProxy. + // + s << " -p " << _protocol; + } + + // + // Always print the encoding version to ensure a stringified proxy + // will convert back to a proxy with the same encoding with + // stringToProxy (and won't use Ice.Default.EncodingVersion). + // + s << " -e " << _encoding; + + return s.str(); + + // Derived class writes the remainder of the string. +} + +bool +IceInternal::Reference::operator==(const Reference& r) const +{ + // + // Note: if(this == &r) test is performed by each non-abstract derived class. + // + + if(_mode != r._mode) + { + return false; + } + + if(_secure != r._secure) + { + return false; + } + + if(_identity != r._identity) + { + return false; + } + + if(_context->getValue() != r._context->getValue()) + { + return false; + } + + if(_facet != r._facet) + { + return false; + } + + if((_overrideCompress != r._overrideCompress) || (_overrideCompress && _compress != r._compress)) + { + return false; + } + + if(_protocol != r._protocol) + { + return false; + } + + if(_encoding != r._encoding) + { + return false; + } + + if(_invocationTimeout != r._invocationTimeout) + { + return false; + } + return true; +} + +bool +IceInternal::Reference::operator<(const Reference& r) const +{ + // + // Note: if(this == &r) test is performed by each non-abstract derived class. + // + + if(_mode < r._mode) + { + return true; + } + else if(r._mode < _mode) + { + return false; + } + + if(_identity < r._identity) + { + return true; + } + else if(r._identity < _identity) + { + return false; + } + + if(_context->getValue() < r._context->getValue()) + { + return true; + } + else if(r._context->getValue() < _context->getValue()) + { + return false; + } + + if(_facet < r._facet) + { + return true; + } + else if(r._facet < _facet) + { + return false; + } + + if(!_overrideCompress && r._overrideCompress) + { + return true; + } + else if(r._overrideCompress < _overrideCompress) + { + return false; + } + else if(_overrideCompress) + { + if(!_compress && r._compress) + { + return true; + } + else if(r._compress < _compress) + { + return false; + } + } + + if(!_secure && r._secure) + { + return true; + } + else if(r._secure < _secure) + { + return false; + } + + if(_protocol < r._protocol) + { + return true; + } + else if(r._protocol < _protocol) + { + return false; + } + + if(_encoding < r._encoding) + { + return true; + } + else if(r._encoding < _encoding) + { + return false; + } + + if(_invocationTimeout < r._invocationTimeout) + { + return true; + } + else if(r._invocationTimeout < _invocationTimeout) + { + return false; + } + + return false; +} + +#ifndef ICE_CPP11_COMPILER +class ConnectionIsDatagram : public unary_function +{ +public: + + bool + operator()(ConnectionIPtr p) const + { + return p->endpoint()->datagram(); + } +}; + +class ConnectionIsSecure : public unary_function +{ +public: + + bool + operator()(ConnectionIPtr p) const + { + return p->endpoint()->secure(); + } +}; +#endif + +IceInternal::Reference::Reference(const InstancePtr& instance, + const CommunicatorPtr& communicator, + const Identity& id, + const string& facet, + Mode mode, + bool secure, + const ProtocolVersion& protocol, + const EncodingVersion& encoding, + int invocationTimeout, + const Ice::Context& ctx) : + _hashInitialized(false), + _instance(instance), + _communicator(communicator), + _mode(mode), + _secure(secure), + _identity(id), + _context(new SharedContext(ctx)), + _facet(facet), + _protocol(protocol), + _encoding(encoding), + _invocationTimeout(invocationTimeout), + _overrideCompress(false), + _compress(false) +{ +} + +IceInternal::Reference::Reference(const Reference& r) : + IceUtil::Shared(), + _hashInitialized(false), + _instance(r._instance), + _communicator(r._communicator), + _mode(r._mode), + _secure(r._secure), + _identity(r._identity), + _context(r._context), + _facet(r._facet), + _protocol(r._protocol), + _encoding(r._encoding), + _invocationTimeout(r._invocationTimeout), + _overrideCompress(r._overrideCompress), + _compress(r._compress) +{ +} + +int +IceInternal::Reference::hashInit() const +{ + Int h = 5381; + hashAdd(h, static_cast(_mode)); + hashAdd(h, _secure); + hashAdd(h, _identity.name); + hashAdd(h, _identity.category); + hashAdd(h, _context->getValue()); + hashAdd(h, _facet); + hashAdd(h, _overrideCompress); + if(_overrideCompress) + { + hashAdd(h, _compress); + } + hashAdd(h, _protocol.major); + hashAdd(h, _protocol.minor); + hashAdd(h, _encoding.major); + hashAdd(h, _encoding.minor); + hashAdd(h, _invocationTimeout); + return h; +} + +IceUtil::Shared* IceInternal::upCast(IceInternal::FixedReference* p) { return p; } + +IceInternal::FixedReference::FixedReference(const InstancePtr& instance, + const CommunicatorPtr& communicator, + const Identity& id, + const string& facet, + Mode mode, + bool secure, + const ProtocolVersion& protocol, + const EncodingVersion& encoding, + const ConnectionIPtr& fixedConnection, + int invocationTimeout, + const Ice::Context& context, + const IceUtil::Optional& compress) : + Reference(instance, communicator, id, facet, mode, secure, protocol, encoding, invocationTimeout, context), + _fixedConnection(fixedConnection) +{ + if(compress) + { + _overrideCompress = true; + _compress = *compress; + } +} + +vector +IceInternal::FixedReference::getEndpoints() const +{ + return vector(); +} + +string +IceInternal::FixedReference::getAdapterId() const +{ + return string(); +} + +bool +IceInternal::FixedReference::getCollocationOptimized() const +{ + return false; +} + +bool +IceInternal::FixedReference::getCacheConnection() const +{ + return true; +} + +bool +IceInternal::FixedReference::getPreferSecure() const +{ + return false; +} + +Ice::EndpointSelectionType +IceInternal::FixedReference::getEndpointSelection() const +{ + return ICE_ENUM(EndpointSelectionType, Random); +} + +int +IceInternal::FixedReference::getLocatorCacheTimeout() const +{ + return 0; +} + +string +IceInternal::FixedReference::getConnectionId() const +{ + return string(); +} + +IceUtil::Optional +IceInternal::FixedReference::getTimeout() const +{ + return IceUtil::Optional(); +} + +ReferencePtr +IceInternal::FixedReference::changeEndpoints(const vector& /*newEndpoints*/) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeAdapterId(const string& /*newAdapterId*/) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeLocator(const LocatorPrxPtr&) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeRouter(const RouterPrxPtr&) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeCollocationOptimized(bool) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeCacheConnection(bool) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changePreferSecure(bool) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeEndpointSelection(EndpointSelectionType) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeLocatorCacheTimeout(int) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeTimeout(int) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeConnectionId(const string&) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +ReferencePtr +IceInternal::FixedReference::changeConnection(const Ice::ConnectionIPtr& newConnection) const +{ + if(newConnection == _fixedConnection) + { + return FixedReferencePtr(const_cast(this)); + } + FixedReferencePtr r = FixedReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_fixedConnection = newConnection; + return r; +} + +bool +IceInternal::FixedReference::isIndirect() const +{ + return false; +} + +bool +IceInternal::FixedReference::isWellKnown() const +{ + return false; +} + +void +IceInternal::FixedReference::streamWrite(OutputStream*) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +PropertyDict +IceInternal::FixedReference::toProperty(const string&) const +{ + throw FixedProxyException(__FILE__, __LINE__); +} + +RequestHandlerPtr +IceInternal::FixedReference::getRequestHandler(const Ice::ObjectPrxPtr& proxy) const +{ + switch(getMode()) + { + case Reference::ModeTwoway: + case Reference::ModeOneway: + case Reference::ModeBatchOneway: + { + if(_fixedConnection->endpoint()->datagram()) + { + throw NoEndpointException(__FILE__, __LINE__, toString()); + } + break; + } + + case Reference::ModeDatagram: + case Reference::ModeBatchDatagram: + { + if(!_fixedConnection->endpoint()->datagram()) + { + throw NoEndpointException(__FILE__, __LINE__, toString()); + } + break; + } + } + + // + // If a secure connection is requested or secure overrides is set, + // check if the connection is secure. + // + bool secure; + DefaultsAndOverridesPtr defaultsAndOverrides = getInstance()->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideSecure) + { + secure = defaultsAndOverrides->overrideSecureValue; + } + else + { + secure = getSecure(); + } + if(secure && !_fixedConnection->endpoint()->secure()) + { + throw NoEndpointException(__FILE__, __LINE__, toString()); + } + + _fixedConnection->throwException(); // Throw in case our connection is already destroyed. + + bool compress = false; + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else if(_overrideCompress) + { + compress = _compress; + } + + ReferencePtr ref = const_cast(this); + return proxy->_setRequestHandler(ICE_MAKE_SHARED(ConnectionRequestHandler, ref, _fixedConnection, compress)); +} + +BatchRequestQueuePtr +IceInternal::FixedReference::getBatchRequestQueue() const +{ + return _fixedConnection->getBatchRequestQueue(); +} + +bool +IceInternal::FixedReference::operator==(const Reference& r) const +{ + if(this == &r) + { + return true; + } + const FixedReference* rhs = dynamic_cast(&r); + if(!rhs || !Reference::operator==(r)) + { + return false; + } + return _fixedConnection == rhs->_fixedConnection; +} + +bool +IceInternal::FixedReference::operator<(const Reference& r) const +{ + if(this == &r) + { + return false; + } + if(Reference::operator<(r)) + { + return true; + } + if(!Reference::operator==(r)) + { + return false; + } + + const FixedReference* rhs = dynamic_cast(&r); + if(!rhs) + { + assert(dynamic_cast(&r)); + return false; // As a rule, routable references are superior to fixed references. + } + return _fixedConnection < rhs->_fixedConnection; +} + +ReferencePtr +IceInternal::FixedReference::clone() const +{ + return new FixedReference(*this); +} + +IceInternal::FixedReference::FixedReference(const FixedReference& r) : + Reference(r), + _fixedConnection(r._fixedConnection) +{ +} + +IceUtil::Shared* IceInternal::upCast(IceInternal::RoutableReference* p) { return p; } + +IceInternal::RoutableReference::RoutableReference(const InstancePtr& instance, + const CommunicatorPtr& communicator, + const Identity& id, + const string& facet, + Mode mode, + bool secure, + const ProtocolVersion& protocol, + const EncodingVersion& encoding, + const vector& endpoints, + const string& adapterId, + const LocatorInfoPtr& locatorInfo, + const RouterInfoPtr& routerInfo, + bool collocationOptimized, + bool cacheConnection, + bool preferSecure, + EndpointSelectionType endpointSelection, + int locatorCacheTimeout, + int invocationTimeout, + const Ice::Context& ctx) : + Reference(instance, communicator, id, facet, mode, secure, protocol, encoding, invocationTimeout, ctx), + _endpoints(endpoints), + _adapterId(adapterId), + _locatorInfo(locatorInfo), + _routerInfo(routerInfo), + _collocationOptimized(collocationOptimized), + _cacheConnection(cacheConnection), + _preferSecure(preferSecure), + _endpointSelection(endpointSelection), + _locatorCacheTimeout(locatorCacheTimeout), + _overrideTimeout(false), + _timeout(-1) +{ + assert(_adapterId.empty() || _endpoints.empty()); +} + +vector +IceInternal::RoutableReference::getEndpoints() const +{ + return _endpoints; +} + +string +IceInternal::RoutableReference::getAdapterId() const +{ + return _adapterId; +} + +LocatorInfoPtr +IceInternal::RoutableReference::getLocatorInfo() const +{ + return _locatorInfo; +} + +RouterInfoPtr +IceInternal::RoutableReference::getRouterInfo() const +{ + return _routerInfo; +} + +bool +IceInternal::RoutableReference::getCollocationOptimized() const +{ + return _collocationOptimized; +} + +bool +IceInternal::RoutableReference::getCacheConnection() const +{ + return _cacheConnection; +} + +bool +IceInternal::RoutableReference::getPreferSecure() const +{ + return _preferSecure; +} + +Ice::EndpointSelectionType +IceInternal::RoutableReference::getEndpointSelection() const +{ + return _endpointSelection; +} + +int +IceInternal::RoutableReference::getLocatorCacheTimeout() const +{ + return _locatorCacheTimeout; +} + +string +IceInternal::RoutableReference::getConnectionId() const +{ + return _connectionId; +} + +IceUtil::Optional +IceInternal::RoutableReference::getTimeout() const +{ + return _overrideTimeout ? IceUtil::Optional(_timeout) : IceUtil::None; +} + +ReferencePtr +IceInternal::RoutableReference::changeEncoding(const Ice::EncodingVersion& encoding) const +{ + ReferencePtr r = Reference::changeEncoding(encoding); + if(r.get() != const_cast(this)) + { + LocatorInfoPtr& locInfo = RoutableReferencePtr::dynamicCast(r)->_locatorInfo; + if(locInfo && locInfo->getLocator()->ice_getEncodingVersion() != encoding) + { + locInfo = getInstance()->locatorManager()->get(locInfo->getLocator()->ice_encodingVersion(encoding)); + } + } + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeCompress(bool newCompress) const +{ + ReferencePtr r = Reference::changeCompress(newCompress); + // Also override the compress flag on the endpoints if it was updated. + if(r.get() != const_cast(this) && !_endpoints.empty()) + { + vector newEndpoints; + for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) + { + newEndpoints.push_back((*p)->compress(newCompress)); + } + RoutableReferencePtr::dynamicCast(r)->_endpoints = newEndpoints; + } + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeEndpoints(const vector& newEndpoints) const +{ + if(newEndpoints == _endpoints) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_endpoints = newEndpoints; + r->applyOverrides(r->_endpoints); + r->_adapterId.clear(); + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeAdapterId(const string& newAdapterId) const +{ + if(newAdapterId == _adapterId) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_adapterId = newAdapterId; + r->_endpoints.clear(); + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeLocator(const LocatorPrxPtr& newLocator) const +{ + LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(newLocator); + if(newLocatorInfo == _locatorInfo) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_locatorInfo = newLocatorInfo; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeRouter(const RouterPrxPtr& newRouter) const +{ + RouterInfoPtr newRouterInfo = getInstance()->routerManager()->get(newRouter); + if(newRouterInfo == _routerInfo) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_routerInfo = newRouterInfo; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeCollocationOptimized(bool newCollocationOptimized) const +{ + if(newCollocationOptimized == _collocationOptimized) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_collocationOptimized = newCollocationOptimized; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeCacheConnection(bool newCache) const +{ + if(newCache == _cacheConnection) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_cacheConnection = newCache; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changePreferSecure(bool newPreferSecure) const +{ + if(newPreferSecure == _preferSecure) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_preferSecure = newPreferSecure; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeEndpointSelection(EndpointSelectionType newType) const +{ + if(newType == _endpointSelection) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_endpointSelection = newType; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeLocatorCacheTimeout(int timeout) const +{ + if(timeout == _locatorCacheTimeout) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_locatorCacheTimeout = timeout; + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeTimeout(int newTimeout) const +{ + if(_overrideTimeout && newTimeout == _timeout) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_timeout = newTimeout; + r->_overrideTimeout = true; + if(!_endpoints.empty()) // Also override the timeout on the endpoints. + { + vector newEndpoints; + for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) + { + newEndpoints.push_back((*p)->timeout(newTimeout)); + } + r->_endpoints = newEndpoints; + } + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeConnectionId(const string& id) const +{ + if(id == _connectionId) + { + return RoutableReferencePtr(const_cast(this)); + } + RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->copy(this)); + r->_connectionId = id; + if(!_endpoints.empty()) // Also override the connection id on the endpoints. + { + vector newEndpoints; + for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) + { + newEndpoints.push_back((*p)->connectionId(id)); + } + r->_endpoints = newEndpoints; + } + return r; +} + +ReferencePtr +IceInternal::RoutableReference::changeConnection(const Ice::ConnectionIPtr& connection) const +{ + return new FixedReference(getInstance(), + getCommunicator(), + getIdentity(), + getFacet(), + getMode(), + getSecure(), + getProtocol(), + getEncoding(), + connection, + getInvocationTimeout(), + getContext()->getValue(), + getCompress()); +} + +bool +IceInternal::RoutableReference::isIndirect() const +{ + return _endpoints.empty(); +} + +bool +IceInternal::RoutableReference::isWellKnown() const +{ + return _endpoints.empty() && _adapterId.empty(); +} + +void +IceInternal::RoutableReference::streamWrite(OutputStream* s) const +{ + Reference::streamWrite(s); + + Int sz = static_cast(_endpoints.size()); + s->writeSize(sz); + if(sz) + { + assert(_adapterId.empty()); + for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) + { + s->write((*p)->type()); + (*p)->streamWrite(s); + } + } + else + { + s->write(_adapterId); + } +} + +string +IceInternal::RoutableReference::toString() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + string result = Reference::toString(); + + if(!_endpoints.empty()) + { + for(vector::const_iterator p = _endpoints.begin(); p != _endpoints.end(); ++p) + { + string endp = (*p)->toString(); + if(!endp.empty()) + { + result.append(":"); + result.append(endp); + } + } + } + else if(!_adapterId.empty()) + { + result.append(" @ "); + + // + // If the encoded adapter id string contains characters which the + // reference parser uses as separators, then we enclose the + // adapter id string in quotes. + // + string a = escapeString(_adapterId, "", getInstance()->toStringMode()); + if(a.find_first_of(" :@") != string::npos) + { + result.append("\""); + result.append(a); + result.append("\""); + } + else + { + result.append(a); + } + } + else + { + return result; + } + return result; +} + +PropertyDict +IceInternal::RoutableReference::toProperty(const string& prefix) const +{ + Ice::PropertyDict properties; + + properties[prefix] = toString(); + properties[prefix + ".CollocationOptimized"] = _collocationOptimized ? "1" : "0"; + properties[prefix + ".ConnectionCached"] = _cacheConnection ? "1" : "0"; + properties[prefix + ".PreferSecure"] = _preferSecure ? "1" : "0"; + properties[prefix + ".EndpointSelection"] = _endpointSelection == ICE_ENUM(EndpointSelectionType, Random) ? "Random" : "Ordered"; + { + ostringstream s; + s << _locatorCacheTimeout; + properties[prefix + ".LocatorCacheTimeout"] = s.str(); + } + { + ostringstream s; + s << getInvocationTimeout(); + properties[prefix + ".InvocationTimeout"] = s.str(); + } + if(_routerInfo) + { + PropertyDict routerProperties = _routerInfo->getRouter()->_getReference()->toProperty(prefix + ".Router"); + for(PropertyDict::const_iterator p = routerProperties.begin(); p != routerProperties.end(); ++p) + { + properties[p->first] = p->second; + } + } + + if(_locatorInfo) + { + PropertyDict locatorProperties = _locatorInfo->getLocator()->_getReference()->toProperty(prefix + ".Locator"); + for(PropertyDict::const_iterator p = locatorProperties.begin(); p != locatorProperties.end(); ++p) + { + properties[p->first] = p->second; + } + } + + return properties; +} + +int +IceInternal::RoutableReference::hashInit() const +{ + int value = Reference::hashInit(); + hashAdd(value, _adapterId); + return value; +} + +bool +IceInternal::RoutableReference::operator==(const Reference& r) const +{ + // + // Note: if(this == &r) test is performed by each non-abstract derived class. + // + if(this == &r) + { + return true; + } + + const RoutableReference* rhs = dynamic_cast(&r); + if(!rhs || !Reference::operator==(r)) + { + return false; + } + if(_preferSecure != rhs->_preferSecure) + { + return false; + } + if(_collocationOptimized != rhs->_collocationOptimized) + { + return false; + } + if(_cacheConnection != rhs->_cacheConnection) + { + return false; + } + if(_endpointSelection != rhs->_endpointSelection) + { + return false; + } + if(_connectionId != rhs->_connectionId) + { + return false; + } + if((_overrideTimeout != rhs->_overrideTimeout) || (_overrideTimeout && _timeout != rhs->_timeout)) + { + return false; + } + if(_routerInfo != rhs->_routerInfo) + { + return false; + } + if(_locatorInfo != rhs->_locatorInfo) + { + return false; + } +#ifdef ICE_CPP11_MAPPING + // + // TODO: With C++14 we could use the version that receives four iterators and we don't need to explicitly + // check the sizes are equal. + // + if(_endpoints.size() != rhs->_endpoints.size() || + !equal(_endpoints.begin(), _endpoints.end(), rhs->_endpoints.begin(), Ice::TargetCompare, std::equal_to>())) +#else + if(_endpoints != rhs->_endpoints) +#endif + { + return false; + } + if(_adapterId != rhs->_adapterId) + { + return false; + } + if(_locatorCacheTimeout != rhs->_locatorCacheTimeout) + { + return false; + } + return true; +} + +bool +IceInternal::RoutableReference::operator<(const Reference& r) const +{ + if(this == &r) + { + return false; + } + + if(Reference::operator<(r)) + { + return true; + } + else if(!Reference::operator==(r)) + { + return false; + } + + const RoutableReference* rhs = dynamic_cast(&r); + if(!rhs) + { + assert(dynamic_cast(&r)); + return true; // As a rule, routable references are superior to fixed references. + } + + if(!_preferSecure && rhs->_preferSecure) + { + return true; + } + else if(rhs->_preferSecure < _preferSecure) + { + return false; + } + if(!_collocationOptimized && rhs->_collocationOptimized) + { + return true; + } + else if(rhs->_collocationOptimized < _collocationOptimized) + { + return false; + } + if(!_cacheConnection && rhs->_cacheConnection) + { + return true; + } + else if(rhs->_cacheConnection < _cacheConnection) + { + return false; + } + if(_endpointSelection < rhs->_endpointSelection) + { + return true; + } + else if(rhs->_endpointSelection < _endpointSelection) + { + return false; + } + if(_connectionId < rhs->_connectionId) + { + return true; + } + else if(rhs->_connectionId < _connectionId) + { + return false; + } + if(!_overrideTimeout && rhs->_overrideTimeout) + { + return true; + } + else if(rhs->_overrideTimeout < _overrideTimeout) + { + return false; + } + else if(_overrideTimeout) + { + if(_timeout < rhs->_timeout) + { + return true; + } + else if(rhs->_timeout < _timeout) + { + return false; + } + } + if(_routerInfo < rhs->_routerInfo) + { + return true; + } + else if(rhs->_routerInfo < _routerInfo) + { + return false; + } + if(_locatorInfo < rhs->_locatorInfo) + { + return true; + } + else if(rhs->_locatorInfo < _locatorInfo) + { + return false; + } + if(_adapterId < rhs->_adapterId) + { + return true; + } + else if(rhs->_adapterId < _adapterId) + { + return false; + } +#ifdef ICE_CPP11_MAPPING + if(lexicographical_compare(_endpoints.begin(), _endpoints.end(), rhs->_endpoints.begin(), rhs->_endpoints.end(), + Ice::TargetCompare, std::less>())) +#else + if(_endpoints < rhs->_endpoints) +#endif + { + return true; + } + else if(rhs->_endpoints < _endpoints) + { + return false; + } + if(_locatorCacheTimeout < rhs->_locatorCacheTimeout) + { + return true; + } + else if(rhs->_locatorCacheTimeout < _locatorCacheTimeout) + { + return false; + } + return false; +} + +ReferencePtr +IceInternal::RoutableReference::clone() const +{ + return new RoutableReference(*this); +} + +RequestHandlerPtr +IceInternal::RoutableReference::getRequestHandler(const Ice::ObjectPrxPtr& proxy) const +{ + return getInstance()->requestHandlerFactory()->getRequestHandler(const_cast(this), proxy); +} + +BatchRequestQueuePtr +IceInternal::RoutableReference::getBatchRequestQueue() const +{ + return new BatchRequestQueue(getInstance(), getMode() == Reference::ModeBatchDatagram); +} + +void +IceInternal::RoutableReference::getConnection(const GetConnectionCallbackPtr& callback) const +{ + class Callback : public RouterInfo::GetClientEndpointsCallback + { + public: + + virtual void + setEndpoints(const vector& endpoints) + { + vector endpts = endpoints; + if(!endpts.empty()) + { + _reference->applyOverrides(endpts); + _reference->createConnection(endpts, _callback); + return; + } + + _reference->getConnectionNoRouterInfo(_callback); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + Callback(const RoutableReferencePtr& reference, const GetConnectionCallbackPtr& callback) : + _reference(reference), _callback(callback) + { + } + + private: + + const RoutableReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + }; + + if(_routerInfo) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + _routerInfo->getClientEndpoints(new Callback(const_cast(this), callback)); + return; + } + + getConnectionNoRouterInfo(callback); +} + +void +IceInternal::RoutableReference::getConnectionNoRouterInfo(const GetConnectionCallbackPtr& callback) const +{ + class Callback : public LocatorInfo::GetEndpointsCallback + { + public: + + class Callback2 ICE_FINAL : public Reference::GetConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& exc) + { + try + { + exc.ice_throw(); + } + catch(const Ice::NoEndpointException& ex) + { + _callback->setException(ex); // No need to retry if there's no endpoints. + } + catch(const Ice::LocalException& ex) + { + LocatorInfoPtr locatorInfo = _reference->getLocatorInfo(); + assert(locatorInfo); + locatorInfo->clearCache(_reference); + if(_cached) + { + TraceLevelsPtr traceLvls = _reference->getInstance()->traceLevels(); + if(traceLvls->retry >= 2) + { + Trace out(_reference->getInstance()->initializationData().logger, traceLvls->retryCat); + out << "connection to cached endpoints failed\n" + << "removing endpoints from cache and trying again\n" << ex; + } + _reference->getConnectionNoRouterInfo(_callback); // Retry. + return; + } + _callback->setException(ex); + } + } + + Callback2(const RoutableReferencePtr& reference, const GetConnectionCallbackPtr& cb, bool cached) : + _reference(reference), _callback(cb), _cached(cached) + { + } + + private: + + const RoutableReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + const bool _cached; + }; + + virtual void + setEndpoints(const vector& endpoints, bool cached) + { + if(endpoints.empty()) + { + _callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, _reference->toString())); + return; + } + + vector endpts = endpoints; + _reference->applyOverrides(endpts); + _reference->createConnection(endpts, ICE_MAKE_SHARED(Callback2, _reference, _callback, cached)); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + Callback(const RoutableReferencePtr& reference, const GetConnectionCallbackPtr& callback) : + _reference(reference), _callback(callback) + { + } + + private: + + const RoutableReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + }; + + if(!_endpoints.empty()) + { + createConnection(_endpoints, callback); + return; + } + + if(_locatorInfo) + { + RoutableReference* self = const_cast(this); + _locatorInfo->getEndpoints(self, _locatorCacheTimeout, new Callback(self, callback)); + } + else + { + callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, toString())); + } +} + +void +IceInternal::RoutableReference::createConnection(const vector& allEndpoints, + const GetConnectionCallbackPtr& callback) const +{ + vector endpoints = filterEndpoints(allEndpoints); + if(endpoints.empty()) + { + callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, toString())); + return; + } + + // + // Finally, create the connection. + // + OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); + if(getCacheConnection() || endpoints.size() == 1) + { + class CB1 : public OutgoingConnectionFactory::CreateConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo && _routerInfo->getAdapter()) + { + connection->setAdapter(_routerInfo->getAdapter()); + } + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + CB1(const RouterInfoPtr& routerInfo, const GetConnectionCallbackPtr& callback) : + _routerInfo(routerInfo), _callback(callback) + { + } + + private: + + const RouterInfoPtr _routerInfo; + const GetConnectionCallbackPtr _callback; + }; + + // + // Get an existing connection or create one if there's no + // existing connection to one of the given endpoints. + // + factory->create(endpoints, false, getEndpointSelection(), new CB1(_routerInfo, callback)); + return; + } + else + { + class CB2 : public OutgoingConnectionFactory::CreateConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_reference->getRouterInfo() && _reference->getRouterInfo()->getAdapter()) + { + connection->setAdapter(_reference->getRouterInfo()->getAdapter()); + } + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& ex) + { + if(!_exception) + { + ICE_SET_EXCEPTION_FROM_CLONE(_exception, ex.ice_clone()); + } + + if(++_i == _endpoints.size()) + { + _callback->setException(*_exception); + return; + } + + const bool more = _i != _endpoints.size() - 1; + vector endpoint; + endpoint.push_back(_endpoints[_i]); + + OutgoingConnectionFactoryPtr factory = _reference->getInstance()->outgoingConnectionFactory(); + factory->create(endpoint, more, _reference->getEndpointSelection(), this); + } + + CB2(const RoutableReferencePtr& reference, const vector& endpoints, + const GetConnectionCallbackPtr& callback) : + _reference(reference), + _endpoints(endpoints), + _callback(callback), + _i(0) + { + } + + private: + + const RoutableReferencePtr _reference; + const vector _endpoints; + const GetConnectionCallbackPtr _callback; + size_t _i; + IceInternal::UniquePtr _exception; + }; + + // + // Go through the list of endpoints and try to create the + // connection until it succeeds. This is different from just + // calling create() with the given endpoints since this might + // create a new connection even if there's an existing + // connection for one of the endpoints. + // + + vector endpt; + endpt.push_back(endpoints[0]); + RoutableReference* self = const_cast(this); + factory->create(endpt, true, getEndpointSelection(), new CB2(self, endpoints, callback)); + return; + } +} + +void +IceInternal::RoutableReference::applyOverrides(vector& endpoints) const +{ + for(vector::iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + *p = (*p)->connectionId(_connectionId); + if(_overrideCompress) + { + *p = (*p)->compress(_compress); + } + if(_overrideTimeout) + { + *p = (*p)->timeout(_timeout); + } + } +} + +IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) : + Reference(r), + _endpoints(r._endpoints), + _adapterId(r._adapterId), + _locatorInfo(r._locatorInfo), + _routerInfo(r._routerInfo), + _collocationOptimized(r._collocationOptimized), + _cacheConnection(r._cacheConnection), + _preferSecure(r._preferSecure), + _endpointSelection(r._endpointSelection), + _locatorCacheTimeout(r._locatorCacheTimeout), + _overrideTimeout(r._overrideTimeout), + _timeout(r._timeout), + _connectionId(r._connectionId) +{ +} + +namespace +{ + +#ifndef ICE_CPP11_COMPILER +struct EndpointIsOpaque : public unary_function +{ +public: + + bool + operator()(EndpointIPtr p) const + { + return dynamic_cast(p.get()) != 0; + } +}; +#endif + +} + +vector +IceInternal::RoutableReference::filterEndpoints(const vector& allEndpoints) const +{ + vector endpoints = allEndpoints; + + // + // Filter out unknown endpoints. + // +#ifdef ICE_CPP11_COMPILER + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return dynamic_cast(p.get()) != 0; + }), + endpoints.end()); +#else + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), EndpointIsOpaque()), endpoints.end()); +#endif + // + // Filter out endpoints according to the mode of the reference. + // + switch(getMode()) + { + case Reference::ModeTwoway: + case Reference::ModeOneway: + case Reference::ModeBatchOneway: + { + // + // Filter out datagram endpoints. + // +#ifdef ICE_CPP11_COMPILER + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return p->datagram(); + }), + endpoints.end()); +#else + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&EndpointI::datagram)), + endpoints.end()); +#endif + break; + } + + case Reference::ModeDatagram: + case Reference::ModeBatchDatagram: + { + // + // Filter out non-datagram endpoints. + // +#ifdef ICE_CPP11_COMPILER + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return !p->datagram(); + }), + endpoints.end()); +#else + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + not1(Ice::constMemFun(&EndpointI::datagram))), + endpoints.end()); +#endif + break; + } + } + + // + // Sort the endpoints according to the endpoint selection type. + // + switch(getEndpointSelection()) + { + case ICE_ENUM(EndpointSelectionType, Random): + { + IceUtilInternal::shuffle(endpoints.begin(), endpoints.end()); + break; + } + case ICE_ENUM(EndpointSelectionType, Ordered): + { + // Nothing to do. + break; + } + default: + { + assert(false); + break; + } + } + + // + // If a secure connection is requested or secure overrides is set, + // remove all non-secure endpoints. Otherwise if preferSecure is set + // make secure endpoints prefered. By default make non-secure + // endpoints preferred over secure endpoints. + // + DefaultsAndOverridesPtr overrides = getInstance()->defaultsAndOverrides(); + if(overrides->overrideSecure ? overrides->overrideSecureValue : getSecure()) + { +#ifdef ICE_CPP11_COMPILER + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return !p->secure(); + }), + endpoints.end()); +#else + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), not1(Ice::constMemFun(&EndpointI::secure))), + endpoints.end()); +#endif + } + else if(getPreferSecure()) + { + // + // We must use stable_partition() instead of just simply + // partition(), because otherwise some STL implementations + // order our now randomized endpoints. + // +#ifdef ICE_CPP11_COMPILER + stable_partition(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return p->secure(); + }); +#else + stable_partition(endpoints.begin(), endpoints.end(), Ice::constMemFun(&EndpointI::secure)); +#endif + } + else + { + // + // We must use stable_partition() instead of just simply + // partition(), because otherwise some STL implementations + // order our now randomized endpoints. + // +#ifdef ICE_CPP11_COMPILER + stable_partition(endpoints.begin(), endpoints.end(), + [](const EndpointIPtr& p) + { + return !p->secure(); + }); +#else + stable_partition(endpoints.begin(), endpoints.end(), not1(Ice::constMemFun(&EndpointI::secure))); +#endif + } + + return endpoints; +} diff --git a/Sources/IceCpp/ReferenceFactory.cpp b/Sources/IceCpp/ReferenceFactory.cpp new file mode 100644 index 0000000..7175eee --- /dev/null +++ b/Sources/IceCpp/ReferenceFactory.cpp @@ -0,0 +1,888 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(::IceInternal::ReferenceFactory* p) { return p; } + +ReferencePtr +IceInternal::ReferenceFactory::copy(const Reference* r) const +{ + const Ice::Identity& ident = r->getIdentity(); + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + return r->clone(); +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, + const string& facet, + const ReferencePtr& tmpl, + const vector& endpoints) +{ + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), tmpl->getProtocol(), tmpl->getEncoding(), + endpoints, "", ""); +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, + const string& facet, + const ReferencePtr& tmpl, + const string& adapterId) +{ + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), tmpl->getProtocol(), tmpl->getEncoding(), + vector(), adapterId, ""); +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, const Ice::ConnectionIPtr& connection) +{ + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + // + // Create new reference + // + return new FixedReference(_instance, + _communicator, + ident, + "", // Facet + connection->endpoint()->datagram() ? Reference::ModeDatagram : Reference::ModeTwoway, + connection->endpoint()->secure(), + Ice::Protocol_1_0, + _instance->defaultsAndOverrides()->defaultEncoding, + connection, + -1, + Ice::Context(), + IceUtil::Optional()); +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const string& str, const string& propertyPrefix) +{ + if(str.empty()) + { + return 0; + } + + const string delim = " \t\r\n"; + + string s(str); + string::size_type beg; + string::size_type end = 0; + + beg = s.find_first_not_of(delim, end); + if(beg == string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "no non-whitespace characters found in `" + s + "'"); + } + + // + // Extract the identity, which may be enclosed in single + // or double quotation marks. + // + string idstr; + end = IceUtilInternal::checkQuote(s, beg); + if(end == string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around identity in `" + s + "'"); + } + else if(end == 0) + { + end = s.find_first_of(delim + ":@", beg); + if(end == string::npos) + { + end = s.size(); + } + idstr = s.substr(beg, end - beg); + } + else + { + beg++; // Skip leading quote + idstr = s.substr(beg, end - beg); + end++; // Skip trailing quote + } + + if(beg == end) + { + throw ProxyParseException(__FILE__, __LINE__, "no identity in `" + s + "'"); + } + + // + // Parsing the identity may raise IdentityParseException. + // + Identity ident = Ice::stringToIdentity(idstr); + + if(ident.name.empty()) + { + // + // An identity with an empty name and a non-empty + // category is illegal. + // + if(!ident.category.empty()) + { + throw IllegalIdentityException(__FILE__, __LINE__, ident); + } + // + // Treat a stringified proxy containing two double + // quotes ("") the same as an empty string, i.e., + // a null proxy, but only if nothing follows the + // quotes. + // + else if(s.find_first_not_of(delim, end) != string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid characters after identity in `" + s + "'"); + } + else + { + return 0; + } + } + + string facet; + Reference::Mode mode = Reference::ModeTwoway; + bool secure = false; + Ice::EncodingVersion encoding = _instance->defaultsAndOverrides()->defaultEncoding; + Ice::ProtocolVersion protocol = Protocol_1_0; + string adapter; + + while(true) + { + beg = s.find_first_not_of(delim, end); + if(beg == string::npos) + { + break; + } + + if(s[beg] == ':' || s[beg] == '@') + { + break; + } + + end = s.find_first_of(delim + ":@", beg); + if(end == string::npos) + { + end = s.length(); + } + + if(beg == end) + { + break; + } + + string option = s.substr(beg, end - beg); + if(option.length() != 2 || option[0] != '-') + { + throw ProxyParseException(__FILE__, __LINE__, "expected a proxy option but found `" + option + "' in `" + + s + "'"); + } + + // + // Check for the presence of an option argument. The + // argument may be enclosed in single or double + // quotation marks. + // + string argument; + string::size_type argumentBeg = s.find_first_not_of(delim, end); + if(argumentBeg != string::npos) + { + if(s[argumentBeg] != '@' && s[argumentBeg] != ':' && s[argumentBeg] != '-') + { + beg = argumentBeg; + end = IceUtilInternal::checkQuote(s, beg); + if(end == string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around value for " + option + + " option in `" + s + "'"); + } + else if(end == 0) + { + end = s.find_first_of(delim + ":@", beg); + if(end == string::npos) + { + end = s.size(); + } + argument = s.substr(beg, end - beg); + } + else + { + beg++; // Skip leading quote + argument = s.substr(beg, end - beg); + end++; // Skip trailing quote + } + } + } + + // + // If any new options are added here, + // IceInternal::Reference::toString() and its derived classes must be updated as well. + // + switch(option[1]) + { + case 'f': + { + if(argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -f option in `" + s + "'"); + } + + try + { + facet = unescapeString(argument, 0, argument.size(), ""); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid facet in `" + s + "': " + ex.reason()); + } + + break; + } + + case 't': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -t option in `" + s + "'"); + } + mode = Reference::ModeTwoway; + break; + } + + case 'o': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -o option in `" + s + "'"); + } + mode = Reference::ModeOneway; + break; + } + + case 'O': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -O option in `" + s + "'"); + } + mode = Reference::ModeBatchOneway; + break; + } + + case 'd': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -d option in `" + s + "'"); + } + mode = Reference::ModeDatagram; + break; + } + + case 'D': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -D option in `" + s + "'"); + } + mode = Reference::ModeBatchDatagram; + break; + } + + case 's': + { + if(!argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -s option in `" + s + "'"); + } + secure = true; + break; + } + + case 'e': + { + if(argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -e option in `" + s + "'"); + } + + try + { + encoding = Ice::stringToEncodingVersion(argument); + } + catch(const Ice::VersionParseException& ex) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid encoding version `" + argument + "' in `" + + s + "':\n" + ex.str); + } + break; + } + + case 'p': + { + if(argument.empty()) + { + throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -p option in `" + s + "'"); + } + + try + { + protocol = Ice::stringToProtocolVersion(argument); + } + catch(const Ice::VersionParseException& ex) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid protocol version `" + argument + "' in `" + + s + "':\n" + ex.str); + } + break; + } + + default: + { + throw ProxyParseException(__FILE__, __LINE__, "unknown option `" + option + "' in `" + s + "'"); + } + } + } + + if(beg == string::npos) + { + return create(ident, facet, mode, secure, protocol, encoding, vector(), "", propertyPrefix); + } + + vector endpoints; + switch(s[beg]) + { + case ':': + { + vector unknownEndpoints; + end = beg; + + while(end < s.length() && s[end] == ':') + { + beg = end + 1; + + end = beg; + while(true) + { + end = s.find(':', end); + if(end == string::npos) + { + end = s.length(); + break; + } + else + { + bool quoted = false; + string::size_type quote = beg; + while(true) + { + quote = s.find('\"', quote); + if(quote == string::npos || end < quote) + { + break; + } + else + { + quote = s.find('\"', ++quote); + if(quote == string::npos) + { + break; + } + else if(end < quote) + { + quoted = true; + break; + } + ++quote; + } + } + if(!quoted) + { + break; + } + ++end; + } + } + + string es = s.substr(beg, end - beg); + EndpointIPtr endp = _instance->endpointFactoryManager()->create(es, false); + if(endp != ICE_NULLPTR) + { + endpoints.push_back(endp); + } + else + { + unknownEndpoints.push_back(es); + } + } + if(endpoints.size() == 0) + { + assert(!unknownEndpoints.empty()); + throw EndpointParseException(__FILE__, __LINE__, "invalid endpoint `" + unknownEndpoints.front() + + "' in `" + s + "'"); + } + else if(unknownEndpoints.size() != 0 && + _instance->initializationData().properties-> + getPropertyAsIntWithDefault("Ice.Warn.Endpoints", 1) > 0) + { + Warning out(_instance->initializationData().logger); + out << "Proxy contains unknown endpoints:"; + for(unsigned int idx = 0; idx < unknownEndpoints.size(); ++idx) + { + out << " `" << unknownEndpoints[idx] << "'"; + } + } + + return create(ident, facet, mode, secure, protocol, encoding, endpoints, "", propertyPrefix); + break; + } + case '@': + { + beg = s.find_first_not_of(delim, beg + 1); + if(beg == string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "missing adapter id in `" + s + "'"); + } + + string adapterstr; + end = IceUtilInternal::checkQuote(s, beg); + if(end == string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around adapter id in `" + s + "'"); + } + else if(end == 0) + { + end = s.find_first_of(delim, beg); + if(end == string::npos) + { + end = s.size(); + } + adapterstr = s.substr(beg, end - beg); + } + else + { + beg++; // Skip leading quote + adapterstr = s.substr(beg, end - beg); + end++; // Skip trailing quote. + } + + // Check for trailing whitespace. + if(end != string::npos && s.find_first_not_of(delim, end) != string::npos) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid trailing characters after `" + + s.substr(0, end + 1) + "' in `" + s + "'"); + } + + try + { + adapter = unescapeString(adapterstr, 0, adapterstr.size(), ""); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + throw ProxyParseException(__FILE__, __LINE__, "invalid adapter id in `" + s + "': " + ex.reason()); + } + if(adapter.size() == 0) + { + throw ProxyParseException(__FILE__, __LINE__, "empty adapter id in `" + s + "'"); + } + + return create(ident, facet, mode, secure, protocol, encoding, endpoints, adapter, propertyPrefix); + break; + } + default: + { + throw ProxyParseException(__FILE__, __LINE__, "malformed proxy `" + s + "'"); + } + } +} + +ReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, InputStream* s) +{ + // + // Don't read the identity here. Operations calling this + // constructor read the identity, and pass it as a parameter. + // + + if(ident.name.empty() && ident.category.empty()) + { + return 0; + } + + // + // For compatibility with the old FacetPath. + // + vector facetPath; + s->read(facetPath); + string facet; + if(!facetPath.empty()) + { + if(facetPath.size() > 1) + { + throw ProxyUnmarshalException(__FILE__, __LINE__); + } + facet.swap(facetPath[0]); + } + + Byte modeAsByte; + s->read(modeAsByte); + Reference::Mode mode = static_cast(modeAsByte); + if(mode < 0 || mode > Reference::ModeLast) + { + throw ProxyUnmarshalException(__FILE__, __LINE__); + } + + bool secure; + s->read(secure); + + Ice::ProtocolVersion protocol; + Ice::EncodingVersion encoding; + if(s->getEncoding() != Ice::Encoding_1_0) + { + s->read(protocol); + s->read(encoding); + } + else + { + protocol = Ice::Protocol_1_0; + encoding = Ice::Encoding_1_0; + } + + vector endpoints; + string adapterId; + + Ice::Int sz = s->readSize(); + + if(sz > 0) + { + endpoints.reserve(static_cast(sz)); + while(sz--) + { + EndpointIPtr endpoint = _instance->endpointFactoryManager()->read(s); + endpoints.push_back(endpoint); + } + } + else + { + s->read(adapterId); + } + + return create(ident, facet, mode, secure, protocol, encoding, endpoints, adapterId, ""); +} + +ReferenceFactoryPtr +IceInternal::ReferenceFactory::setDefaultRouter(const RouterPrxPtr& defaultRouter) +{ + if(defaultRouter == _defaultRouter) + { + return this; + } + + ReferenceFactoryPtr factory = new ReferenceFactory(_instance, _communicator); + factory->_defaultLocator = _defaultLocator; + factory->_defaultRouter = defaultRouter; + return factory; +} + +RouterPrxPtr +IceInternal::ReferenceFactory::getDefaultRouter() const +{ + return _defaultRouter; +} + +ReferenceFactoryPtr +IceInternal::ReferenceFactory::setDefaultLocator(const LocatorPrxPtr& defaultLocator) +{ + if(defaultLocator == _defaultLocator) + { + return this; + } + + ReferenceFactoryPtr factory = new ReferenceFactory(_instance, _communicator); + factory->_defaultRouter = _defaultRouter; + factory->_defaultLocator = defaultLocator; + return factory; +} + +LocatorPrxPtr +IceInternal::ReferenceFactory::getDefaultLocator() const +{ + return _defaultLocator; +} + +IceInternal::ReferenceFactory::ReferenceFactory(const InstancePtr& instance, const CommunicatorPtr& communicator) : + _instance(instance), + _communicator(communicator) +{ +} + +void +IceInternal::ReferenceFactory::checkForUnknownProperties(const string& prefix) +{ + static const string suffixes[] = + { + "EndpointSelection", + "ConnectionCached", + "PreferSecure", + "LocatorCacheTimeout", + "InvocationTimeout", + "Locator", + "Router", + "CollocationOptimized", + "Context.*" + }; + + // + // Do not warn about unknown properties list if Ice prefix, ie Ice, Glacier2, etc + // + for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) + { + if(prefix.find(*i) == 0) + { + return; + } + } + + StringSeq unknownProps; + PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix + "."); + for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) + { + bool valid = false; + for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) + { + string prop = prefix + "." + suffixes[i]; + if(IceUtilInternal::match(p->first, prop)) + { + valid = true; + break; + } + } + + if(!valid) + { + unknownProps.push_back(p->first); + } + } + + if(unknownProps.size()) + { + Warning out(_instance->initializationData().logger); + out << "found unknown properties for proxy '" << prefix << "':"; + for(unsigned int i = 0; i < unknownProps.size(); ++i) + { + out << "\n " << unknownProps[i]; + } + } +} + +RoutableReferencePtr +IceInternal::ReferenceFactory::create(const Identity& ident, + const string& facet, + Reference::Mode mode, + bool secure, + const Ice::ProtocolVersion& protocol, + const Ice::EncodingVersion& encoding, + const vector& endpoints, + const string& adapterId, + const string& propertyPrefix) +{ + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + + // + // Default local proxy options. + // + LocatorInfoPtr locatorInfo; + if(_defaultLocator) + { + if(_defaultLocator->ice_getEncodingVersion() != encoding) + { + locatorInfo = _instance->locatorManager()->get(_defaultLocator->ice_encodingVersion(encoding)); + } + else + { + locatorInfo = _instance->locatorManager()->get(_defaultLocator); + } + } + RouterInfoPtr routerInfo = _instance->routerManager()->get(_defaultRouter); + bool collocationOptimized = defaultsAndOverrides->defaultCollocationOptimization; + bool cacheConnection = true; + bool preferSecure = defaultsAndOverrides->defaultPreferSecure; + Ice::EndpointSelectionType endpointSelection = defaultsAndOverrides->defaultEndpointSelection; + int locatorCacheTimeout = defaultsAndOverrides->defaultLocatorCacheTimeout; + int invocationTimeout = defaultsAndOverrides->defaultInvocationTimeout; + Ice::Context ctx; + + // + // Override the defaults with the proxy properties if a property prefix is defined. + // + if(!propertyPrefix.empty()) + { + PropertiesPtr properties = _instance->initializationData().properties; + if(properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) + { + checkForUnknownProperties(propertyPrefix); + } + + string property; + + property = propertyPrefix + ".Locator"; + LocatorPrxPtr locator = ICE_UNCHECKED_CAST(LocatorPrx, _communicator->propertyToProxy(property)); + if(locator) + { + if(locator->ice_getEncodingVersion() != encoding) + { + locatorInfo = _instance->locatorManager()->get(locator->ice_encodingVersion(encoding)); + } + else + { + locatorInfo = _instance->locatorManager()->get(locator); + } + } + + property = propertyPrefix + ".Router"; + RouterPrxPtr router = ICE_UNCHECKED_CAST(RouterPrx, _communicator->propertyToProxy(property)); + if(router) + { + if(propertyPrefix.size() > 7 && propertyPrefix.substr(propertyPrefix.size() - 7, 7) == ".Router") + { + Warning out(_instance->initializationData().logger); + out << "`" << property << "=" << properties->getProperty(property) + << "': cannot set a router on a router; setting ignored"; + } + else + { + routerInfo = _instance->routerManager()->get(router); + } + } + + property = propertyPrefix + ".CollocationOptimized"; + collocationOptimized = properties->getPropertyAsIntWithDefault(property, collocationOptimized) > 0; + + property = propertyPrefix + ".ConnectionCached"; + cacheConnection = properties->getPropertyAsIntWithDefault(property, cacheConnection) > 0; + + property = propertyPrefix + ".PreferSecure"; + preferSecure = properties->getPropertyAsIntWithDefault(property, preferSecure) > 0; + + property = propertyPrefix + ".EndpointSelection"; + if(!properties->getProperty(property).empty()) + { + string type = properties->getProperty(property); + if(type == "Random") + { + endpointSelection = ICE_ENUM(EndpointSelectionType, Random); + } + else if(type == "Ordered") + { + endpointSelection = ICE_ENUM(EndpointSelectionType, Ordered); + } + else + { + throw EndpointSelectionTypeParseException(__FILE__, __LINE__, "illegal value `" + type + + "'; expected `Random' or `Ordered'"); + } + } + + property = propertyPrefix + ".LocatorCacheTimeout"; + string value = properties->getProperty(property); + if(!value.empty()) + { + locatorCacheTimeout = properties->getPropertyAsIntWithDefault(property, locatorCacheTimeout); + if(locatorCacheTimeout < -1) + { + locatorCacheTimeout = -1; + + Warning out(_instance->initializationData().logger); + out << "invalid value for " << property << "`" << properties->getProperty(property) << "'" + << ": defaulting to -1"; + } + } + + property = propertyPrefix + ".InvocationTimeout"; + value = properties->getProperty(property); + if(!value.empty()) + { + invocationTimeout = properties->getPropertyAsIntWithDefault(property, invocationTimeout); + if(invocationTimeout < 1 && invocationTimeout != -1) + { + invocationTimeout = -1; + + Warning out(_instance->initializationData().logger); + out << "invalid value for " << property << "`" << properties->getProperty(property) << "'" + << ": defaulting to -1"; + } + } + + property = propertyPrefix + ".Context."; + PropertyDict contexts = properties->getPropertiesForPrefix(property); + for(PropertyDict::const_iterator p = contexts.begin(); p != contexts.end(); ++p) + { + ctx.insert(make_pair(p->first.substr(property.length()), p->second)); + } + } + + // + // Create new reference + // + return new RoutableReference(_instance, + _communicator, + ident, + facet, + mode, + secure, + protocol, + encoding, + endpoints, + adapterId, + locatorInfo, + routerInfo, + collocationOptimized, + cacheConnection, + preferSecure, + endpointSelection, + locatorCacheTimeout, + invocationTimeout, + ctx); +} diff --git a/Sources/IceCpp/RegisterPluginsInit.cpp b/Sources/IceCpp/RegisterPluginsInit.cpp new file mode 100644 index 0000000..9fb8120 --- /dev/null +++ b/Sources/IceCpp/RegisterPluginsInit.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +extern "C" +{ + +Ice::Plugin* createStringConverter(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); +Ice::Plugin* createIceUDP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); +Ice::Plugin* createIceTCP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); +Ice::Plugin* createIceWS(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); + +} + +IceInternal::RegisterPluginsInit::RegisterPluginsInit() +{ + Ice::registerPluginFactory("IceTCP", createIceTCP, true); + + // + // Only include the UDP and WS transport plugins with non-static builds or Gem/PyPI/Swift + // builds. + // +#if !defined(ICE_STATIC_LIBS) || defined(ICE_GEM) || defined(ICE_PYPI) || defined(ICE_SWIFT) + Ice::registerPluginFactory("IceUDP", createIceUDP, true); + Ice::registerPluginFactory("IceWS", createIceWS, true); +#endif + + // + // Also include IceStringConverter in Gem/PyPI builds. + // +#if defined(ICE_GEM) || defined(ICE_PYPI) + Ice::registerPluginFactory("IceStringConverter", createStringConverter, false); +#endif +} diff --git a/Sources/IceCpp/RemoteLogger.cpp b/Sources/IceCpp/RemoteLogger.cpp new file mode 100644 index 0000000..2cc4b56 --- /dev/null +++ b/Sources/IceCpp/RemoteLogger.cpp @@ -0,0 +1,1171 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RemoteLogger.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_Ice_RemoteLogger_ids[2] = +{ + "::Ice::Object", + "::Ice::RemoteLogger" +}; +const ::std::string iceC_Ice_RemoteLogger_ops[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "init", + "log" +}; +const ::std::string iceC_Ice_RemoteLogger_init_name = "init"; +const ::std::string iceC_Ice_RemoteLogger_log_name = "log"; + +const ::IceInternal::DefaultUserExceptionFactoryInit<::Ice::RemoteLoggerAlreadyAttachedException> iceC_Ice_RemoteLoggerAlreadyAttachedException_init("::Ice::RemoteLoggerAlreadyAttachedException"); + +const ::std::string iceC_Ice_LoggerAdmin_ids[2] = +{ + "::Ice::LoggerAdmin", + "::Ice::Object" +}; +const ::std::string iceC_Ice_LoggerAdmin_ops[] = +{ + "attachRemoteLogger", + "detachRemoteLogger", + "getLog", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_Ice_LoggerAdmin_attachRemoteLogger_name = "attachRemoteLogger"; +const ::std::string iceC_Ice_LoggerAdmin_detachRemoteLogger_name = "detachRemoteLogger"; +const ::std::string iceC_Ice_LoggerAdmin_getLog_name = "getLog"; + +} + +Ice::RemoteLoggerAlreadyAttachedException::~RemoteLoggerAlreadyAttachedException() +{ +} + +const ::std::string& +Ice::RemoteLoggerAlreadyAttachedException::ice_staticId() +{ + static const ::std::string typeId = "::Ice::RemoteLoggerAlreadyAttachedException"; + return typeId; +} + +bool +Ice::RemoteLogger::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_RemoteLogger_ids, iceC_Ice_RemoteLogger_ids + 2, s); +} + +::std::vector<::std::string> +Ice::RemoteLogger::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_RemoteLogger_ids[0], &iceC_Ice_RemoteLogger_ids[2]); +} + +::std::string +Ice::RemoteLogger::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::RemoteLogger::ice_staticId() +{ + static const ::std::string typeId = "::Ice::RemoteLogger"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceD_init(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_prefix; + LogMessageSeq iceP_logMessages; + istr->readAll(iceP_prefix, iceP_logMessages); + inS.endReadParams(); + this->init(::std::move(iceP_prefix), ::std::move(iceP_logMessages), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceD_log(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + LogMessage iceP_message; + istr->readAll(iceP_message); + inS.endReadParams(); + this->log(::std::move(iceP_message), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_RemoteLogger_ops, iceC_Ice_RemoteLogger_ops + 6, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_RemoteLogger_ops) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_init(in, current); + } + case 5: + { + return _iceD_log(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +Ice::LoggerAdmin::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LoggerAdmin_ids, iceC_Ice_LoggerAdmin_ids + 2, s); +} + +::std::vector<::std::string> +Ice::LoggerAdmin::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_LoggerAdmin_ids[0], &iceC_Ice_LoggerAdmin_ids[2]); +} + +::std::string +Ice::LoggerAdmin::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LoggerAdmin::ice_staticId() +{ + static const ::std::string typeId = "::Ice::LoggerAdmin"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_attachRemoteLogger(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::shared_ptr iceP_prx; + LogMessageTypeSeq iceP_messageTypes; + StringSeq iceP_traceCategories; + int iceP_messageMax; + istr->readAll(iceP_prx, iceP_messageTypes, iceP_traceCategories, iceP_messageMax); + inS.endReadParams(); + this->attachRemoteLogger(::std::move(iceP_prx), ::std::move(iceP_messageTypes), ::std::move(iceP_traceCategories), iceP_messageMax, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_detachRemoteLogger(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::shared_ptr iceP_prx; + istr->readAll(iceP_prx); + inS.endReadParams(); + bool ret = this->detachRemoteLogger(::std::move(iceP_prx), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_getLog(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + LogMessageTypeSeq iceP_messageTypes; + StringSeq iceP_traceCategories; + int iceP_messageMax; + istr->readAll(iceP_messageTypes, iceP_traceCategories, iceP_messageMax); + inS.endReadParams(); + ::std::string iceP_prefix; + LogMessageSeq ret = this->getLog(::std::move(iceP_messageTypes), ::std::move(iceP_traceCategories), iceP_messageMax, iceP_prefix, current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(iceP_prefix, ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LoggerAdmin_ops, iceC_Ice_LoggerAdmin_ops + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LoggerAdmin_ops) + { + case 0: + { + return _iceD_attachRemoteLogger(in, current); + } + case 1: + { + return _iceD_detachRemoteLogger(in, current); + } + case 2: + { + return _iceD_getLog(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +Ice::RemoteLoggerPrx::_iceI_init(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_prefix, const LogMessageSeq& iceP_logMessages, const Context& context) +{ + outAsync->invoke(iceC_Ice_RemoteLogger_init_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_prefix, iceP_logMessages); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::RemoteLoggerPrx::_iceI_log(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const LogMessage& iceP_message, const Context& context) +{ + outAsync->invoke(iceC_Ice_RemoteLogger_log_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_message); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::RemoteLoggerPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::RemoteLoggerPrx::ice_staticId() +{ + return RemoteLogger::ice_staticId(); +} + +/// \cond INTERNAL +void +Ice::LoggerAdminPrx::_iceI_attachRemoteLogger(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::shared_ptr& iceP_prx, const LogMessageTypeSeq& iceP_messageTypes, const StringSeq& iceP_traceCategories, int iceP_messageMax, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_attachRemoteLogger_name); + outAsync->invoke(iceC_Ice_LoggerAdmin_attachRemoteLogger_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_prx, iceP_messageTypes, iceP_traceCategories, iceP_messageMax); + }, + [](const UserException& ex) + { + try + { + ex.ice_throw(); + } + catch(const RemoteLoggerAlreadyAttachedException&) + { + throw; + } + catch(const UserException&) + { + } + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LoggerAdminPrx::_iceI_detachRemoteLogger(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::shared_ptr& iceP_prx, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_detachRemoteLogger_name); + outAsync->invoke(iceC_Ice_LoggerAdmin_detachRemoteLogger_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_prx); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::LoggerAdminPrx::_iceI_getLog(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const LogMessageTypeSeq& iceP_messageTypes, const StringSeq& iceP_traceCategories, int iceP_messageMax, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_getLog_name); + outAsync->invoke(iceC_Ice_LoggerAdmin_getLog_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_messageTypes, iceP_traceCategories, iceP_messageMax); + }, + nullptr, + [](InputStream* istr) + { + LoggerAdmin::GetLogResult v; + istr->readAll(v.prefix, v.returnValue); + return v; + }); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::LoggerAdminPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::LoggerAdminPrx::ice_staticId() +{ + return LoggerAdmin::ice_staticId(); +} + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_Ice_RemoteLogger_init_name = "init"; + +const ::std::string iceC_Ice_RemoteLogger_log_name = "log"; + +const ::std::string iceC_Ice_LoggerAdmin_attachRemoteLogger_name = "attachRemoteLogger"; + +const ::std::string iceC_Ice_LoggerAdmin_detachRemoteLogger_name = "detachRemoteLogger"; + +const ::std::string iceC_Ice_LoggerAdmin_getLog_name = "getLog"; + +} + +namespace +{ + +const ::IceInternal::DefaultUserExceptionFactoryInit< ::Ice::RemoteLoggerAlreadyAttachedException> iceC_Ice_RemoteLoggerAlreadyAttachedException_init("::Ice::RemoteLoggerAlreadyAttachedException"); + +} + +#ifdef ICE_CPP11_COMPILER +Ice::RemoteLoggerAlreadyAttachedException::~RemoteLoggerAlreadyAttachedException() +{ +} +#else +Ice::RemoteLoggerAlreadyAttachedException::~RemoteLoggerAlreadyAttachedException() throw() +{ +} +#endif + +::std::string +Ice::RemoteLoggerAlreadyAttachedException::ice_id() const +{ + return "::Ice::RemoteLoggerAlreadyAttachedException"; +} + +Ice::RemoteLoggerAlreadyAttachedException* +Ice::RemoteLoggerAlreadyAttachedException::ice_clone() const +{ + return new RemoteLoggerAlreadyAttachedException(*this); +} + +void +Ice::RemoteLoggerAlreadyAttachedException::ice_throw() const +{ + throw *this; +} + +/// \cond STREAM +void +Ice::RemoteLoggerAlreadyAttachedException::_writeImpl(OutputStream* ostr) const +{ + ostr->startSlice("::Ice::RemoteLoggerAlreadyAttachedException", -1, true); + StreamWriter< RemoteLoggerAlreadyAttachedException, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::RemoteLoggerAlreadyAttachedException::_readImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< RemoteLoggerAlreadyAttachedException, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(RemoteLogger* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< RemoteLogger>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new RemoteLogger; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::RemoteLogger::_iceI_begin_init(const ::std::string& iceP_prefix, const ::Ice::LogMessageSeq& iceP_logMessages, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_RemoteLogger_init_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_RemoteLogger_init_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_prefix); + ostr->write(iceP_logMessages); + result->endWriteParams(); + result->invoke(iceC_Ice_RemoteLogger_init_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::RemoteLogger::end_init(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_Ice_RemoteLogger_init_name); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::RemoteLogger::_iceI_begin_log(const ::Ice::LogMessage& iceP_message, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_RemoteLogger_log_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_RemoteLogger_log_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_message); + result->endWriteParams(); + result->invoke(iceC_Ice_RemoteLogger_log_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::RemoteLogger::end_log(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_Ice_RemoteLogger_log_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::RemoteLogger::_newInstance() const +{ + return new RemoteLogger; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::RemoteLogger::ice_staticId() +{ + return ::Ice::RemoteLogger::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(LoggerAdmin* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< LoggerAdmin>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new LoggerAdmin; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::LoggerAdmin::_iceI_begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& iceP_prx, const ::Ice::LogMessageTypeSeq& iceP_messageTypes, const ::Ice::StringSeq& iceP_traceCategories, ::Ice::Int iceP_messageMax, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_attachRemoteLogger_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LoggerAdmin_attachRemoteLogger_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LoggerAdmin_attachRemoteLogger_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_prx); + ostr->write(iceP_messageTypes); + ostr->write(iceP_traceCategories); + ostr->write(iceP_messageMax); + result->endWriteParams(); + result->invoke(iceC_Ice_LoggerAdmin_attachRemoteLogger_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::Ice::LoggerAdmin::end_attachRemoteLogger(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LoggerAdmin_attachRemoteLogger_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::RemoteLoggerAlreadyAttachedException&) + { + throw; + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + result->_readEmptyParams(); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::LoggerAdmin::_iceI_begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& iceP_prx, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_detachRemoteLogger_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LoggerAdmin_detachRemoteLogger_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LoggerAdmin_detachRemoteLogger_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_prx); + result->endWriteParams(); + result->invoke(iceC_Ice_LoggerAdmin_detachRemoteLogger_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +bool +IceProxy::Ice::LoggerAdmin::end_detachRemoteLogger(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LoggerAdmin_detachRemoteLogger_name); + bool ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::LoggerAdmin::_iceI_begin_getLog(const ::Ice::LogMessageTypeSeq& iceP_messageTypes, const ::Ice::StringSeq& iceP_traceCategories, ::Ice::Int iceP_messageMax, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_LoggerAdmin_getLog_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_LoggerAdmin_getLog_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_LoggerAdmin_getLog_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_messageTypes); + ostr->write(iceP_traceCategories); + ostr->write(iceP_messageMax); + result->endWriteParams(); + result->invoke(iceC_Ice_LoggerAdmin_getLog_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::LogMessageSeq +IceProxy::Ice::LoggerAdmin::end_getLog(::std::string& iceP_prefix, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LoggerAdmin_getLog_name); + ::Ice::LogMessageSeq ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_prefix); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +void IceProxy::Ice::LoggerAdmin::_iceI_end_getLog(::std::string& iceP_prefix, ::Ice::LogMessageSeq& ret, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_LoggerAdmin_getLog_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(iceP_prefix); + istr->read(ret); + result->_endReadParams(); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::LoggerAdmin::_newInstance() const +{ + return new LoggerAdmin; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::LoggerAdmin::ice_staticId() +{ + return ::Ice::LoggerAdmin::ice_staticId(); +} + +Ice::RemoteLogger::~RemoteLogger() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(RemoteLogger* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_RemoteLogger_ids[2] = +{ + "::Ice::Object", + "::Ice::RemoteLogger" +}; + +} + +bool +Ice::RemoteLogger::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_RemoteLogger_ids, iceC_Ice_RemoteLogger_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::RemoteLogger::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_RemoteLogger_ids[0], &iceC_Ice_RemoteLogger_ids[2]); +} + +const ::std::string& +Ice::RemoteLogger::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::RemoteLogger::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::RemoteLogger"; + return typeId; +#else + return iceC_Ice_RemoteLogger_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceD_init(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + ::std::string iceP_prefix; + LogMessageSeq iceP_logMessages; + istr->read(iceP_prefix); + istr->read(iceP_logMessages); + inS.endReadParams(); + this->init(iceP_prefix, iceP_logMessages, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceD_log(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + LogMessage iceP_message; + istr->read(iceP_message); + inS.endReadParams(); + this->log(iceP_message, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_RemoteLogger_all[] = +{ + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping", + "init", + "log" +}; + +} + +/// \cond INTERNAL +bool +Ice::RemoteLogger::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_RemoteLogger_all, iceC_Ice_RemoteLogger_all + 6, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_RemoteLogger_all) + { + case 0: + { + return _iceD_ice_id(in, current); + } + case 1: + { + return _iceD_ice_ids(in, current); + } + case 2: + { + return _iceD_ice_isA(in, current); + } + case 3: + { + return _iceD_ice_ping(in, current); + } + case 4: + { + return _iceD_init(in, current); + } + case 5: + { + return _iceD_log(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::RemoteLogger::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< RemoteLogger, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::RemoteLogger::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< RemoteLogger, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(RemoteLoggerPtr& handle, const ObjectPtr& v) +{ + handle = RemoteLoggerPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(RemoteLogger::ice_staticId(), v); + } +} +/// \endcond + +Ice::LoggerAdmin::~LoggerAdmin() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(LoggerAdmin* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LoggerAdmin_ids[2] = +{ + "::Ice::LoggerAdmin", + "::Ice::Object" +}; + +} + +bool +Ice::LoggerAdmin::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_LoggerAdmin_ids, iceC_Ice_LoggerAdmin_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::LoggerAdmin::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_LoggerAdmin_ids[0], &iceC_Ice_LoggerAdmin_ids[2]); +} + +const ::std::string& +Ice::LoggerAdmin::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::LoggerAdmin::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::LoggerAdmin"; + return typeId; +#else + return iceC_Ice_LoggerAdmin_ids[0]; +#endif +} + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_attachRemoteLogger(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + RemoteLoggerPrx iceP_prx; + LogMessageTypeSeq iceP_messageTypes; + StringSeq iceP_traceCategories; + Int iceP_messageMax; + istr->read(iceP_prx); + istr->read(iceP_messageTypes); + istr->read(iceP_traceCategories); + istr->read(iceP_messageMax); + inS.endReadParams(); + this->attachRemoteLogger(iceP_prx, iceP_messageTypes, iceP_traceCategories, iceP_messageMax, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_detachRemoteLogger(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + RemoteLoggerPrx iceP_prx; + istr->read(iceP_prx); + inS.endReadParams(); + bool ret = this->detachRemoteLogger(iceP_prx, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceD_getLog(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + InputStream* istr = inS.startReadParams(); + LogMessageTypeSeq iceP_messageTypes; + StringSeq iceP_traceCategories; + Int iceP_messageMax; + istr->read(iceP_messageTypes); + istr->read(iceP_traceCategories); + istr->read(iceP_messageMax); + inS.endReadParams(); + ::std::string iceP_prefix; + LogMessageSeq ret = this->getLog(iceP_messageTypes, iceP_traceCategories, iceP_messageMax, iceP_prefix, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(iceP_prefix); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_LoggerAdmin_all[] = +{ + "attachRemoteLogger", + "detachRemoteLogger", + "getLog", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +Ice::LoggerAdmin::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_LoggerAdmin_all, iceC_Ice_LoggerAdmin_all + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_LoggerAdmin_all) + { + case 0: + { + return _iceD_attachRemoteLogger(in, current); + } + case 1: + { + return _iceD_detachRemoteLogger(in, current); + } + case 2: + { + return _iceD_getLog(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::LoggerAdmin::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< LoggerAdmin, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::LoggerAdmin::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< LoggerAdmin, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(LoggerAdminPtr& handle, const ObjectPtr& v) +{ + handle = LoggerAdminPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(LoggerAdmin::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/RequestHandler.cpp b/Sources/IceCpp/RequestHandler.cpp new file mode 100644 index 0000000..6d642d1 --- /dev/null +++ b/Sources/IceCpp/RequestHandler.cpp @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(RequestHandler* p) { return p; } +IceUtil::Shared* IceInternal::upCast(CancellationHandler* p) { return p; } +#endif + +RetryException::RetryException(const Ice::LocalException& ex) +{ + ICE_SET_EXCEPTION_FROM_CLONE(_ex, ex.ice_clone()); +} + +RetryException::RetryException(const RetryException& ex) +{ + ICE_SET_EXCEPTION_FROM_CLONE(_ex, ex.get()->ice_clone()); +} + +const Ice::LocalException* +RetryException::get() const +{ + assert(_ex.get()); + return _ex.get(); +} + +RequestHandler::RequestHandler(const ReferencePtr& reference) : + _reference(reference), + _response(reference->getMode() == Reference::ModeTwoway) +{ +} diff --git a/Sources/IceCpp/RequestHandlerFactory.cpp b/Sources/IceCpp/RequestHandlerFactory.cpp new file mode 100644 index 0000000..f50674d --- /dev/null +++ b/Sources/IceCpp/RequestHandlerFactory.cpp @@ -0,0 +1,77 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace IceInternal; + +RequestHandlerFactory::RequestHandlerFactory(const InstancePtr& instance) : _instance(instance) +{ +} + +RequestHandlerPtr +IceInternal::RequestHandlerFactory::getRequestHandler(const RoutableReferencePtr& ref, const Ice::ObjectPrxPtr& proxy) +{ + if(ref->getCollocationOptimized()) + { + Ice::ObjectAdapterPtr adapter = _instance->objectAdapterFactory()->findObjectAdapter(proxy); + if(adapter) + { + return proxy->_setRequestHandler(ICE_MAKE_SHARED(CollocatedRequestHandler, ref, adapter)); + } + } + + ConnectRequestHandlerPtr handler; + bool connect = false; + if(ref->getCacheConnection()) + { + Lock sync(*this); + map::iterator p = _handlers.find(ref); + if(p == _handlers.end()) + { + handler = ICE_MAKE_SHARED(ConnectRequestHandler, ref, proxy); + _handlers.insert(make_pair(ref, handler)); + connect = true; + } + else + { + handler = p->second; + } + } + else + { + handler = ICE_MAKE_SHARED(ConnectRequestHandler, ref, proxy); + connect = true; + } + if(connect) + { +#ifdef ICE_CPP11_MAPPING + ref->getConnection(handler); +#else + ref->getConnection(handler.get()); +#endif + } + return proxy->_setRequestHandler(handler->connect(proxy)); +} + +void +IceInternal::RequestHandlerFactory::removeRequestHandler(const ReferencePtr& ref, const RequestHandlerPtr& handler) +{ + if(ref->getCacheConnection()) + { + Lock sync(*this); + map::iterator p = _handlers.find(ref); + if(p != _handlers.end() && p->second.get() == handler.get()) + { + _handlers.erase(p); + } + } +} diff --git a/Sources/IceCpp/ResponseHandler.cpp b/Sources/IceCpp/ResponseHandler.cpp new file mode 100644 index 0000000..252f57a --- /dev/null +++ b/Sources/IceCpp/ResponseHandler.cpp @@ -0,0 +1,12 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(ResponseHandler* obj) { return obj; } +#endif diff --git a/Sources/IceCpp/RetryQueue.cpp b/Sources/IceCpp/RetryQueue.cpp new file mode 100644 index 0000000..b52a6b5 --- /dev/null +++ b/Sources/IceCpp/RetryQueue.cpp @@ -0,0 +1,157 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(RetryQueue* p) { return p; } + +IceInternal::RetryTask::RetryTask(const InstancePtr& instance, + const RetryQueuePtr& queue, + const ProxyOutgoingAsyncBasePtr& outAsync) : + _instance(instance), + _queue(queue), + _outAsync(outAsync) +{ +} + +void +IceInternal::RetryTask::runTimerTask() +{ + _outAsync->retry(); // Retry again the invocation. + + // + // NOTE: this must be called last, destroy() blocks until all task + // are removed to prevent the client thread pool to be destroyed + // (we still need the client thread pool at this point to call + // exception callbacks with CommunicatorDestroyedException). + // + _queue->remove(ICE_SHARED_FROM_THIS); +} + +void +IceInternal::RetryTask::asyncRequestCanceled(const OutgoingAsyncBasePtr& /*outAsync*/, const Ice::LocalException& ex) +{ + if(_queue->cancel(ICE_SHARED_FROM_THIS)) + { + if(_instance->traceLevels()->retry >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->retryCat); + out << "operation retry canceled\n" << ex; + } + if(_outAsync->exception(ex)) + { + _outAsync->invokeExceptionAsync(); + } + } +} + +void +IceInternal::RetryTask::destroy() +{ + try + { + _outAsync->abort(CommunicatorDestroyedException(__FILE__, __LINE__)); + } + catch(const CommunicatorDestroyedException&) + { + // Abort can throw if there's no callback, ignore. + } +} + +bool +IceInternal::RetryTask::operator<(const RetryTask& rhs) const +{ + return this < &rhs; +} + +IceInternal::RetryQueue::RetryQueue(const InstancePtr& instance) : _instance(instance) +{ +} + +void +IceInternal::RetryQueue::add(const ProxyOutgoingAsyncBasePtr& out, int interval) +{ + Lock sync(*this); + if(!_instance) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + RetryTaskPtr task = ICE_MAKE_SHARED(RetryTask, _instance, this, out); + out->cancelable(task); // This will throw if the request is canceled. + try + { + _instance->timer()->schedule(task, IceUtil::Time::milliSeconds(interval)); + } + catch(const IceUtil::IllegalArgumentException&) // Expected if the communicator destroyed the timer. + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + _requests.insert(task); +} + +void +IceInternal::RetryQueue::destroy() +{ + Lock sync(*this); + assert(_instance); + + set::iterator p = _requests.begin(); + while(p != _requests.end()) + { + if(_instance->timer()->cancel(*p)) + { + (*p)->destroy(); + _requests.erase(p++); + } + else + { + ++p; + } + } + + _instance = 0; + while(!_requests.empty()) + { + wait(); + } +} + +void +IceInternal::RetryQueue::remove(const RetryTaskPtr& task) +{ + Lock sync(*this); + assert(_requests.find(task) != _requests.end()); + _requests.erase(task); + if(!_instance && _requests.empty()) + { + notify(); // If we are destroying the queue, destroy is probably waiting on the queue to be empty. + } +} + +bool +IceInternal::RetryQueue::cancel(const RetryTaskPtr& task) +{ + Lock sync(*this); + if(_requests.erase(task) > 0) + { + if(_instance) + { + return _instance->timer()->cancel(task); + } + else if(_requests.empty()) + { + notify(); // If we are destroying the queue, destroy is probably waiting on the queue to be empty. + } + } + return false; +} diff --git a/Sources/IceCpp/Router.cpp b/Sources/IceCpp/Router.cpp new file mode 100644 index 0000000..46238ad --- /dev/null +++ b/Sources/IceCpp/Router.cpp @@ -0,0 +1,977 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Router.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_Ice_Router_ids[2] = +{ + "::Ice::Object", + "::Ice::Router" +}; +const ::std::string iceC_Ice_Router_ops[] = +{ + "addProxies", + "getClientProxy", + "getServerProxy", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_Ice_Router_getClientProxy_name = "getClientProxy"; +const ::std::string iceC_Ice_Router_getServerProxy_name = "getServerProxy"; +const ::std::string iceC_Ice_Router_addProxies_name = "addProxies"; + +const ::std::string iceC_Ice_RouterFinder_ids[2] = +{ + "::Ice::Object", + "::Ice::RouterFinder" +}; +const ::std::string iceC_Ice_RouterFinder_ops[] = +{ + "getRouter", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_Ice_RouterFinder_getRouter_name = "getRouter"; + +} + +bool +Ice::Router::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Router_ids, iceC_Ice_Router_ids + 2, s); +} + +::std::vector<::std::string> +Ice::Router::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_Router_ids[0], &iceC_Ice_Router_ids[2]); +} + +::std::string +Ice::Router::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Router::ice_staticId() +{ + static const ::std::string typeId = "::Ice::Router"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::Router::_iceD_getClientProxy(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + inS.readEmptyParams(); + Ice::optional iceP_hasRoutingTable; + ::std::shared_ptr ret = this->getClientProxy(iceP_hasRoutingTable, current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + ostr->writeAll({1}, iceP_hasRoutingTable); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Router::_iceD_getServerProxy(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + inS.readEmptyParams(); + ::std::shared_ptr ret = this->getServerProxy(current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Router::_iceD_addProxies(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ObjectProxySeq iceP_proxies; + istr->readAll(iceP_proxies); + inS.endReadParams(); + ObjectProxySeq ret = this->addProxies(::std::move(iceP_proxies), current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Router::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Router_ops, iceC_Ice_Router_ops + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Router_ops) + { + case 0: + { + return _iceD_addProxies(in, current); + } + case 1: + { + return _iceD_getClientProxy(in, current); + } + case 2: + { + return _iceD_getServerProxy(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +Ice::RouterFinder::ice_isA(::std::string s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_RouterFinder_ids, iceC_Ice_RouterFinder_ids + 2, s); +} + +::std::vector<::std::string> +Ice::RouterFinder::ice_ids(const Current&) const +{ + return ::std::vector<::std::string>(&iceC_Ice_RouterFinder_ids[0], &iceC_Ice_RouterFinder_ids[2]); +} + +::std::string +Ice::RouterFinder::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::RouterFinder::ice_staticId() +{ + static const ::std::string typeId = "::Ice::RouterFinder"; + return typeId; +} + +/// \cond INTERNAL +bool +Ice::RouterFinder::_iceD_getRouter(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + inS.readEmptyParams(); + ::std::shared_ptr ret = this->getRouter(current); + auto ostr = inS.startWriteParams(); + ostr->writeAll(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::RouterFinder::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_RouterFinder_ops, iceC_Ice_RouterFinder_ops + 5, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_RouterFinder_ops) + { + case 0: + { + return _iceD_getRouter(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +Ice::RouterPrx::_iceI_getClientProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Router_getClientProxy_name); + outAsync->invoke(iceC_Ice_Router_getClientProxy_name, ::Ice::OperationMode::Nonmutating, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr, + [](InputStream* istr) + { + Router::GetClientProxyResult v; + istr->readAll(v.returnValue); + istr->readAll({1}, v.hasRoutingTable); + return v; + }); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::RouterPrx::_iceI_getServerProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>& outAsync, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Router_getServerProxy_name); + outAsync->invoke(iceC_Ice_Router_getServerProxy_name, ::Ice::OperationMode::Nonmutating, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::RouterPrx::_iceI_addProxies(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::Ice::ObjectProxySeq>>& outAsync, const ObjectProxySeq& iceP_proxies, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_Router_addProxies_name); + outAsync->invoke(iceC_Ice_Router_addProxies_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](OutputStream* ostr) + { + ostr->writeAll(iceP_proxies); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::RouterPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::RouterPrx::ice_staticId() +{ + return Router::ice_staticId(); +} + +/// \cond INTERNAL +void +Ice::RouterFinderPrx::_iceI_getRouter(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::RouterPrx>>>& outAsync, const Context& context) +{ + _checkTwowayOnly(iceC_Ice_RouterFinder_getRouter_name); + outAsync->invoke(iceC_Ice_RouterFinder_getRouter_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + nullptr, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +Ice::RouterFinderPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +Ice::RouterFinderPrx::ice_staticId() +{ + return RouterFinder::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_Ice_Router_getClientProxy_name = "getClientProxy"; + +const ::std::string iceC_Ice_Router_getServerProxy_name = "getServerProxy"; + +const ::std::string iceC_Ice_Router_addProxies_name = "addProxies"; + +const ::std::string iceC_Ice_RouterFinder_getRouter_name = "getRouter"; + +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(Router* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Router>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Router; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::Router::_iceI_begin_getClientProxy(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Router_getClientProxy_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Router_getClientProxy_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Router_getClientProxy_name, ::Ice::Nonmutating, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_Router_getClientProxy_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::ObjectPrx +IceProxy::Ice::Router::end_getClientProxy(IceUtil::Optional& iceP_hasRoutingTable, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Router_getClientProxy_name); + ::Ice::ObjectPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + istr->read(1, iceP_hasRoutingTable); + result->_endReadParams(); + return ret; +} + +void IceProxy::Ice::Router::_iceI_end_getClientProxy(IceUtil::Optional& iceP_hasRoutingTable, ::Ice::ObjectPrxPtr& ret, const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Router_getClientProxy_name); + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + istr->read(1, iceP_hasRoutingTable); + result->_endReadParams(); +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Router::_iceI_begin_getServerProxy(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Router_getServerProxy_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Router_getServerProxy_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Router_getServerProxy_name, ::Ice::Nonmutating, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_Router_getServerProxy_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::ObjectPrx +IceProxy::Ice::Router::end_getServerProxy(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Router_getServerProxy_name); + ::Ice::ObjectPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +::Ice::AsyncResultPtr +IceProxy::Ice::Router::_iceI_begin_addProxies(const ::Ice::ObjectProxySeq& iceP_proxies, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_Router_addProxies_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_Router_addProxies_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_Router_addProxies_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_proxies); + result->endWriteParams(); + result->invoke(iceC_Ice_Router_addProxies_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::ObjectProxySeq +IceProxy::Ice::Router::end_addProxies(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_Router_addProxies_name); + ::Ice::ObjectProxySeq ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::Router::_newInstance() const +{ + return new Router; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::Router::ice_staticId() +{ + return ::Ice::Router::ice_staticId(); +} + +/// \cond INTERNAL +ICE_API ::IceProxy::Ice::Object* ::IceProxy::Ice::upCast(RouterFinder* p) { return p; } + +void +::IceProxy::Ice::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< RouterFinder>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new RouterFinder; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::Ice::RouterFinder::_iceI_begin_getRouter(const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + _checkTwowayOnly(iceC_Ice_RouterFinder_getRouter_name, sync); + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_Ice_RouterFinder_getRouter_name, del, cookie, sync); + try + { + result->prepare(iceC_Ice_RouterFinder_getRouter_name, ::Ice::Normal, context); + result->writeEmptyParams(); + result->invoke(iceC_Ice_RouterFinder_getRouter_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +::Ice::RouterPrx +IceProxy::Ice::RouterFinder::end_getRouter(const ::Ice::AsyncResultPtr& result) +{ + ::Ice::AsyncResult::_check(result, this, iceC_Ice_RouterFinder_getRouter_name); + ::Ice::RouterPrx ret; + if(!result->_waitForResponse()) + { + try + { + result->_throwUserException(); + } + catch(const ::Ice::UserException& ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_id()); + } + } + ::Ice::InputStream* istr = result->_startReadParams(); + istr->read(ret); + result->_endReadParams(); + return ret; +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::Ice::RouterFinder::_newInstance() const +{ + return new RouterFinder; +} +/// \endcond + +const ::std::string& +IceProxy::Ice::RouterFinder::ice_staticId() +{ + return ::Ice::RouterFinder::ice_staticId(); +} + +Ice::Router::~Router() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(Router* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Router_ids[2] = +{ + "::Ice::Object", + "::Ice::Router" +}; + +} + +bool +Ice::Router::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_Router_ids, iceC_Ice_Router_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::Router::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_Router_ids[0], &iceC_Ice_Router_ids[2]); +} + +const ::std::string& +Ice::Router::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::Router::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::Router"; + return typeId; +#else + return iceC_Ice_Router_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +Ice::Router::_iceD_getClientProxy(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + inS.readEmptyParams(); + IceUtil::Optional iceP_hasRoutingTable; + ObjectPrx ret = this->getClientProxy(iceP_hasRoutingTable, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + ostr->write(1, iceP_hasRoutingTable); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Router::_iceD_getServerProxy(::IceInternal::Incoming& inS, const Current& current) const +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + inS.readEmptyParams(); + ObjectPrx ret = this->getServerProxy(current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +Ice::Router::_iceD_addProxies(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + InputStream* istr = inS.startReadParams(); + ObjectProxySeq iceP_proxies; + istr->read(iceP_proxies); + inS.endReadParams(); + ObjectProxySeq ret = this->addProxies(iceP_proxies, current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_Router_all[] = +{ + "addProxies", + "getClientProxy", + "getServerProxy", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +Ice::Router::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_Router_all, iceC_Ice_Router_all + 7, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_Router_all) + { + case 0: + { + return _iceD_addProxies(in, current); + } + case 1: + { + return _iceD_getClientProxy(in, current); + } + case 2: + { + return _iceD_getServerProxy(in, current); + } + case 3: + { + return _iceD_ice_id(in, current); + } + case 4: + { + return _iceD_ice_ids(in, current); + } + case 5: + { + return _iceD_ice_isA(in, current); + } + case 6: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::Router::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< Router, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::Router::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< Router, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(RouterPtr& handle, const ObjectPtr& v) +{ + handle = RouterPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Router::ice_staticId(), v); + } +} +/// \endcond + +Ice::RouterFinder::~RouterFinder() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::Object* Ice::upCast(RouterFinder* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_RouterFinder_ids[2] = +{ + "::Ice::Object", + "::Ice::RouterFinder" +}; + +} + +bool +Ice::RouterFinder::ice_isA(const ::std::string& s, const Current&) const +{ + return ::std::binary_search(iceC_Ice_RouterFinder_ids, iceC_Ice_RouterFinder_ids + 2, s); +} + +::std::vector< ::std::string> +Ice::RouterFinder::ice_ids(const Current&) const +{ + return ::std::vector< ::std::string>(&iceC_Ice_RouterFinder_ids[0], &iceC_Ice_RouterFinder_ids[2]); +} + +const ::std::string& +Ice::RouterFinder::ice_id(const Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +Ice::RouterFinder::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::Ice::RouterFinder"; + return typeId; +#else + return iceC_Ice_RouterFinder_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +Ice::RouterFinder::_iceD_getRouter(::IceInternal::Incoming& inS, const Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + inS.readEmptyParams(); + RouterPrx ret = this->getRouter(current); + OutputStream* ostr = inS.startWriteParams(); + ostr->write(ret); + inS.endWriteParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_Ice_RouterFinder_all[] = +{ + "getRouter", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +Ice::RouterFinder::_iceDispatch(::IceInternal::Incoming& in, const Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_Ice_RouterFinder_all, iceC_Ice_RouterFinder_all + 5, current.operation); + if(r.first == r.second) + { + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_Ice_RouterFinder_all) + { + case 0: + { + return _iceD_getRouter(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +Ice::RouterFinder::_iceWriteImpl(OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + StreamWriter< RouterFinder, OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +Ice::RouterFinder::_iceReadImpl(InputStream* istr) +{ + istr->startSlice(); + StreamReader< RouterFinder, InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +Ice::_icePatchObjectPtr(RouterFinderPtr& handle, const ObjectPtr& v) +{ + handle = RouterFinderPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(RouterFinder::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/RouterF.cpp b/Sources/IceCpp/RouterF.cpp new file mode 100644 index 0000000..87971c5 --- /dev/null +++ b/Sources/IceCpp/RouterF.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RouterF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/RouterInfo.cpp b/Sources/IceCpp/RouterInfo.cpp new file mode 100644 index 0000000..82de463 --- /dev/null +++ b/Sources/IceCpp/RouterInfo.cpp @@ -0,0 +1,379 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include // For ice_connection()->timeout(). +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(RouterManager* p) { return p; } +IceUtil::Shared* IceInternal::upCast(RouterInfo* p) { return p; } + +IceInternal::RouterManager::RouterManager() : + _tableHint(_table.end()) +{ +} + +void +IceInternal::RouterManager::destroy() +{ + IceUtil::Mutex::Lock sync(*this); +#ifdef ICE_CPP11_COMPILER + for_each(_table.begin(), _table.end(), + [](const pair it) + { + it.second->destroy(); + }); +#else + for_each(_table.begin(), _table.end(), Ice::secondVoidMemFun(&RouterInfo::destroy)); +#endif + _table.clear(); + _tableHint = _table.end(); +} + +RouterInfoPtr +IceInternal::RouterManager::get(const RouterPrxPtr& rtr) +{ + if(!rtr) + { + return 0; + } + + RouterPrxPtr router = rtr->ice_router(0); // The router cannot be routed. + + IceUtil::Mutex::Lock sync(*this); + + RouterInfoTable::iterator p = _table.end(); + + if(_tableHint != _table.end()) + { + if(targetEqualTo(_tableHint->first, router)) + { + p = _tableHint; + } + } + + if(p == _table.end()) + { + p = _table.find(router); + } + + if(p == _table.end()) + { + _tableHint = _table.insert(_tableHint, pair(router, new RouterInfo(router))); + } + else + { + _tableHint = p; + } + + return _tableHint->second; +} + +RouterInfoPtr +IceInternal::RouterManager::erase(const RouterPrxPtr& rtr) +{ + RouterInfoPtr info; + if(rtr) + { + RouterPrxPtr router = ICE_UNCHECKED_CAST(RouterPrx, rtr->ice_router(ICE_NULLPTR)); // The router cannot be routed. + IceUtil::Mutex::Lock sync(*this); + + RouterInfoTable::iterator p = _table.end(); + if(_tableHint != _table.end() && targetEqualTo(_tableHint->first, router)) + { + p = _tableHint; + _tableHint = _table.end(); + } + + if(p == _table.end()) + { + p = _table.find(router); + } + + if(p != _table.end()) + { + info = p->second; + _table.erase(p); + } + } + + return info; +} + +IceInternal::RouterInfo::RouterInfo(const RouterPrxPtr& router) : _router(router), _hasRoutingTable(false) +{ + assert(_router); +} + +void +IceInternal::RouterInfo::destroy() +{ + IceUtil::Mutex::Lock sync(*this); + + _clientEndpoints.clear(); + _adapter = 0; + _identities.clear(); +} + +bool +IceInternal::RouterInfo::operator==(const RouterInfo& rhs) const +{ + return Ice::targetEqualTo(_router, rhs._router); +} + +bool +IceInternal::RouterInfo::operator<(const RouterInfo& rhs) const +{ + return Ice::targetLess(_router, rhs._router); +} + +vector +IceInternal::RouterInfo::getClientEndpoints() +{ + { + IceUtil::Mutex::Lock sync(*this); + if(!_clientEndpoints.empty()) + { + return _clientEndpoints; + } + } + + IceUtil::Optional hasRoutingTable; + Ice::ObjectPrxPtr proxy = _router->getClientProxy(hasRoutingTable); + return setClientEndpoints(proxy, hasRoutingTable ? hasRoutingTable.value() : true); +} + +void +IceInternal::RouterInfo::getClientProxyResponse(const Ice::ObjectPrxPtr& proxy, + const IceUtil::Optional& hasRoutingTable, + const GetClientEndpointsCallbackPtr& callback) +{ + callback->setEndpoints(setClientEndpoints(proxy, hasRoutingTable ? hasRoutingTable.value() : true)); +} + +void +IceInternal::RouterInfo::getClientProxyException(const Ice::Exception& ex, + const GetClientEndpointsCallbackPtr& callback) +{ + callback->setException(dynamic_cast(ex)); +} + +void +IceInternal::RouterInfo::getClientEndpoints(const GetClientEndpointsCallbackPtr& callback) +{ + vector clientEndpoints; + { + IceUtil::Mutex::Lock sync(*this); + clientEndpoints = _clientEndpoints; + } + + if(!clientEndpoints.empty()) + { + callback->setEndpoints(clientEndpoints); + return; + } + +#ifdef ICE_CPP11_MAPPING + RouterInfoPtr self = this; + _router->getClientProxyAsync( + [self, callback](const Ice::ObjectPrxPtr& proxy, Ice::optional hasRoutingTable) + { + self->getClientProxyResponse(proxy, hasRoutingTable, callback); + }, + [self, callback](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Ice::Exception& ex) + { + self->getClientProxyException(ex, callback); + } + }); +#else + _router->begin_getClientProxy(newCallback_Router_getClientProxy(this, + &RouterInfo::getClientProxyResponse, + &RouterInfo::getClientProxyException), + callback); +#endif +} + +vector +IceInternal::RouterInfo::getServerEndpoints() +{ + Ice::ObjectPrxPtr serverProxy = _router->getServerProxy(); + if(!serverProxy) + { + throw NoEndpointException(__FILE__, __LINE__); + } + serverProxy = serverProxy->ice_router(0); // The server proxy cannot be routed. + return serverProxy->_getReference()->getEndpoints(); +} + +void +IceInternal::RouterInfo::addProxyResponse(const Ice::ObjectProxySeq& proxies, const AddProxyCookiePtr& cookie) +{ + addAndEvictProxies(cookie->proxy(), proxies); + cookie->cb()->addedProxy(); +} + +void +IceInternal::RouterInfo::addProxyException(const Ice::Exception& ex, const AddProxyCookiePtr& cookie) +{ + cookie->cb()->setException(dynamic_cast(ex)); +} + +bool +IceInternal::RouterInfo::addProxy(const Ice::ObjectPrxPtr& proxy, const AddProxyCallbackPtr& callback) +{ + assert(proxy); + { + IceUtil::Mutex::Lock sync(*this); + if(!_hasRoutingTable) + { + return true; // The router implementation doesn't maintain a routing table. + } + else if(_identities.find(proxy->ice_getIdentity()) != _identities.end()) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return true; + } + } + + Ice::ObjectProxySeq proxies; + proxies.push_back(proxy); + AddProxyCookiePtr cookie = new AddProxyCookie(callback, proxy); + +#ifdef ICE_CPP11_MAPPING + RouterInfoPtr self = this; + _router->addProxiesAsync(proxies, + [self, cookie](const Ice::ObjectProxySeq& p) + { + self->addProxyResponse(p, cookie); + }, + [self, cookie](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Ice::Exception& ex) + { + self->addProxyException(ex, cookie); + } + }); +#else + _router->begin_addProxies(proxies, + newCallback_Router_addProxies(this, + &RouterInfo::addProxyResponse, + &RouterInfo::addProxyException), + cookie); +#endif + return false; +} + +void +IceInternal::RouterInfo::setAdapter(const ObjectAdapterPtr& adapter) +{ + IceUtil::Mutex::Lock sync(*this); + _adapter = adapter; +} + +ObjectAdapterPtr +IceInternal::RouterInfo::getAdapter() const +{ + IceUtil::Mutex::Lock sync(*this); + return _adapter; +} + +void +IceInternal::RouterInfo::clearCache(const ReferencePtr& ref) +{ + IceUtil::Mutex::Lock sync(*this); + _identities.erase(ref->getIdentity()); +} + +vector +IceInternal::RouterInfo::setClientEndpoints(const Ice::ObjectPrxPtr& proxy, bool hasRoutingTable) +{ + IceUtil::Mutex::Lock sync(*this); + if(_clientEndpoints.empty()) + { + _hasRoutingTable = hasRoutingTable; + if(!proxy) + { + // + // If getClientProxy() return nil, use router endpoints. + // + _clientEndpoints = _router->_getReference()->getEndpoints(); + } + else + { + Ice::ObjectPrxPtr clientProxy = proxy->ice_router(0); // The client proxy cannot be routed. + + // + // In order to avoid creating a new connection to the router, + // we must use the same timeout as the already existing + // connection. + // + if(_router->ice_getConnection()) + { + clientProxy = clientProxy->ice_timeout(_router->ice_getConnection()->timeout()); + } + + _clientEndpoints = clientProxy->_getReference()->getEndpoints(); + } + } + return _clientEndpoints; +} + +void +IceInternal::RouterInfo::addAndEvictProxies(const Ice::ObjectPrxPtr& proxy, const Ice::ObjectProxySeq& evictedProxies) +{ + IceUtil::Mutex::Lock sync(*this); + + // + // Check if the proxy hasn't already been evicted by a concurrent addProxies call. + // If it's the case, don't add it to our local map. + // + multiset::iterator p = _evictedIdentities.find(proxy->ice_getIdentity()); + if(p != _evictedIdentities.end()) + { + _evictedIdentities.erase(p); + } + else + { + // + // If we successfully added the proxy to the router, + // we add it to our local map. + // + _identities.insert(proxy->ice_getIdentity()); + } + + // + // We also must remove whatever proxies the router evicted. + // + for(Ice::ObjectProxySeq::const_iterator q = evictedProxies.begin(); q != evictedProxies.end(); ++q) + { + if(_identities.erase((*q)->ice_getIdentity()) == 0) + { + // + // It's possible for the proxy to not have been + // added yet in the local map if two threads + // concurrently call addProxies. + // + _evictedIdentities.insert((*q)->ice_getIdentity()); + } + } +} diff --git a/Sources/IceCpp/SHA1.cpp b/Sources/IceCpp/SHA1.cpp new file mode 100644 index 0000000..8d0ed34 --- /dev/null +++ b/Sources/IceCpp/SHA1.cpp @@ -0,0 +1,169 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if defined(_WIN32) +# include +# include +#elif defined(__APPLE__) +# include +#else +# include +# // Ignore OpenSSL 3.0 deprecation warning +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +using namespace std; +using namespace IceUtil; + +namespace IceInternal +{ + +class SHA1::Hasher +{ +public: + + Hasher(); +#ifdef _WIN32 + ~Hasher(); +#endif + + void update(const unsigned char*, std::size_t); + void finalize(std::vector&); + +private: + + // noncopyable + Hasher(const Hasher&); + Hasher operator=(const Hasher&); + +#if defined (_WIN32) + HCRYPTPROV _ctx; + HCRYPTHASH _hash; +#elif defined(__APPLE__) + CC_SHA1_CTX _ctx; +#else + SHA_CTX _ctx; +#endif +}; + +} + +#if defined(_WIN32) + +namespace +{ +const int SHA_DIGEST_LENGTH = 20; +} + +IceInternal::SHA1::Hasher::Hasher() : + _ctx(0), + _hash(0) +{ + if(!CryptAcquireContext(&_ctx, 0, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + throw IceUtil::SyscallException(__FILE__, __LINE__, GetLastError()); + } + + if(!CryptCreateHash(_ctx, CALG_SHA1, 0, 0, &_hash)) + { + throw IceUtil::SyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +IceInternal::SHA1::Hasher::~Hasher() +{ + if(_hash) + { + CryptDestroyHash(_hash); + } + + if(_ctx) + { + CryptReleaseContext(_ctx, 0); + } +} +#elif defined(__APPLE__) +IceInternal::SHA1::Hasher::Hasher() +{ + CC_SHA1_Init(&_ctx); +} +#else +IceInternal::SHA1::Hasher::Hasher() +{ + SHA1_Init(&_ctx); +} +#endif + +void +IceInternal::SHA1::Hasher::update(const unsigned char* data, size_t length) +{ +#if defined(_WIN32) + if(!CryptHashData(_hash, data, static_cast(length), 0)) + { + throw IceUtil::SyscallException(__FILE__, __LINE__, GetLastError()); + } +#elif defined(__APPLE__) + CC_SHA1_Update(&_ctx, reinterpret_cast(data), static_cast(length)); +#else + SHA1_Update(&_ctx, reinterpret_cast(data), length); +#endif +} + +void +IceInternal::SHA1::Hasher::finalize(vector& md) +{ +#if defined(_WIN32) + md.resize(SHA_DIGEST_LENGTH); + DWORD length = SHA_DIGEST_LENGTH; + if(!CryptGetHashParam(_hash, HP_HASHVAL, &md[0], &length, 0)) + { + throw IceUtil::SyscallException(__FILE__, __LINE__, GetLastError()); + } +#elif defined(__APPLE__) + md.resize(CC_SHA1_DIGEST_LENGTH); + CC_SHA1_Final(&md[0], &_ctx); +#else + md.resize(SHA_DIGEST_LENGTH); + SHA1_Final(&md[0], &_ctx); +#endif +} + +IceInternal::SHA1::SHA1() : + _hasher(new Hasher()) +{ +} + +IceInternal::SHA1::~SHA1() +{ +} + +void +IceInternal::SHA1::update(const unsigned char* data, std::size_t length) +{ + _hasher->update(data, length); +} + +void +IceInternal::SHA1::finalize(std::vector& md) +{ + _hasher->finalize(md); +} + +void +IceInternal::sha1(const unsigned char* data, size_t length, vector& md) +{ +#if defined(_WIN32) + SHA1 hasher; + hasher.update(data, length); + hasher.finalize(md); +#elif defined(__APPLE__) + md.resize(CC_SHA1_DIGEST_LENGTH); + CC_SHA1(&data[0], static_cast(length), &md[0]); +#else + md.resize(SHA_DIGEST_LENGTH); + ::SHA1(&data[0], length, &md[0]); +#endif +} diff --git a/Sources/IceCpp/Selector.cpp b/Sources/IceCpp/Selector.cpp new file mode 100644 index 0000000..c013008 --- /dev/null +++ b/Sources/IceCpp/Selector.cpp @@ -0,0 +1,1525 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +#ifdef ICE_USE_CFSTREAM +# include +# include +#endif + +using namespace std; +using namespace IceInternal; + +#if defined(ICE_USE_KQUEUE) +namespace +{ +struct timespec zeroTimeout = { 0, 0 }; +} +#endif + +#if defined(ICE_USE_IOCP) + +Selector::Selector(const InstancePtr& instance) : _instance(instance) +{ +} + +Selector::~Selector() +{ +} + +#ifdef ICE_USE_IOCP +void +Selector::setup(int sizeIO) +{ + _handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, ICE_NULLPTR, 0, sizeIO); + if(_handle == ICE_NULLPTR) + { + throw Ice::SocketException(__FILE__, __LINE__, GetLastError()); + } +} +#endif + +void +Selector::destroy() +{ +#ifdef ICE_USE_IOCP + CloseHandle(_handle); +#endif +} + +void +Selector::initialize(EventHandler* handler) +{ + if(!handler->getNativeInfo()) + { + return; + } + +#ifdef ICE_USE_IOCP + SOCKET socket = handler->getNativeInfo()->fd(); + if(socket != INVALID_SOCKET) + { + if(CreateIoCompletionPort(reinterpret_cast(socket), + _handle, + reinterpret_cast(handler), + 0) == ICE_NULLPTR) + { + throw Ice::SocketException(__FILE__, __LINE__, GetLastError()); + } + } + handler->getNativeInfo()->initialize(_handle, reinterpret_cast(handler)); +#else + EventHandlerPtr h = ICE_GET_SHARED_FROM_THIS(handler); + handler->getNativeInfo()->setCompletedHandler( + ref new SocketOperationCompletedHandler( + [=](int operation) + { + // + // Use the reference counted handler to ensure it's not + // destroyed as long as the callback lambda exists. + // + completed(h.get(), static_cast(operation)); + })); +#endif +} + +void +Selector::update(EventHandler* handler, SocketOperation remove, SocketOperation add) +{ + handler->_registered = static_cast(handler->_registered & ~remove); + handler->_registered = static_cast(handler->_registered | add); + if(add & SocketOperationRead && !(handler->_pending & SocketOperationRead)) + { + handler->_pending = static_cast(handler->_pending | SocketOperationRead); + completed(handler, SocketOperationRead); // Start an asynchrnous read + } + else if(add & SocketOperationWrite && !(handler->_pending & SocketOperationWrite)) + { + handler->_pending = static_cast(handler->_pending | SocketOperationWrite); + completed(handler, SocketOperationWrite); // Start an asynchrnous write + } +} + +void +Selector::finish(IceInternal::EventHandler* handler) +{ + handler->_registered = SocketOperationNone; + handler->_finish = false; // Ensures that finished() is only called once on the event handler. +} + +void +Selector::ready(EventHandler* handler, SocketOperation status, bool value) +{ + if(((handler->_ready & status) != 0) == value) + { + return; // Nothing to do if ready state already correctly set. + } + + if(value) + { + handler->_ready = static_cast(handler->_ready | status); + } + else + { + handler->_ready = static_cast(handler->_ready & ~status); + } +} + +EventHandler* +#ifdef ICE_USE_IOCP +Selector::getNextHandler(SocketOperation& status, DWORD& count, int& error, int timeout) +#else +Selector::getNextHandler(SocketOperation& status, int timeout) +#endif +{ +#ifdef ICE_USE_IOCP + ULONG_PTR key; + LPOVERLAPPED ol; + error = ERROR_SUCCESS; + + if(!GetQueuedCompletionStatus(_handle, &count, &key, &ol, timeout > 0 ? timeout * 1000 : INFINITE)) + { + int err = WSAGetLastError(); + if(ol == 0) + { + if(err == WAIT_TIMEOUT) + { + throw SelectorTimeoutException(); + } + else + { + Ice::SocketException ex(__FILE__, __LINE__, err); + Ice::Error out(_instance->initializationData().logger); + out << "couldn't dequeue packet from completion port:\n" << ex; + IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(5)); // Sleep 5s to avoid looping + } + } + AsyncInfo* info = static_cast(ol); + if(info) + { + status = info->status; + } + count = 0; + error = WSAGetLastError(); + return reinterpret_cast(key); + } + + AsyncInfo* info = static_cast(ol); + if(info) + { + status = info->status; + } + else + { + status = reinterpret_cast(key)->_ready; + } + return reinterpret_cast(key); +#else + IceUtil::Monitor::Lock lock(_monitor); + while(_events.empty()) + { + if(timeout > 0) + { + _monitor.timedWait(IceUtil::Time::seconds(timeout)); + if(_events.empty()) + { + throw SelectorTimeoutException(); + } + } + else + { + _monitor.wait(); + } + } + assert(!_events.empty()); + IceInternal::EventHandlerPtr handler = _events.front().handler; + const SelectEvent& event = _events.front(); + status = event.status; + _events.pop_front(); + return handler.get(); +#endif +} + +void +Selector::completed(EventHandler* handler, SocketOperation op) +{ +#ifdef ICE_USE_IOCP + AsyncInfo* info = 0; + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(nativeInfo) + { + info = nativeInfo->getAsyncInfo(op); + } + if(!PostQueuedCompletionStatus(_handle, 0, reinterpret_cast(handler), info)) + { + throw Ice::SocketException(__FILE__, __LINE__, GetLastError()); + } +#else + IceUtil::Monitor::Lock lock(_monitor); + _events.push_back(SelectEvent(handler->shared_from_this(), op)); + _monitor.notify(); +#endif +} + +#elif defined(ICE_USE_KQUEUE) || defined(ICE_USE_EPOLL) || defined(ICE_USE_SELECT) || defined(ICE_USE_POLL) + +Selector::Selector(const InstancePtr& instance) : _instance(instance), _interrupted(false) +{ + SOCKET fds[2]; + createPipe(fds); + _fdIntrRead = fds[0]; + _fdIntrWrite = fds[1]; + _selecting = false; + +#if defined(ICE_USE_EPOLL) + _events.resize(256); + _queueFd = epoll_create(1); + if(_queueFd < 0) + { + throw Ice::SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + + epoll_event event; + memset(&event, 0, sizeof(epoll_event)); + event.data.ptr = 0; + event.events = EPOLLIN; + if(epoll_ctl(_queueFd, EPOLL_CTL_ADD, _fdIntrRead, &event) != 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_KQUEUE) + _events.resize(256); + _queueFd = kqueue(); + if(_queueFd < 0) + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + struct kevent ev; + EV_SET(&ev, _fdIntrRead, EVFILT_READ, EV_ADD, 0, 0, 0); + int rs = kevent(_queueFd, &ev, 1, 0, 0, 0); + if(rs < 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_SELECT) + FD_ZERO(&_readFdSet); + FD_ZERO(&_writeFdSet); + FD_ZERO(&_errorFdSet); + FD_SET(_fdIntrRead, &_readFdSet); +#else + struct pollfd pollFd; + pollFd.fd = _fdIntrRead; + pollFd.events = POLLIN; + _pollFdSet.push_back(pollFd); +#endif +} + +Selector::~Selector() +{ +} + +void +Selector::destroy() +{ +#if defined(ICE_USE_KQUEUE) || defined(ICE_USE_EPOLL) + try + { + closeSocket(_queueFd); + } + catch(const Ice::LocalException& ex) + { + Ice::Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } +#endif + + try + { + closeSocket(_fdIntrWrite); + } + catch(const Ice::LocalException& ex) + { + Ice::Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } + + try + { + closeSocket(_fdIntrRead); + } + catch(const Ice::LocalException& ex) + { + Ice::Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } +} + +void +Selector::update(EventHandler* handler, SocketOperation remove, SocketOperation add) +{ + SocketOperation previous = handler->_registered; + handler->_registered = static_cast(handler->_registered & ~remove); + handler->_registered = static_cast(handler->_registered | add); + if(previous == handler->_registered) + { + return; + } + checkReady(handler); + + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(nativeInfo && nativeInfo->fd() != INVALID_SOCKET) + { + updateSelectorForEventHandler(handler, remove, add); + } +} + +void +Selector::enable(EventHandler* handler, SocketOperation status) +{ + if(!(handler->_disabled & status)) + { + return; + } + handler->_disabled = static_cast(handler->_disabled & ~status); + checkReady(handler); + + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(!nativeInfo || nativeInfo->fd() == INVALID_SOCKET) + { + return; + } + + if(handler->_registered & status) + { +#if defined(ICE_USE_EPOLL) + SOCKET fd = nativeInfo->fd(); + SocketOperation previous = static_cast(handler->_registered & ~(handler->_disabled | status)); + SocketOperation newStatus = static_cast(handler->_registered & ~handler->_disabled); + epoll_event event; + memset(&event, 0, sizeof(epoll_event)); + event.data.ptr = handler; + if(newStatus & SocketOperationRead) + { + event.events |= EPOLLIN; + } + if(newStatus & SocketOperationWrite) + { + event.events |= EPOLLOUT; + } + if(epoll_ctl(_queueFd, previous ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &event) != 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_KQUEUE) + struct kevent ev; + SOCKET fd = handler->getNativeInfo()->fd(); + EV_SET(&ev, fd, status == SocketOperationRead ? EVFILT_READ : EVFILT_WRITE, EV_ENABLE, 0, 0, handler); + _changes.push_back(ev); + if(_selecting) + { + updateSelector(); + } +#else + _changes.push_back(make_pair(handler, static_cast(handler->_registered & ~handler->_disabled))); + wakeup(); +#endif + } +} + +void +Selector::disable(EventHandler* handler, SocketOperation status) +{ + if(handler->_disabled & status) + { + return; + } + handler->_disabled = static_cast(handler->_disabled | status); + checkReady(handler); + + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(!nativeInfo || nativeInfo->fd() == INVALID_SOCKET) + { + return; + } + + if(handler->_registered & status) + { +#if defined(ICE_USE_EPOLL) + SOCKET fd = nativeInfo->fd(); + SocketOperation newStatus = static_cast(handler->_registered & ~handler->_disabled); + epoll_event event; + memset(&event, 0, sizeof(epoll_event)); + event.data.ptr = handler; + if(newStatus & SocketOperationRead) + { + event.events |= EPOLLIN; + } + if(newStatus & SocketOperationWrite) + { + event.events |= EPOLLOUT; + } + if(epoll_ctl(_queueFd, newStatus ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, &event) != 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_KQUEUE) + SOCKET fd = nativeInfo->fd(); + struct kevent ev; + EV_SET(&ev, fd, status == SocketOperationRead ? EVFILT_READ : EVFILT_WRITE, EV_DISABLE, 0, 0, handler); + _changes.push_back(ev); + if(_selecting) + { + updateSelector(); + } +#else + _changes.push_back(make_pair(handler, static_cast(handler->_registered & ~handler->_disabled))); + wakeup(); +#endif + } +} + +bool +Selector::finish(EventHandler* handler, bool closeNow) +{ + if(handler->_registered) + { + update(handler, handler->_registered, SocketOperationNone); +#if !defined(ICE_USE_EPOLL) && !defined(ICE_USE_KQUEUE) + return false; // Don't close now if selecting +#endif + } + +#if defined(ICE_USE_KQUEUE) + if(closeNow && !_changes.empty()) + { + // + // Update selector now to remove the FD from the kqueue if + // we're going to close it now. This isn't necessary for + // epoll since we always update the epoll FD immediately. + // + updateSelector(); + } +#elif !defined(ICE_USE_EPOLL) + if(!_changes.empty()) + { + return false; + } +#endif + + return closeNow; +} + +void +Selector::ready(EventHandler* handler, SocketOperation status, bool value) +{ + if(((handler->_ready & status) != 0) == value) + { + return; // Nothing to do if ready state already correctly set. + } + + if(status & SocketOperationConnect) + { + NativeInfoPtr nativeInfo = handler->getNativeInfo(); + if(nativeInfo && nativeInfo->newFd() && handler->_registered) + { + // If new FD is set after connect, register the FD with the selector. + updateSelectorForEventHandler(handler, SocketOperationNone, handler->_registered); + } + } + + if(value) + { + handler->_ready = static_cast(handler->_ready | status); + } + else + { + handler->_ready = static_cast(handler->_ready & ~status); + } + checkReady(handler); +} + +void +Selector::wakeup() +{ + if(_selecting && !_interrupted) + { + char c = 0; + while(true) + { + if(::write(_fdIntrWrite, &c, 1) == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + throw Ice::SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + break; + } + _interrupted = true; + } +} + +void +Selector::startSelect() +{ + if(_interrupted) + { + char c; + while(true) + { + ssize_t ret = ::read(_fdIntrRead, &c, 1); + if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + throw Ice::SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + break; + } + _interrupted = false; + } + +#if !defined(ICE_USE_EPOLL) + if(!_changes.empty()) + { + updateSelector(); + } +#endif + _selecting = true; + + // + // If there are ready handlers, don't block in select, just do a non-blocking + // select to retrieve new ready handlers from the Java selector. + // + _selectNow = !_readyHandlers.empty(); +} + +void +Selector::finishSelect(vector >& handlers) +{ + _selecting = false; + + assert(handlers.empty()); + +#if defined(ICE_USE_POLL) || defined(ICE_USE_SELECT) + if(_interrupted) // Interrupted, we have to process the interrupt before returning any handlers + { + return; + } +#endif + +#if defined(ICE_USE_POLL) + for(vector::const_iterator r = _pollFdSet.begin(); r != _pollFdSet.end(); ++r) +#else + for(int i = 0; i < _count; ++i) +#endif + { + pair p; + +#if defined(ICE_USE_EPOLL) + struct epoll_event& ev = _events[i]; + p.first = reinterpret_cast(ev.data.ptr); + p.second = static_cast(((ev.events & (EPOLLIN | EPOLLERR)) ? + SocketOperationRead : SocketOperationNone) | + ((ev.events & (EPOLLOUT | EPOLLERR)) ? + SocketOperationWrite : SocketOperationNone)); +#elif defined(ICE_USE_KQUEUE) + struct kevent& ev = _events[static_cast(i)]; + if(ev.flags & EV_ERROR) + { + Ice::Error out(_instance->initializationData().logger); + out << "selector returned error:\n" << IceUtilInternal::errorToString(static_cast(ev.data)); + continue; + } + p.first = reinterpret_cast(ev.udata); + p.second = (ev.filter == EVFILT_READ) ? SocketOperationRead : SocketOperationWrite; +#elif defined(ICE_USE_SELECT) + // + // Round robin for the filedescriptors. + // + SOCKET fd; + p.second = SocketOperationNone; + if(i < _selectedReadFdSet.fd_count) + { + fd = _selectedReadFdSet.fd_array[i]; + p.second = static_cast(p.second | SocketOperationRead); + } + else if(i < _selectedWriteFdSet.fd_count + _selectedReadFdSet.fd_count) + { + fd = _selectedWriteFdSet.fd_array[i - _selectedReadFdSet.fd_count]; + p.second = static_cast(p.second | SocketOperationWrite); + } + else + { + fd = _selectedErrorFdSet.fd_array[i - _selectedReadFdSet.fd_count - _selectedWriteFdSet.fd_count]; + p.second = static_cast(p.second | SocketOperationConnect); + } + + assert(fd != _fdIntrRead); + p.first = _handlers[fd]; +#else + if(r->revents == 0) + { + continue; + } + + SOCKET fd = r->fd; + assert(_handlers.find(fd) != _handlers.end()); + p.first = _handlers[fd]; + p.second = SocketOperationNone; + if(r->revents & (POLLIN | POLLERR | POLLHUP)) + { + p.second = static_cast(p.second | SocketOperationRead); + } + if(r->revents & (POLLOUT | POLLERR | POLLHUP)) + { + p.second = static_cast(p.second | SocketOperationWrite); + } + assert(p.second); +#endif + if(!p.first) + { + continue; // Interrupted + } + + map::iterator q = _readyHandlers.find(ICE_GET_SHARED_FROM_THIS(p.first)); + + if(q != _readyHandlers.end()) // Handler will be added by the loop below + { + q->second = p.second; // We just remember which operations are ready here. + } + else + { + handlers.push_back(p); + } + } + + for(map::iterator q = _readyHandlers.begin(); q != _readyHandlers.end(); ++q) + { + pair p; + p.first = q->first.get(); + p.second = static_cast(p.first->_ready & ~p.first->_disabled & p.first->_registered); + p.second = static_cast(p.second | q->second); + if(p.second) + { + handlers.push_back(p); + } + + // + // Reset the operation, it's only used by this method to temporarly store the socket status + // return by the select operation above. + // + q->second = SocketOperationNone; + } +} + +void +Selector::select(int timeout) +{ + if(_selectNow) + { + timeout = 0; + } + else if(timeout > 0) + { + timeout = timeout * 1000; + } + else + { + timeout = -1; + } + + int spuriousWakeup = 0; + while(true) + { +#if defined(ICE_USE_EPOLL) + _count = epoll_wait(_queueFd, &_events[0], _events.size(), timeout); +#elif defined(ICE_USE_KQUEUE) + assert(!_events.empty()); + if(timeout >= 0) + { + struct timespec ts; + ts.tv_sec = timeout; + ts.tv_nsec = 0; + _count = kevent(_queueFd, 0, 0, &_events[0], static_cast(_events.size()), &ts); + } + else + { + _count = kevent(_queueFd, 0, 0, &_events[0], static_cast(_events.size()), 0); + } +#elif defined(ICE_USE_SELECT) + fd_set* rFdSet = fdSetCopy(_selectedReadFdSet, _readFdSet); + fd_set* wFdSet = fdSetCopy(_selectedWriteFdSet, _writeFdSet); + fd_set* eFdSet = fdSetCopy(_selectedErrorFdSet, _errorFdSet); + if(timeout >= 0) + { + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + _count = ::select(0, rFdSet, wFdSet, eFdSet, &tv); // The first parameter is ignored on Windows + } + else + { + _count = ::select(0, rFdSet, wFdSet, eFdSet, 0); // The first parameter is ignored on Windows + } +#else + _count = poll(&_pollFdSet[0], _pollFdSet.size(), timeout); +#endif + + if(_count == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + Ice::SocketException ex(__FILE__, __LINE__, IceInternal::getSocketErrno()); + Ice::Error out(_instance->initializationData().logger); + out << "selector failed:\n" << ex; + IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(5)); // Sleep 5s to avoid looping + } + else if(_count == 0 && timeout < 0) + { + if(++spuriousWakeup > 100) + { + spuriousWakeup = 0; + _instance->initializationData().logger->warning("spurious selector wakeup"); + } + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(1)); + continue; + } + break; + } + + if(_count == 0 && !_selectNow) + { + throw SelectorTimeoutException(); + } +} + +void +Selector::checkReady(EventHandler* handler) +{ + if(handler->_ready & ~handler->_disabled & handler->_registered) + { + _readyHandlers.insert(make_pair(ICE_GET_SHARED_FROM_THIS(handler), SocketOperationNone)); + wakeup(); + } + else + { + map::iterator p = _readyHandlers.find(ICE_GET_SHARED_FROM_THIS(handler)); + if(p != _readyHandlers.end()) + { + _readyHandlers.erase(p); + } + } +} + +void +Selector::updateSelector() +{ +#if defined(ICE_USE_KQUEUE) + int rs = kevent(_queueFd, &_changes[0], static_cast(_changes.size()), + &_changes[0], static_cast(_changes.size()), &zeroTimeout); + if(rs < 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } + else + { + for(int i = 0; i < rs; ++i) + { + // + // Check for errors, we ignore EINPROGRESS that started showing up with macOS Sierra + // and which occurs when another thread removes the FD from the kqueue (see ICE-7419). + // + if(_changes[static_cast(i)].flags & EV_ERROR && + _changes[static_cast(i)].data != EINPROGRESS) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" + << IceUtilInternal::errorToString(static_cast(_changes[static_cast(i)].data)); + } + } + } + _changes.clear(); +#elif !defined(ICE_USE_EPOLL) + assert(!_selecting); + + for(vector >::const_iterator p = _changes.begin(); p != _changes.end(); ++p) + { + EventHandler* handler = p->first; + SocketOperation status = p->second; + + SOCKET fd = handler->getNativeInfo()->fd(); + if(status) + { +#if defined(ICE_USE_SELECT) + if(status & SocketOperationRead) + { + FD_SET(fd, &_readFdSet); + } + else + { + FD_CLR(fd, &_readFdSet); + } + if(status & SocketOperationWrite) + { + FD_SET(fd, &_writeFdSet); + } + else + { + FD_CLR(fd, &_writeFdSet); + } + if(status & SocketOperationConnect) + { + FD_SET(fd, &_writeFdSet); + FD_SET(fd, &_errorFdSet); + } + else + { + FD_CLR(fd, &_writeFdSet); + FD_CLR(fd, &_errorFdSet); + } + _handlers[fd] = handler; +#else + short events = 0; + if(status & SocketOperationRead) + { + events |= POLLIN; + } + if(status & SocketOperationWrite) + { + events |= POLLOUT; + } + map::const_iterator q = _handlers.find(fd); + if(q == _handlers.end()) + { + struct pollfd pollFd; + pollFd.fd = fd; + pollFd.events = events; + pollFd.revents = 0; + _pollFdSet.push_back(pollFd); + _handlers.insert(make_pair(fd, handler)); + } + else + { + for(vector::iterator r = _pollFdSet.begin(); r != _pollFdSet.end(); ++r) + { + if(r->fd == fd) + { + r->events = events; + break; + } + } + } +#endif + } + else + { +#if defined(ICE_USE_SELECT) + FD_CLR(fd, &_readFdSet); + FD_CLR(fd, &_writeFdSet); + FD_CLR(fd, &_errorFdSet); +#else + for(vector::iterator r = _pollFdSet.begin(); r != _pollFdSet.end(); ++r) + { + if(r->fd == fd) + { + _pollFdSet.erase(r); + break; + } + } +#endif + _handlers.erase(fd); + } + } + _changes.clear(); +#endif +} + +void +Selector::updateSelectorForEventHandler(EventHandler* handler, + ICE_MAYBE_UNUSED SocketOperation remove, + ICE_MAYBE_UNUSED SocketOperation add) +{ +#if defined(ICE_USE_EPOLL) + SocketOperation previous = handler->_registered; + previous = static_cast(previous & ~add); + previous = static_cast(previous | remove); + SOCKET fd = handler->getNativeInfo()->fd(); + assert(fd != INVALID_SOCKET); + epoll_event event; + memset(&event, 0, sizeof(epoll_event)); + event.data.ptr = handler; + SocketOperation status = handler->_registered; + if(handler->_disabled) + { + status = static_cast(status & ~handler->_disabled); + previous = static_cast(previous & ~handler->_disabled); + } + if(status & SocketOperationRead) + { + event.events |= EPOLLIN; + } + if(status & SocketOperationWrite) + { + event.events |= EPOLLOUT; + } + int op; + if(!previous && status) + { + op = EPOLL_CTL_ADD; + } + else if(previous && !status) + { + op = EPOLL_CTL_DEL; + } + else if(previous == status) + { + return; + } + else + { + op = EPOLL_CTL_MOD; + } + if(epoll_ctl(_queueFd, op, fd, &event) != 0) + { + Ice::Error out(_instance->initializationData().logger); + out << "error while updating selector:\n" << IceUtilInternal::errorToString(IceInternal::getSocketErrno()); + } +#elif defined(ICE_USE_KQUEUE) + SOCKET fd = handler->getNativeInfo()->fd(); + assert(fd != INVALID_SOCKET); + if(remove & SocketOperationRead) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, handler); + _changes.push_back(ev); + } + if(remove & SocketOperationWrite) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, handler); + _changes.push_back(ev); + } + if(add & SocketOperationRead) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_READ, EV_ADD | (handler->_disabled & SocketOperationRead ? EV_DISABLE : 0), 0, 0, + handler); + _changes.push_back(ev); + } + if(add & SocketOperationWrite) + { + struct kevent ev; + EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD | (handler->_disabled & SocketOperationWrite ? EV_DISABLE : 0), 0, 0, + handler); + _changes.push_back(ev); + } + if(_selecting) + { + updateSelector(); + } +#else + _changes.push_back(make_pair(handler, static_cast(handler->_registered & ~handler->_disabled))); + wakeup(); +#endif + checkReady(handler); +} + +#elif defined(ICE_USE_CFSTREAM) + +namespace +{ + +void selectorInterrupt(void* info) +{ + reinterpret_cast(info)->processInterrupt(); +} + +void eventHandlerSocketCallback(CFSocketRef, CFSocketCallBackType callbackType, CFDataRef, const void* d, void* info) +{ + if(callbackType == kCFSocketReadCallBack) + { + reinterpret_cast(info)->readyCallback(SocketOperationRead); + } + else if(callbackType == kCFSocketWriteCallBack) + { + reinterpret_cast(info)->readyCallback(SocketOperationWrite); + } + else if(callbackType == kCFSocketConnectCallBack) + { + reinterpret_cast(info)->readyCallback(SocketOperationConnect, + d ? *reinterpret_cast(d) : 0); + } +} + +class SelectorHelperThread : public IceUtil::Thread +{ +public: + + SelectorHelperThread(Selector& selector) : _selector(selector) + { + } + + virtual void run() + { + _selector.run(); + +#if TARGET_IPHONE_SIMULATOR != 0 + // + // Workaround for CFSocket bug where the CFSocketManager thread crashes if an + // invalidated socket is being processed for reads/writes. We add this sleep + // mostly to prevent spurious crashes with testing. This bug is very unlikely + // to be hit otherwise. + // + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(100)); +#endif + } + +private: + + Selector& _selector; +}; + +CFOptionFlags +toCFCallbacks(SocketOperation op) +{ + CFOptionFlags cbs = 0; + if(op & SocketOperationRead) + { + cbs |= kCFSocketReadCallBack; + } + if(op & SocketOperationWrite) + { + cbs |= kCFSocketWriteCallBack; + } + if(op & SocketOperationConnect) + { + cbs |= kCFSocketConnectCallBack; + } + return cbs; +} + +} + +EventHandlerWrapper::EventHandlerWrapper(EventHandler* handler, Selector& selector) : + _handler(ICE_GET_SHARED_FROM_THIS(handler)), + _streamNativeInfo(StreamNativeInfoPtr::dynamicCast(handler->getNativeInfo())), + _selector(selector), + _ready(SocketOperationNone), + _finish(false) +{ + if(_streamNativeInfo) + { + _streamNativeInfo->initStreams(this); + } + else if(handler->getNativeInfo()) + { + SOCKET fd = handler->getNativeInfo()->fd(); + CFSocketContext ctx = { 0, this, 0, 0, 0 }; + _socket.reset(CFSocketCreateWithNative(kCFAllocatorDefault, + fd, + kCFSocketReadCallBack | + kCFSocketWriteCallBack | + kCFSocketConnectCallBack, + eventHandlerSocketCallback, + &ctx)); + + // Disable automatic re-enabling of callbacks and closing of the native socket. + CFSocketSetSocketFlags(_socket.get(), 0); + CFSocketDisableCallBacks(_socket.get(), kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); + _source.reset(CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket.get(), 0)); + } +} + +EventHandlerWrapper::~EventHandlerWrapper() +{ +} + +void +EventHandlerWrapper::updateRunLoop() +{ + SocketOperation op = _handler->_registered; + assert(!op || !_finish); + + if(_socket) + { + CFSocketDisableCallBacks(_socket.get(), kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); + if(op) + { + CFSocketEnableCallBacks(_socket.get(), toCFCallbacks(op)); + } + + if(op && !CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode)) + { + CFRunLoopAddSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); + } + else if(!op && CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode)) + { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); + } + + if(_finish) + { + CFSocketInvalidate(_socket.get()); + } + } + else + { + SocketOperation readyOp = _streamNativeInfo->registerWithRunLoop(op); + if(!(op & (SocketOperationWrite | SocketOperationConnect)) || _ready & SocketOperationWrite) + { + _streamNativeInfo->unregisterFromRunLoop(SocketOperationWrite, false); + } + + if(!(op & (SocketOperationRead | SocketOperationConnect)) || _ready & SocketOperationRead) + { + _streamNativeInfo->unregisterFromRunLoop(SocketOperationRead, false); + } + + if(readyOp) + { + ready(readyOp, 0); + } + + if(_finish) + { + _streamNativeInfo->closeStreams(); + } + } +} + +void +EventHandlerWrapper::readyCallback(SocketOperation op, int error) +{ + _selector.ready(this, op, error); +} + +void +EventHandlerWrapper::ready(SocketOperation op, int error) +{ + if(!_socket) + { + // + // Unregister the stream from the runloop as soon as we got the callback. This is + // required to allow thread pool thread to perform read/write operations on the + // stream (which can't be used from another thread than the run loop thread if + // it's registered with a run loop). + // + op = _streamNativeInfo->unregisterFromRunLoop(op, error != 0); + } + + op = static_cast(_handler->_registered & op); + if(!op || _ready & op) + { + return; + } + + if(_socket) + { + if(op & SocketOperationConnect) + { + _streamNativeInfo->setConnectError(error); + } + } + + _ready = static_cast(_ready | op); + checkReady(); +} + +bool +EventHandlerWrapper::checkReady() +{ + if((_ready | _handler->_ready) & ~_handler->_disabled & _handler->_registered) + { + _selector.addReadyHandler(this); + return false; + } + else + { + return _handler->getNativeInfo() && !_finish; + } +} + +SocketOperation +EventHandlerWrapper::readyOp() +{ + assert(!(~_handler->_registered & _ready)); + SocketOperation op = static_cast(~_handler->_disabled & (_ready | _handler->_ready)); + _ready = static_cast(~op & _ready); + return op; +} + +bool +EventHandlerWrapper::update(SocketOperation remove, SocketOperation add) +{ + SocketOperation previous = _handler->_registered; + _handler->_registered = static_cast(_handler->_registered & ~remove); + _handler->_registered = static_cast(_handler->_registered | add); + if(previous == _handler->_registered) + { + return false; + } + + // Clear ready flags which might not be valid anymore. + _ready = static_cast(_ready & _handler->_registered); + return _handler->getNativeInfo(); +} + +bool +EventHandlerWrapper::finish() +{ + _finish = true; + _ready = SocketOperationNone; + _handler->_registered = SocketOperationNone; + return _handler->getNativeInfo(); +} + +Selector::Selector(const InstancePtr& instance) : _instance(instance), _destroyed(false) +{ + CFRunLoopSourceContext ctx; + memset(&ctx, 0, sizeof(CFRunLoopSourceContext)); + ctx.info = this; + ctx.perform = selectorInterrupt; + _source.reset(CFRunLoopSourceCreate(0, 0, &ctx)); + _runLoop = 0; + + _thread = new SelectorHelperThread(*this); + _thread->start(); + + Lock sync(*this); + while(!_runLoop) + { + wait(); + } +} + +Selector::~Selector() +{ +} + +void +Selector::destroy() +{ + { + Lock sync(*this); + + // + // Make sure any pending changes are processed to ensure remaining + // streams/sockets are closed. + // + _destroyed = true; + CFRunLoopSourceSignal(_source.get()); + CFRunLoopWakeUp(_runLoop); + + while(!_changes.empty()) + { + CFRunLoopSourceSignal(_source.get()); + CFRunLoopWakeUp(_runLoop); + + wait(); + } + } + + _thread->getThreadControl().join(); + _thread = 0; + + Lock sync(*this); + _source.reset(0); + + //assert(_wrappers.empty()); + _readyHandlers.clear(); + _selectedHandlers.clear(); +} + +void +Selector::initialize(EventHandler* handler) +{ + Lock sync(*this); + _wrappers[handler] = new EventHandlerWrapper(handler, *this); +} + +void +Selector::update(EventHandler* handler, SocketOperation remove, SocketOperation add) +{ + Lock sync(*this); + const EventHandlerWrapperPtr& wrapper = _wrappers[handler]; + if(wrapper->update(remove, add)) + { + _changes.insert(wrapper); + notify(); + } +} + +void +Selector::enable(EventHandler* handler, SocketOperation op) +{ + Lock sync(*this); + if(!(handler->_disabled & op)) + { + return; + } + handler->_disabled = static_cast(handler->_disabled & ~op); + + if(handler->_registered & op) + { + _wrappers[handler]->checkReady(); + } +} + +void +Selector::disable(EventHandler* handler, SocketOperation op) +{ + Lock sync(*this); + if(handler->_disabled & op) + { + return; + } + handler->_disabled = static_cast(handler->_disabled | op); +} + +bool +Selector::finish(EventHandler* handler, bool closeNow) +{ + Lock sync(*this); + std::map::iterator p = _wrappers.find(handler); + assert(p != _wrappers.end()); + EventHandlerWrapperPtr wrapper = p->second; + if(wrapper->finish()) + { + _changes.insert(wrapper); + notify(); + } + _wrappers.erase(p); + return closeNow; +} + +void +Selector::ready(EventHandler* handler, SocketOperation status, bool value) +{ + if(((handler->_ready & status) != 0) == value) + { + return; // Nothing to do if ready state already correctly set. + } + + if(value) + { + handler->_ready = static_cast(handler->_ready | status); + } + else + { + handler->_ready = static_cast(handler->_ready & ~status); + } + + Lock sync(*this); + std::map::iterator p = _wrappers.find(handler); + assert(p != _wrappers.end()); + p->second->checkReady(); +} + +void +Selector::startSelect() +{ + Lock sync(*this); + + // + // Re-enable callbacks for previously selected handlers. + // + vector >::const_iterator p; + for(p = _selectedHandlers.begin(); p != _selectedHandlers.end(); ++p) + { + if(p->first->checkReady()) + { + _changes.insert(p->first); + } + } + _selectedHandlers.clear(); +} + +void +Selector::finishSelect(std::vector >& handlers) +{ + Lock sync(*this); + handlers.clear(); + for(set::const_iterator p = _readyHandlers.begin(); p != _readyHandlers.end(); ++p) + { + SocketOperation op = (*p)->readyOp(); + if(op) + { + _selectedHandlers.push_back(pair(*p, op)); + handlers.push_back(pair((*p)->_handler.get(), op)); + } + } + _readyHandlers.clear(); +} + +void +Selector::select(int timeout) +{ + // + // Wait for handlers to be ready. + // + Lock sync(*this); + while(!_destroyed) + { + while(!_changes.empty()) + { + CFRunLoopSourceSignal(_source.get()); + CFRunLoopWakeUp(_runLoop); + + wait(); + } + + if(_readyHandlers.empty()) + { + if(timeout > 0) + { + if(!timedWait(IceUtil::Time::seconds(timeout))) + { + break; + } + } + else + { + wait(); + } + } + + if(_changes.empty()) + { + break; + } + } +} + +void +Selector::processInterrupt() +{ + Lock sync(*this); + if(!_changes.empty()) + { + for(set::const_iterator p = _changes.begin(); p != _changes.end(); ++p) + { + (*p)->updateRunLoop(); + } + _changes.clear(); + notify(); + } + if(_destroyed) + { + CFRunLoopStop(_runLoop); + } +} + +void +Selector::run() +{ + { + Lock sync(*this); + _runLoop = CFRunLoopGetCurrent(); + notify(); + } + + CFRunLoopAddSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); + CFRunLoopRun(); + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); +} + +void +Selector::ready(EventHandlerWrapper* wrapper, SocketOperation op, int error) +{ + Lock sync(*this); + wrapper->ready(op, error); +} + +void +Selector::addReadyHandler(EventHandlerWrapper* wrapper) +{ + // Called from ready() + _readyHandlers.insert(wrapper); + if(_readyHandlers.size() == 1) + { + notify(); + } +} + +#endif diff --git a/Sources/IceCpp/ServantLocator.cpp b/Sources/IceCpp/ServantLocator.cpp new file mode 100644 index 0000000..bd67faa --- /dev/null +++ b/Sources/IceCpp/ServantLocator.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ServantLocator::~ServantLocator() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ServantLocator::~ServantLocator() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ServantLocator* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ServantLocatorF.cpp b/Sources/IceCpp/ServantLocatorF.cpp new file mode 100644 index 0000000..345a29e --- /dev/null +++ b/Sources/IceCpp/ServantLocatorF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ServantManager.cpp b/Sources/IceCpp/ServantManager.cpp new file mode 100644 index 0000000..6f985a4 --- /dev/null +++ b/Sources/IceCpp/ServantManager.cpp @@ -0,0 +1,480 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +ICE_API IceUtil::Shared* IceInternal::upCast(ServantManager* p) { return p; } + +void +IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity& ident, const string& facet) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + + if(p == _servantMapMap.end() || p->first != ident) + { + p = _servantMapMap.find(ident); + } + + if(p == _servantMapMap.end()) + { + p = _servantMapMap.insert(_servantMapMapHint, pair(ident, FacetMap())); + } + else + { + if(p->second.find(facet) != p->second.end()) + { + ToStringMode toStringMode = _instance->toStringMode(); + ostringstream os; + os << Ice::identityToString(ident, toStringMode); + if(!facet.empty()) + { + os << " -f " << escapeString(facet, "", toStringMode); + } + throw AlreadyRegisteredException(__FILE__, __LINE__, "servant", os.str()); + } + } + + _servantMapMapHint = p; + + p->second.insert(pair(facet, object)); +} + +void +IceInternal::ServantManager::addDefaultServant(const ObjectPtr& object, const string& category) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + DefaultServantMap::iterator p = _defaultServantMap.find(category); + if(p != _defaultServantMap.end()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "default servant", category); + } + + _defaultServantMap.insert(pair(category, object)); +} + +ObjectPtr +IceInternal::ServantManager::removeServant(const Identity& ident, const string& facet) +{ + // + // We return the removed servant to avoid releasing the last reference count + // with *this locked. We don't want to run user code, such as the servant + // destructor, with an internal Ice mutex locked. + // + ObjectPtr servant = 0; + + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + FacetMap::iterator q; + + if(p == _servantMapMap.end() || p->first != ident) + { + p = _servantMapMap.find(ident); + } + + if(p == _servantMapMap.end() || (q = p->second.find(facet)) == p->second.end()) + { + ToStringMode toStringMode = _instance->toStringMode(); + ostringstream os; + os << Ice::identityToString(ident, toStringMode); + if(!facet.empty()) + { + os << " -f " + escapeString(facet, "", toStringMode); + } + throw NotRegisteredException(__FILE__, __LINE__, "servant", os.str()); + } + + servant = q->second; + p->second.erase(q); + + if(p->second.empty()) + { + if(p == _servantMapMapHint) + { + _servantMapMap.erase(p++); + _servantMapMapHint = p; + } + else + { + _servantMapMap.erase(p); + } + } + return servant; +} + +ObjectPtr +IceInternal::ServantManager::removeDefaultServant(const string& category) +{ + // + // We return the removed servant to avoid releasing the last reference count + // with *this locked. We don't want to run user code, such as the servant + // destructor, with an internal Ice mutex locked. + // + ObjectPtr servant = 0; + + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + DefaultServantMap::iterator p = _defaultServantMap.find(category); + if(p == _defaultServantMap.end()) + { + throw NotRegisteredException(__FILE__, __LINE__, "default servant", category); + } + + servant = p->second; + _defaultServantMap.erase(p); + + return servant; +} + +FacetMap +IceInternal::ServantManager::removeAllFacets(const Identity& ident) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + + if(p == _servantMapMap.end() || p->first != ident) + { + p = _servantMapMap.find(ident); + } + + if(p == _servantMapMap.end()) + { + throw NotRegisteredException(__FILE__, __LINE__, "servant", + Ice::identityToString(ident, _instance->toStringMode())); + } + + FacetMap result = p->second; + + if(p == _servantMapMapHint) + { + _servantMapMap.erase(p++); + _servantMapMapHint = p; + } + else + { + _servantMapMap.erase(p); + } + + return result; +} + +ObjectPtr +IceInternal::ServantManager::findServant(const Identity& ident, const string& facet) const +{ + IceUtil::Mutex::Lock sync(*this); + + // + // This assert is not valid if the adapter dispatch incoming + // requests from bidir connections. This method might be called if + // requests are received over the bidir connection after the + // adapter was deactivated. + // + //assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + FacetMap::iterator q; + + ServantMapMap& servantMapMap = const_cast(_servantMapMap); + + if(p == servantMapMap.end() || p->first != ident) + { + p = servantMapMap.find(ident); + } + + if(p == servantMapMap.end() || (q = p->second.find(facet)) == p->second.end()) + { + DefaultServantMap::const_iterator d = _defaultServantMap.find(ident.category); + if(d == _defaultServantMap.end()) + { + d = _defaultServantMap.find(""); + if(d == _defaultServantMap.end()) + { + return 0; + } + else + { + return d->second; + } + } + else + { + return d->second; + } + } + else + { + _servantMapMapHint = p; + return q->second; + } +} + +ObjectPtr +IceInternal::ServantManager::findDefaultServant(const string& category) const +{ + IceUtil::Mutex::Lock sync(*this); + + DefaultServantMap::const_iterator p = _defaultServantMap.find(category); + if(p == _defaultServantMap.end()) + { + return 0; + } + else + { + return p->second; + } +} + +FacetMap +IceInternal::ServantManager::findAllFacets(const Identity& ident) const +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + + ServantMapMap& servantMapMap = const_cast(_servantMapMap); + + if(p == servantMapMap.end() || p->first != ident) + { + p = servantMapMap.find(ident); + } + + if(p == servantMapMap.end()) + { + return FacetMap(); + } + else + { + _servantMapMapHint = p; + return p->second; + } +} + +bool +IceInternal::ServantManager::hasServant(const Identity& ident) const +{ + IceUtil::Mutex::Lock sync(*this); + + // + // This assert is not valid if the adapter dispatch incoming + // requests from bidir connections. This method might be called if + // requests are received over the bidir connection after the + // adapter was deactivated. + // + //assert(_instance); // Must not be called after destruction. + + ServantMapMap::iterator p = _servantMapMapHint; + ServantMapMap& servantMapMap = const_cast(_servantMapMap); + + if(p == servantMapMap.end() || p->first != ident) + { + p = servantMapMap.find(ident); + } + + if(p == servantMapMap.end()) + { + return false; + } + else + { + _servantMapMapHint = p; + assert(!p->second.empty()); + return true; + } +} + +void +IceInternal::ServantManager::addServantLocator(const ServantLocatorPtr& locator, const string& category) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + if((_locatorMapHint != _locatorMap.end() && _locatorMapHint->first == category) + || _locatorMap.find(category) != _locatorMap.end()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "servant locator", category); + } + + _locatorMapHint = _locatorMap.insert(_locatorMapHint, pair(category, locator)); +} + +ServantLocatorPtr +IceInternal::ServantManager::removeServantLocator(const string& category) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + map::iterator p = _locatorMap.end(); + if(_locatorMapHint != p) + { + if(_locatorMapHint->first == category) + { + p = _locatorMapHint; + } + } + + if(p == _locatorMap.end()) + { + p = _locatorMap.find(category); + } + + if(p == _locatorMap.end()) + { + throw NotRegisteredException(__FILE__, __LINE__, "servant locator", category); + } + + ServantLocatorPtr locator = p->second; + _locatorMap.erase(p); + _locatorMapHint = _locatorMap.begin(); + return locator; +} + +ServantLocatorPtr +IceInternal::ServantManager::findServantLocator(const string& category) const +{ + IceUtil::Mutex::Lock sync(*this); + + // + // This assert is not valid if the adapter dispatch incoming + // requests from bidir connections. This method might be called if + // requests are received over the bidir connection after the + // adapter was deactivated. + // + //assert(_instance); // Must not be called after destruction. + + map& locatorMap = + const_cast&>(_locatorMap); + + map::iterator p = locatorMap.end(); + if(_locatorMapHint != locatorMap.end()) + { + if(_locatorMapHint->first == category) + { + p = _locatorMapHint; + } + } + + if(p == locatorMap.end()) + { + p = locatorMap.find(category); + } + + if(p != locatorMap.end()) + { + _locatorMapHint = p; + return p->second; + } + else + { + return 0; + } +} + +IceInternal::ServantManager::ServantManager(const InstancePtr& instance, const string& adapterName) + : _instance(instance), + _adapterName(adapterName), + _servantMapMapHint(_servantMapMap.end()), + _locatorMapHint(_locatorMap.end()) +{ +} + +IceInternal::ServantManager::~ServantManager() +{ + // + // Don't check whether destroy() has been called. It might have + // not been called if the associated object adapter was not + // properly deactivated. + // + //assert(!_instance); +} + +void +IceInternal::ServantManager::destroy() +{ + ServantMapMap servantMapMap; + DefaultServantMap defaultServantMap; + map locatorMap; + Ice::LoggerPtr logger; + + { + IceUtil::Mutex::Lock sync(*this); + // + // If the ServantManager has already been destroyed, we're done. + // + if(!_instance) + { + return; + } + + logger = _instance->initializationData().logger; + + servantMapMap.swap(_servantMapMap); + _servantMapMapHint = _servantMapMap.end(); + + defaultServantMap.swap(_defaultServantMap); + + locatorMap.swap(_locatorMap); + _locatorMapHint = _locatorMap.end(); + + _instance = 0; + } + + for(map::const_iterator p = locatorMap.begin(); p != locatorMap.end(); ++p) + { + try + { + p->second->deactivate(p->first); + } + catch(const Exception& ex) + { + Error out(logger); + out << "exception during locator deactivation:\n" + << "object adapter: `" << _adapterName << "'\n" + << "locator category: `" << p->first << "'\n" + << ex; + } + catch(...) + { + Error out(logger); + out << "unknown exception during locator deactivation:\n" + << "object adapter: `" << _adapterName << "'\n" + << "locator category: `" << p->first << "'"; + } + } + + // + // We clear the maps outside the synchronization as we don't want to + // hold any internal Ice mutex while running user code (such as servant + // or servant locator destructors). + // + servantMapMap.clear(); + locatorMap.clear(); + defaultServantMap.clear(); +} diff --git a/Sources/IceCpp/Service.cpp b/Sources/IceCpp/Service.cpp new file mode 100644 index 0000000..1ec6cb4 --- /dev/null +++ b/Sources/IceCpp/Service.cpp @@ -0,0 +1,1883 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +# include +# include +# include +# ifdef ICE_USE_SYSTEMD +# include +# endif +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Ice::Service* Ice::Service::_instance = 0; +static IceUtil::CtrlCHandler* _ctrlCHandler = 0; + +// +// Callback for IceUtil::CtrlCHandler. +// +static void +ctrlCHandlerCallback(int sig) +{ + Ice::Service* service = Ice::Service::instance(); + assert(service != 0); + service->handleInterrupt(sig); +} + +#ifdef _WIN32 + +// +// Main function for Win32 service. +// +void WINAPI +Ice_Service_ServiceMain(DWORD argc, LPWSTR* argv) +{ + Ice::Service* service = Ice::Service::instance(); + assert(service != 0); + service->serviceMain(argc, argv); +} + +// +// Win32 service control handler. +// +void WINAPI +Ice_Service_CtrlHandler(DWORD ctrl) +{ + Ice::Service* service = Ice::Service::instance(); + assert(service != 0); + service->control(ctrl); +} + +namespace +{ + +class ServiceStatusManager : public IceUtil::Monitor +{ +public: + + ServiceStatusManager(SERVICE_STATUS_HANDLE); + + // + // Start a thread to provide regular status updates to the SCM. + // + void startUpdate(DWORD); + + // + // Stop the update thread. + // + void stopUpdate(); + + // + // Change the service status and report it (once). + // + void changeStatus(DWORD, DWORD); + + // + // Report the current status. + // + void reportStatus(); + +private: + + void run(); + + class StatusThread : public IceUtil::Thread + { + public: + + StatusThread(ServiceStatusManager* manager) : + IceUtil::Thread("Ice service status manager thread"), + _manager(manager) + { + } + + virtual void run() + { + _manager->run(); + } + + private: + + ServiceStatusManager* _manager; + }; + friend class StatusThread; + + SERVICE_STATUS_HANDLE _handle; + SERVICE_STATUS _status; + IceUtil::ThreadPtr _thread; + bool _stopped; +}; + +static ServiceStatusManager* serviceStatusManager; + +// +// Interface implemented by SMEventLoggerI and called from +// SMEventLoggerIWrapper. +// +class SMEventLogger : public IceUtil::Shared +{ +public: + virtual void print(const string&, const string&) = 0; + virtual void trace(const string&, const string&, const string&) = 0; + virtual void warning(const string&, const string&) = 0; + virtual void error(const string&, const string&) = 0; +}; +typedef IceUtil::Handle SMEventLoggerPtr; + +class SMEventLoggerIWrapper : public Ice::Logger +{ +public: + + SMEventLoggerIWrapper(const SMEventLoggerPtr& logger, const string& prefix) : + _logger(logger), + _prefix(prefix) + { + assert(_logger); + } + + virtual void + print(const string& message) + { + _logger->print(_prefix, message); + } + + void + trace(const string& category, const string& message) + { + _logger->trace(_prefix, category, message); + } + + virtual void + warning(const string& message) + { + _logger->warning(_prefix, message); + } + + virtual void + error(const string& message) + { + _logger->error(_prefix, message); + } + + virtual string + getPrefix() + { + return _prefix; + } + + virtual Ice::LoggerPtr + cloneWithPrefix(const string& prefix) + { + return ICE_MAKE_SHARED(SMEventLoggerIWrapper, _logger, prefix); + } + +private: + + SMEventLoggerPtr _logger; + const string _prefix; +}; + +class SMEventLoggerI : public SMEventLogger +{ +public: + + SMEventLoggerI(const string& source, const StringConverterPtr& stringConverter) : + _stringConverter(stringConverter) + { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + _source = RegisterEventSourceW(0, stringToWstring(mangleSource(source), _stringConverter).c_str()); + if(_source == 0) + { + throw SyscallException(__FILE__, __LINE__, GetLastError()); + } + } + + ~SMEventLoggerI() + { + assert(_source != 0); + DeregisterEventSource(_source); + } + + static void + addKeys(const string& source, const StringConverterPtr& stringConverter) + { + HKEY hKey; + DWORD d; + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + LONG err = RegCreateKeyExW(HKEY_LOCAL_MACHINE, + stringToWstring(createKey(source), stringConverter).c_str(), + 0, const_cast(L"REG_SZ"), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &d); + + if(err != ERROR_SUCCESS) + { + throw SyscallException(__FILE__, __LINE__, err); + } + + // + // Get the filename of this DLL. + // + wchar_t path[_MAX_PATH]; + assert(_module != 0); + if(!GetModuleFileNameW(_module, path, _MAX_PATH)) + { + RegCloseKey(hKey); + throw SyscallException(__FILE__, __LINE__, GetLastError()); + } + + // + // The event resources are bundled into this DLL, therefore + // the "EventMessageFile" key should contain the path to this + // DLL. + // + err = RegSetValueExW(hKey, L"EventMessageFile", 0, REG_EXPAND_SZ, reinterpret_cast(path), + static_cast((wcslen(path) * sizeof(wchar_t)) + 1)); + + if(err == ERROR_SUCCESS) + { + // + // The "TypesSupported" key indicates the supported event + // types. + // + DWORD typesSupported = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; + err = RegSetValueExW(hKey, L"TypesSupported", 0, REG_DWORD, + reinterpret_cast(&typesSupported), sizeof(typesSupported)); + } + if(err != ERROR_SUCCESS) + { + RegCloseKey(hKey); + throw SyscallException(__FILE__, __LINE__, err); + } + + RegCloseKey(hKey); + } + + static void + removeKeys(const string& source, const StringConverterPtr& stringConverter) + { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + LONG err = RegDeleteKeyW(HKEY_LOCAL_MACHINE, + stringToWstring(createKey(source), stringConverter).c_str()); + if(err != ERROR_SUCCESS) + { + throw SyscallException(__FILE__, __LINE__, err); + } + } + + virtual void + print(const string& prefix, const string& message) + { + string s; + if(!prefix.empty()) + { + s = prefix; + s.append(": "); + } + s.append(message); + print(s); + } + + void + print(const string& message) + { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + const wstring msg = stringToWstring(message, _stringConverter); + const wchar_t* messages[1]; + messages[0] = msg.c_str(); + // + // We ignore any failures from ReportEvent since there isn't + // anything we can do about it. + // + ReportEventW(_source, EVENTLOG_INFORMATION_TYPE, 0, EVENT_LOGGER_MSG, 0, 1, 0, messages, 0); + } + + virtual void + trace(const string& prefix, const string& category, const string& message) + { + string s; + if(!category.empty()) + { + s = category; + s.append(": "); + } + s.append(message); + trace(prefix, s); + } + + void + trace(const string& category, const string& message) + { + string s; + if(!category.empty()) + { + s = category; + s.append(": "); + } + s.append(message); + + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = stringToWstring(s, _stringConverter); + const wchar_t* messages[1]; + messages[0] = msg.c_str(); + // + // We ignore any failures from ReportEvent since there isn't + // anything we can do about it. + // + ReportEventW(_source, EVENTLOG_INFORMATION_TYPE, 0, EVENT_LOGGER_MSG, 0, 1, 0, messages, 0); + } + + virtual void + warning(const string& prefix, const string& message) + { + string s; + if(!prefix.empty()) + { + s = prefix; + s.append(": "); + } + s.append(message); + warning(s); + } + + void + warning(const string& message) + { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = stringToWstring(message, _stringConverter); + const wchar_t* messages[1]; + messages[0] = msg.c_str(); + // + // We ignore any failures from ReportEvent since there isn't + // anything we can do about it. + // + ReportEventW(_source, EVENTLOG_WARNING_TYPE, 0, EVENT_LOGGER_MSG, 0, 1, 0, messages, 0); + } + + virtual void + error(const string& prefix, const string& message) + { + string s; + if(!prefix.empty()) + { + s = prefix; + s.append(": "); + } + s.append(message); + error(s); + } + + void + error(const string& message) + { + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + wstring msg = stringToWstring(message, _stringConverter); + const wchar_t* messages[1]; + messages[0] = msg.c_str(); + // + // We ignore any failures from ReportEvent since there isn't + // anything we can do about it. + // + ReportEventW(_source, EVENTLOG_ERROR_TYPE, 0, EVENT_LOGGER_MSG, 0, 1, 0, messages, 0); + } + + static void + setModuleHandle(HMODULE module) + { + _module = module; + } + +private: + + static string + mangleSource(string name) + { + // + // The source name cannot contain backslashes. + // + string::size_type pos = 0; + while((pos = name.find('\\', pos)) != string::npos) + { + name[pos] = '/'; + } + return name; + } + + static string + createKey(string name) + { + // + // The registry key is: + // + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application. + // + return "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" + mangleSource(name); + } + + StringConverterPtr _stringConverter; + HANDLE _source; + static HMODULE _module; +}; + +HMODULE SMEventLoggerI::_module = 0; + +} + +#endif + +Ice::Service::Service() +{ + assert(_instance == 0); + _nohup = true; + _service = false; + _instance = this; +#ifndef _WIN32 + _changeDirectory = true; + _closeFiles = true; +#endif +} + +Ice::Service::~Service() +{ + _instance = 0; + delete _ctrlCHandler; +} + +bool +Ice::Service::shutdown() +{ + if(_communicator) + { + try + { + _communicator->shutdown(); + } + catch(const CommunicatorDestroyedException&) + { + // + // Expected if the service communicator is being destroyed. + // + } + catch(const Ice::Exception& ex) + { + ServiceWarning warn(this); + warn << "exception during shutdown:\n" << ex; + } + catch(const std::exception& ex) + { + ServiceWarning warn(this); + warn << "exception during shutdown:\n" << ex; + } + catch(...) + { + warning("unknown exception during shutdown"); + } + } + return true; +} + +void +Ice::Service::interrupt() +{ + shutdown(); +} + +int +Ice::Service::main(int argc, const char* const argv[], const InitializationData& initializationData, int version) +{ + _name = ""; + if(argc > 0) + { + _name = argv[0]; + } + + IceInternal::ArgVector av(argc, argv); // copy args + + // + // We parse the properties here to extract Ice.ProgramName and + // Ice.EventLog.Source on Windows. + // + InitializationData initData = initializationData; + try + { + initData.properties = createProperties(av.argc, av.argv, initData.properties); + } + catch(const Ice::Exception& ex) + { + ServiceError err(this); + err << "createProperties failed: " << ex; + return EXIT_FAILURE; + } + +#ifdef _WIN32 + + // + // First check for the --service option. + // + string name; + int idx = 1; + const StringConverterPtr stringConverter = getProcessStringConverter(); + while(idx < av.argc) + { + if(strcmp(av.argv[idx], "--service") == 0) + { + if(idx + 1 >= av.argc) + { + error("service name argument expected for `" + string(av.argv[idx]) + "'"); + return EXIT_FAILURE; + } + + name = av.argv[idx + 1]; + + // + // If the process logger is the default logger then we use + // our own logger. + // + _logger = getProcessLogger(); + if(ICE_DYNAMIC_CAST(LoggerI, _logger)) + { + string eventLogSource = initData.properties->getPropertyWithDefault("Ice.EventLog.Source", name); + _logger = ICE_MAKE_SHARED(SMEventLoggerIWrapper, new SMEventLoggerI(eventLogSource, stringConverter), ""); + setProcessLogger(_logger); + } + + for(int i = idx; i + 2 < av.argc; ++i) + { + av.argv[i] = av.argv[i + 2]; + } + av.argc -= 2; + } + else + { + ++idx; + } + } + + if(!name.empty()) + { + configureService(name); + } +#else + // + // Check for --daemon, --noclose, --nochdir and --pidfile. + // + + bool daemonize = false; + bool closeFiles = true; + bool changeDirectory = true; + string pidFile; + int idx = 1; + while(idx < av.argc) + { + if(strcmp(av.argv[idx], "--daemon") == 0) + { + for(int i = idx; i + 1 < av.argc; ++i) + { + av.argv[i] = av.argv[i + 1]; + } + av.argc -= 1; + + daemonize = true; + } + else if(strcmp(av.argv[idx], "--noclose") == 0) + { + for(int i = idx; i + 1 < av.argc; ++i) + { + av.argv[i] = av.argv[i + 1]; + } + av.argc -= 1; + + closeFiles = false; + } + else if(strcmp(av.argv[idx], "--nochdir") == 0) + { + for(int i = idx; i + 1 < av.argc; ++i) + { + av.argv[i] = av.argv[i + 1]; + } + av.argc -= 1; + + changeDirectory = false; + } + else if(strcmp(av.argv[idx], "--pidfile") == 0) + { + if(idx + 1 < av.argc) + { + pidFile = av.argv[idx + 1]; + } + else + { + if(av.argv[0]) + { + consoleErr << av.argv[0] << ": "; + } + consoleErr << "--pidfile must be followed by an argument" << endl; + return EXIT_FAILURE; + } + + for(int i = idx; i + 2 < av.argc; ++i) + { + av.argv[i] = av.argv[i + 2]; + } + av.argc -= 2; + } + else + { + ++idx; + } + } + + if(!closeFiles && !daemonize) + { + if(av.argv[0]) + { + consoleErr << av.argv[0] << ": "; + } + consoleErr << "--noclose must be used with --daemon" << endl; + return EXIT_FAILURE; + } + + if(pidFile.size() > 0 && !daemonize) + { + if(av.argv[0]) + { + consoleErr << av.argv[0] << ": "; + } + consoleErr << "--pidfile must be used with --daemon" << endl; + return EXIT_FAILURE; + } + + if(daemonize) + { + configureDaemon(changeDirectory, closeFiles, pidFile); + } +#endif + + // + // If no logger has been set yet, we set it to the process logger. If the + // process logger is the default logger, we change it to a logger which is + // using the program name for the prefix. + // + if(!_logger) + { + _logger = getProcessLogger(); + if(ICE_DYNAMIC_CAST(LoggerI, _logger)) + { + const bool convert = + initData.properties->getPropertyAsIntWithDefault("Ice.LogStdErr.Convert", 1) > 0 && + initData.properties->getProperty("Ice.StdErr").empty(); + + _logger = ICE_MAKE_SHARED(LoggerI, initData.properties->getProperty("Ice.ProgramName"), "", convert); + setProcessLogger(_logger); + } + } + + return run(av.argc, av.argv, initData, version); +} + +#ifdef _WIN32 +int +Ice::Service::main(int argc, const wchar_t* const argv[], const InitializationData& initializationData, int version) +{ + return main(Ice::argsToStringSeq(argc, argv), initializationData, version); +} +#endif + +int +Ice::Service::main(const StringSeq& args, const InitializationData& initData, int version) +{ + IceInternal::ArgVector av(args); + return main(av.argc, av.argv, initData, version); +} + +Ice::CommunicatorPtr +Ice::Service::communicator() const +{ + return _communicator; +} + +Ice::Service* +Ice::Service::instance() +{ + return _instance; +} + +bool +Ice::Service::service() const +{ + return _service; +} + +string +Ice::Service::name() const +{ + return _name; +} + +#ifdef _WIN32 +int +Ice::Service::run(int argc, const wchar_t* const argv[], const InitializationData& initData, int version) +{ + StringSeq args = Ice::argsToStringSeq(argc, argv); + IceInternal::ArgVector av(args); + return run(av.argc, av.argv, initData, version); +} +#endif + +int +Ice::Service::run(int argc, const char* const argv[], const InitializationData& initData, int version) +{ + IceInternal::ArgVector av(argc, argv); // copy args + + if(_service) + { +#ifdef _WIN32 + return runService(av.argc, av.argv, initData); +#else + return runDaemon(av.argc, av.argv, initData, version); +#endif + } + + // + // Run as a foreground process. + // + int status = EXIT_FAILURE; + try + { + // + // Create the CtrlCHandler after any potential forking so that signals + // are initialized properly. We do this before initializing the + // communicator because we need to ensure that this is done before any + // additional threads are created. + // + _ctrlCHandler = new IceUtil::CtrlCHandler; + + // + // Initialize the communicator. + // + _communicator = initializeCommunicator(av.argc, av.argv, initData, version); + + // + // Use the configured logger. + // + _logger = _communicator->getLogger(); + + // + // Determines whether we ignore SIGHUP/CTRL_LOGOFF_EVENT. + // + _nohup = _communicator->getProperties()->getPropertyAsIntWithDefault("Ice.Nohup", 1) > 0; + + // + // Start the service. + // + if(start(av.argc, av.argv, status)) + { +#ifdef ICE_USE_SYSTEMD + sd_notify(0, "READY=1"); +#endif + // + // Wait for service shutdown. + // + waitForShutdown(); + +#ifdef ICE_USE_SYSTEMD + // + // Inform the service manager that the service is beginning its shutdown. + // + sd_notify(0, "STOPPING=1"); +#endif + // + // Stop the service. + // + if(stop()) + { + status = EXIT_SUCCESS; + } + } + } + catch(const Ice::Exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; +#ifdef ICE_USE_SYSTEMD + const string msg = err.str(); + sd_notifyf(0, "STATUS=Failed service terminating after catching exception: %s", msg.c_str()); +#endif + } + catch(const std::exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; +#ifdef ICE_USE_SYSTEMD + const string msg = err.str(); + sd_notifyf(0, "STATUS=Failed service terminating after catching exception: %s", msg.c_str()); +#endif + } + catch(const std::string& msg) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << msg; +#ifdef ICE_USE_SYSTEMD + sd_notifyf(0, "STATUS=Failed service terminating after catching exception: %s", msg.c_str()); +#endif + } + catch(const char* msg) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << msg; +#ifdef ICE_USE_SYSTEMD + sd_notifyf(0, "STATUS=Failed service terminating after catching exception: %s", msg); +#endif + } + catch(...) + { + error("service terminating after catching unknown exception"); +#ifdef ICE_USE_SYSTEMD + sd_notify(0, "STATUS=Failed service terminating after catching unknown exception"); +#endif + } + + if(_communicator) + { + _communicator->destroy(); + } + + return status; +} + +#ifdef _WIN32 + +void +Ice::Service::configureService(const string& name) +{ + _service = true; + _name = name; +} + +void +Ice::Service::setModuleHandle(HMODULE module) +{ + SMEventLoggerI::setModuleHandle(module); +} + +#else + +void +Ice::Service::configureDaemon(bool changeDirectory, bool closeFiles, const string& pidFile) +{ + _service = true; + _changeDirectory = changeDirectory; + _closeFiles = closeFiles; + _pidFile = pidFile; +} + +#endif + +void +Ice::Service::handleInterrupt(int sig) +{ +#ifdef _WIN32 + if(_nohup && sig == CTRL_LOGOFF_EVENT) + { + return; + } +#else + if(_nohup && sig == SIGHUP) + { + return; + } +#endif + + interrupt(); +} + +void +Ice::Service::waitForShutdown() +{ + if(_communicator) + { + enableInterrupt(); + _communicator->waitForShutdown(); + disableInterrupt(); + } +} + +bool +Ice::Service::stop() +{ + return true; +} + +Ice::CommunicatorPtr +Ice::Service::initializeCommunicator(int& argc, char* argv[], const InitializationData& initData, int version) +{ + return Ice::initialize(argc, argv, initData, version); +} + +void +Ice::Service::syserror(const string& msg) +{ + string errmsg = IceUtilInternal::lastErrorToString(); + if(_logger) + { + ostringstream ostr; + if(!msg.empty()) + { + ostr << msg << endl; + } + if(!errmsg.empty()) + { + ostr << errmsg; + } + _logger->error(ostr.str()); + } + else + { + if(!_name.empty()) + { + consoleErr << _name << ": "; + } + if(!msg.empty()) + { + consoleErr << msg << endl; + } + if(!errmsg.empty()) + { + consoleErr << errmsg; + } + } +} + +void +Ice::Service::error(const string& msg) +{ + if(_logger) + { + _logger->error(msg); + } + else + { + if(!_name.empty()) + { + consoleErr << _name << ": "; + } + consoleErr << "error: " << msg << endl; + } +} + +void +Ice::Service::warning(const string& msg) +{ + if(_logger) + { + _logger->warning(msg); + } + else + { + if(!_name.empty()) + { + consoleErr << _name << ": "; + } + consoleErr << "warning: " << msg << endl; + } +} + +void +Ice::Service::trace(const string& msg) +{ + if(_logger) + { + _logger->trace("", msg); + } + else + { + consoleErr << msg << endl; + } +} + +void +Ice::Service::print(const string& msg) +{ + if(_logger) + { + _logger->print(msg); + } + else + { + consoleErr << msg << endl; + } +} + +void +Ice::Service::enableInterrupt() +{ + _ctrlCHandler->setCallback(ctrlCHandlerCallback); +} + +void +Ice::Service::disableInterrupt() +{ + _ctrlCHandler->setCallback(0); +} + +#ifdef _WIN32 + +int +Ice::Service::runService(int argc, const char* const argv[], const InitializationData& initData) +{ + assert(_service); + + if(_name.empty()) + { + error("invalid name for Win32 service"); + return EXIT_FAILURE; + } + + // + // Arguments passed to the executable are not passed to the service's main function, + // so save them now and serviceMain will merge them later. + // + for(int idx = 1; idx < argc; ++idx) + { + _serviceArgs.push_back(argv[idx]); + } + + _initData = initData; + + // + // Don't need to use a wide string converter as the wide string is passed + // to Windows API. + // + const wstring serviceName = stringToWstring(_name, getProcessStringConverter()); + SERVICE_TABLE_ENTRYW ste[] = + { + { const_cast(serviceName.c_str()), Ice_Service_ServiceMain }, + { 0, 0 }, + }; + + // + // Start the service. + // + if(!StartServiceCtrlDispatcherW(ste)) + { + syserror("unable to start service control dispatcher"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +void +Ice::Service::terminateService(DWORD exitCode) +{ + serviceStatusManager->stopUpdate(); + delete serviceStatusManager; + serviceStatusManager = 0; + + SERVICE_STATUS status; + + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + status.dwCurrentState = SERVICE_STOPPED; + status.dwControlsAccepted = 0; + if(exitCode != 0) + { + status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; + } + else + { + status.dwWin32ExitCode = 0; + } + status.dwServiceSpecificExitCode = exitCode; + status.dwCheckPoint = 0; + status.dwWaitHint = 0; + + SetServiceStatus(_statusHandle, &status); +} + +bool +Ice::Service::waitForServiceState(SC_HANDLE hService, DWORD pendingState, SERVICE_STATUS& status) +{ + if(!QueryServiceStatus(hService, &status)) + { + return false; + } + + // + // Save the tick count and initial checkpoint. + // + DWORD startTickCount = GetTickCount(); + DWORD oldCheckPoint = status.dwCheckPoint; + + // + // Loop while the service is in the pending state. + // + while(status.dwCurrentState == pendingState) + { + // + // Do not wait longer than the wait hint. A good interval is + // one tenth the wait hint, but no less than 1 second and no + // more than 10 seconds. + // + + DWORD waitTime = status.dwWaitHint / 10; + + if(waitTime < 1000) + { + waitTime = 1000; + } + else if(waitTime > 10000) + { + waitTime = 10000; + } + + Sleep(waitTime); + + // + // Check the status again. + // + if(!QueryServiceStatus(hService, &status)) + { + return false; + } + + if(status.dwCheckPoint > oldCheckPoint) + { + // + // The service is making progress. + // + startTickCount = GetTickCount(); + oldCheckPoint = status.dwCheckPoint; + } + else + { + if(GetTickCount() - startTickCount > status.dwWaitHint) + { + // + // No progress made within the wait hint. + // + break; + } + } + } + + return true; +} + +void +Ice::Service::showServiceStatus(const string& msg, SERVICE_STATUS& status) +{ + string state; + switch(status.dwCurrentState) + { + case SERVICE_STOPPED: + state = "STOPPED"; + break; + case SERVICE_START_PENDING: + state = "START PENDING"; + break; + case SERVICE_STOP_PENDING: + state = "STOP PENDING"; + break; + case SERVICE_RUNNING: + state = "RUNNING"; + break; + case SERVICE_CONTINUE_PENDING: + state = "CONTINUE PENDING"; + break; + case SERVICE_PAUSE_PENDING: + state = "PAUSE PENDING"; + break; + case SERVICE_PAUSED: + state = "PAUSED"; + break; + default: + state = "UNKNOWN"; + break; + } + + ServiceTrace tr(this); + tr << msg + << "\n Current state: " << state + << "\n Exit code: " << status.dwWin32ExitCode + << "\n Service specific exit code: " << status.dwServiceSpecificExitCode + << "\n Check point: " << status.dwCheckPoint + << "\n Wait hint: " << status.dwWaitHint; +} + +void +Ice::Service::serviceMain(int argc, const wchar_t* const argv[]) +{ + _ctrlCHandler = new IceUtil::CtrlCHandler; + + // + // Register the control handler function. + // + _statusHandle = RegisterServiceCtrlHandlerW(argv[0], Ice_Service_CtrlHandler); + if(_statusHandle == 0) + { + syserror("unable to register service control handler"); + return; + } + + // + // Create the service status manager and start a thread to periodically + // update the service's status with the service control manager (SCM). + // The SCM must receive periodic updates otherwise it assumes that + // initialization failed and terminates the service. + // + serviceStatusManager = new ServiceStatusManager(_statusHandle); + serviceStatusManager->startUpdate(SERVICE_START_PENDING); + + // + // Don't need to pass a wide string converter in the argv conversions + // as argv come from Windows API. + // + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); + + // + // Merge the executable's arguments with the service's arguments. + // + char** args = new char*[_serviceArgs.size() + argc]; + + // + // First argument is argv[0] the serviceName + // + const string serviceName = wstringToString(argv[0], converter); + args[0] = const_cast(serviceName.c_str()); + + int i = 1; + for(vector::iterator p = _serviceArgs.begin(); p != _serviceArgs.end(); ++p) + { + args[i++] = const_cast(p->c_str()); + } + + // + // Convert wide string wchar_t** argv to a sequence of narrow strings and merge + // the converted sequence into the args array. + // + vector executableArgs; + for(int j = 1; j < argc; ++j) + { + executableArgs.push_back(IceUtil::wstringToString(argv[j], converter)); + } + for(vector::iterator p = executableArgs.begin(); p != executableArgs.end(); ++p) + { + args[i++] = const_cast(p->c_str()); + } + argc += static_cast(_serviceArgs.size()); + + // + // If we can't initialize a communicator, then stop immediately. + // + try + { + _communicator = initializeCommunicator(argc, args, _initData, ICE_INT_VERSION); + } + catch(const Ice::Exception& ex) + { + delete[] args; + { + ServiceError err(this); + err << "exception occurred while initializing a communicator:\n" << ex; + } + terminateService(EXIT_FAILURE); + return; + } + catch(...) + { + delete[] args; + error("unknown exception occurred while initializing a communicator"); + terminateService(EXIT_FAILURE); + return; + } + + // + // Use the configured logger. + // + _logger = _communicator->getLogger(); + + // + // Determines whether we ignore SIGHUP/CTRL_LOGOFF_EVENT. + // + _nohup = _communicator->getProperties()->getPropertyAsIntWithDefault("Ice.Nohup", 1) > 0; + + DWORD status = EXIT_FAILURE; + try + { + int tmpStatus = EXIT_FAILURE; + if(start(argc, args, tmpStatus)) + { + trace("Service started successfully."); + + // + // Change the current status from START_PENDING to RUNNING. + // + serviceStatusManager->stopUpdate(); + serviceStatusManager->changeStatus(SERVICE_RUNNING, SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + + // + // Wait for the service to be shut down. + // + waitForShutdown(); + + // + // Give the service a chance to clean up. + // + if(stop()) + { + status = EXIT_SUCCESS; + } + } + else + { + status = tmpStatus; + } + } + catch(const Ice::Exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; + } + catch(const std::exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; + } + catch(...) + { + error("service terminating after catching unknown exception"); + } + + delete[] args; + + assert(_communicator); + _communicator->destroy(); + + terminateService(status); +} + +void +Ice::Service::control(int ctrl) +{ + assert(serviceStatusManager); + + switch(ctrl) + { + case SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL_STOP: + { + serviceStatusManager->startUpdate(SERVICE_STOP_PENDING); + shutdown(); + break; + } + default: + { + if(ctrl != SERVICE_CONTROL_INTERROGATE) + { + ServiceError err(this); + err << "unrecognized service control code " << ctrl; + } + + serviceStatusManager->reportStatus(); + break; + } + } +} + +ServiceStatusManager::ServiceStatusManager(SERVICE_STATUS_HANDLE handle) : + _handle(handle), _stopped(false) +{ + _status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + _status.dwControlsAccepted = 0; + _status.dwWin32ExitCode = 0; + _status.dwServiceSpecificExitCode = 0; + _status.dwCheckPoint = 0; + _status.dwWaitHint = 0; +} + +void +ServiceStatusManager::startUpdate(DWORD state) +{ + Lock sync(*this); + + assert(state == SERVICE_START_PENDING || state == SERVICE_STOP_PENDING); + assert(!_thread); + + _status.dwCurrentState = state; + _status.dwControlsAccepted = 0; // Don't accept any other control messages while pending. + + _stopped = false; + + _thread = new StatusThread(this); + _thread->start(); +} + +void +ServiceStatusManager::stopUpdate() +{ + IceUtil::ThreadPtr thread; + + { + Lock sync(*this); + + if(_thread) + { + _stopped = true; + notify(); + thread = _thread; + _thread = 0; + } + } + + if(thread) + { + thread->getThreadControl().join(); + } +} + +void +ServiceStatusManager::changeStatus(DWORD state, DWORD controlsAccepted) +{ + Lock sync(*this); + + _status.dwCurrentState = state; + _status.dwControlsAccepted = controlsAccepted; + + SetServiceStatus(_handle, &_status); +} + +void +ServiceStatusManager::reportStatus() +{ + Lock sync(*this); + + SetServiceStatus(_handle, &_status); +} + +void +ServiceStatusManager::run() +{ + Lock sync(*this); + + IceUtil::Time delay = IceUtil::Time::milliSeconds(1000); + _status.dwWaitHint = 2000; + _status.dwCheckPoint = 0; + + while(!_stopped) + { + _status.dwCheckPoint++; + SetServiceStatus(_handle, &_status); + timedWait(delay); + } +} + +#else + +int +Ice::Service::runDaemon(int argc, char* argv[], const InitializationData& initData, int version) +{ + assert(_service); + + // + // Create a pipe that is used to notify the parent when the child is ready. + // + SOCKET fds[2]; + IceInternal::createPipe(fds); + + // + // Fork the child. + // + pid_t pid = fork(); + if(pid < 0) + { + if(argv[0]) + { + consoleErr << argv[0] << ": "; + } + consoleErr << IceUtilInternal::errorToString(errno) << endl; + return EXIT_FAILURE; + } + + if(pid != 0) + { + // + // Parent process. + // + + // + // Close an unused end of the pipe. + // + close(fds[1]); + + // + // Wait for the child to write a byte to the pipe to indicate that it + // is ready to receive requests, or that an error occurred. + // + char c = 0; + while(true) + { + if(read(fds[0], &c, 1) == -1) + { + if(IceInternal::interrupted()) + { + continue; + } + + if(argv[0]) + { + consoleErr << argv[0] << ": "; + } + consoleErr << IceUtilInternal::errorToString(errno) << endl; + _exit(EXIT_FAILURE); + } + break; + } + + if(c != 0) + { + // + // Read an error message. + // + ssize_t rs; + char s[16]; + string message; + while((rs = read(fds[0], &s, 16)) > 0) + { + message.append(s, static_cast(rs)); + } + + if(argv[0]) + { + consoleErr << argv[0] << ": "; + } + + if(rs == -1) + { + consoleErr << "I/O error while reading error message from child:\n" << IceUtilInternal::errorToString(errno); + } + else + { + consoleErr << "failure occurred in daemon"; + if(!message.empty()) + { + consoleErr << ":\n" << message; + } + } + consoleErr << endl; + _exit(EXIT_FAILURE); + } + + _exit(EXIT_SUCCESS); + } + + // + // Child process. + // + + string errMsg; + int status = EXIT_FAILURE; + try + { + // + // Become a session and process group leader. + // + if(setsid() == -1) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + + // + // Ignore SIGHUP so that the grandchild process is not sent SIGHUP when this + // process exits. + // + signal(SIGHUP, SIG_IGN); + + // + // Fork again to eliminate the possibility of acquiring a controlling terminal. + // + pid = fork(); + if(pid < 0) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + if(pid != 0) + { + exit(0); + } + + if(_changeDirectory) + { + // + // Change the working directory. + // + if(chdir("/") != 0) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + } + + vector fdsToClose; + if(_closeFiles) + { + // + // Take a snapshot of the open file descriptors. We don't actually close these + // descriptors until after the communicator is initialized, so that plug-ins + // have an opportunity to use stdin/stdout/stderr if necessary. This also + // conveniently allows the Ice.PrintProcessId property to work as expected. + // + int fdMax = static_cast(sysconf(_SC_OPEN_MAX)); + if(fdMax <= 0) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + + for(int i = 0; i < fdMax; ++i) + { + if(fcntl(i, F_GETFL) != -1) + { + // + // Don't close the write end of the pipe. + // + if(i != fds[1]) + { + fdsToClose.push_back(i); + } + } + } + } + + // + // Create the CtrlCHandler after forking the child so that signals are initialized + // properly. We do this before initializing the communicator because we need to + // ensure that signals are initialized before additional threads are created. The + // communicator thread pools currently use lazy initialization, but a thread can + // be created to monitor connections. + // + _ctrlCHandler = new IceUtil::CtrlCHandler; + + // + // Initialize the communicator. + // + _communicator = initializeCommunicator(argc, argv, initData, version); + + if(_closeFiles) + { + // + // Close unnecessary file descriptors. + // + PropertiesPtr properties = _communicator->getProperties(); + string stdOut = properties->getProperty("Ice.StdOut"); + string stdErr = properties->getProperty("Ice.StdErr"); + + for(vector::const_iterator p = fdsToClose.begin(); p != fdsToClose.end(); ++p) + { + // + // NOTE: Do not close stdout if Ice.StdOut is defined. Likewise for Ice.StdErr. + // + if((*p == 1 && !stdOut.empty()) || (*p == 2 && !stdErr.empty())) + { + continue; + } + close(*p); + } + + // + // Associate stdin, stdout and stderr with /dev/null. + // + int fd = open("/dev/null", O_RDWR); + assert(fd == 0); + if(fd != 0) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + if(stdOut.empty()) + { + fd = dup2(0, 1); + assert(fd == 1); + if(fd != 1) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + } + if(stdErr.empty()) + { + fd = dup2(1, 2); + assert(fd == 2); + if(fd != 2) + { + throw SyscallException(__FILE__, __LINE__, IceInternal::getSystemErrno()); + } + } + } + + // + // Write PID + // + if(_pidFile.size() > 0) + { + ofstream of(_pidFile.c_str()); + of << getpid() << endl; + + if(!of) + { + warning("Could not write PID file " + _pidFile); + } + } + + // + // Use the configured logger. + // + _logger = _communicator->getLogger(); + + // + // Start the service. + // + if(start(argc, argv, status)) + { + // + // Notify the parent that the child is ready. + // + char c = 0; + while(true) + { + if(write(fds[1], &c, 1) == -1) + { + if(IceInternal::interrupted()) + { + continue; + } + } + break; + } + close(fds[1]); + fds[1] = -1; + + // + // Wait for service shutdown. + // + waitForShutdown(); + + // + // Stop the service. + // + if(stop()) + { + status = EXIT_SUCCESS; + } + } + } + catch(const Ice::Exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; + errMsg = err.str(); + } + catch(const std::exception& ex) + { + ServiceError err(this); + err << "service terminating after catching exception:\n" << ex; + errMsg = err.str(); + } + catch(...) + { + errMsg = "service terminating after catching unknown exception"; + error(errMsg); + } + + // + // If the service failed and the pipe to the parent is still open, + // then send an error notification to the parent. + // + if(status != EXIT_SUCCESS && fds[1] != -1) + { + char c = 1; + while(true) + { + if(write(fds[1], &c, 1) == -1) + { + if(IceInternal::interrupted()) + { + continue; + } + } + break; + } + const char* msg = errMsg.c_str(); + size_t len = strlen(msg) + 1; // Include null byte + size_t pos = 0; + while(len > 0) + { + ssize_t n = write(fds[1], &msg[pos], len); + if(n == -1) + { + if(IceInternal::interrupted()) + { + continue; + } + else + { + break; + } + } + len -= static_cast(n); + pos += static_cast(n); + } + close(fds[1]); + } + + if(_communicator) + { + _communicator->destroy(); + } + + return status; +} + +#endif diff --git a/Sources/IceCpp/Shared.cpp b/Sources/IceCpp/Shared.cpp new file mode 100644 index 0000000..a385e19 --- /dev/null +++ b/Sources/IceCpp/Shared.cpp @@ -0,0 +1,71 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace IceUtil; + +// +// Flag constant used by the Shared class. Derived classes +// such as GCObject define more flag constants. +// +const unsigned char IceUtil::Shared::NoDelete = 1; + +IceUtil::SimpleShared::SimpleShared() : + _ref(0), + _noDelete(false) +{ +} + +IceUtil::SimpleShared::SimpleShared(const SimpleShared&) : + _ref(0), + _noDelete(false) +{ +} + +IceUtil::SimpleShared::~SimpleShared() +{ + // Out of line to avoid weak vtable +} + +IceUtil::Shared::Shared() : + _ref(0), + _flags(0) +{ +} + +IceUtil::Shared::Shared(const Shared&) : + _ref(0), + _flags(0) +{ +} + +void +IceUtil::Shared::__incRef() +{ + assert(_ref >= 0); + ++_ref; +} + +void +IceUtil::Shared::__decRef() +{ + assert(_ref > 0); + if(--_ref == 0 && !(_flags & NoDelete)) + { + delete this; + } +} + +int +IceUtil::Shared::__getRef() const +{ + return _ref; +} + +void +IceUtil::Shared::__setNoDelete(bool b) +{ + _flags = b ? (_flags | NoDelete) : (_flags & ~NoDelete); +} diff --git a/Sources/IceCpp/SliceChecksumDict.cpp b/Sources/IceCpp/SliceChecksumDict.cpp new file mode 100644 index 0000000..f77f104 --- /dev/null +++ b/Sources/IceCpp/SliceChecksumDict.cpp @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `SliceChecksumDict.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#else // C++98 mapping + +#endif diff --git a/Sources/IceCpp/SliceChecksums.cpp b/Sources/IceCpp/SliceChecksums.cpp new file mode 100644 index 0000000..3bd6cf6 --- /dev/null +++ b/Sources/IceCpp/SliceChecksums.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace std; +using namespace Ice; + +namespace +{ + +SliceChecksumDict* _sliceChecksums = 0; + +IceUtil::Mutex* _mutex = 0; + +class Init +{ +public: + + Init() + { + _mutex = new IceUtil::Mutex; + } + + ~Init() + { + delete _mutex; + _mutex = 0; + } +}; + +Init init; + +class SliceChecksumDictDestroyer +{ +public: + + ~SliceChecksumDictDestroyer() + { + delete _sliceChecksums; + _sliceChecksums = 0; + } +}; + +SliceChecksumDictDestroyer destroyer; + +} + +SliceChecksumDict +Ice::sliceChecksums() +{ + IceUtilInternal::MutexPtrLock lock(_mutex); + if(_sliceChecksums == 0) + { + _sliceChecksums = new SliceChecksumDict(); + } + return *_sliceChecksums; +} + +IceInternal::SliceChecksumInit::SliceChecksumInit(const char* checksums[]) +{ + IceUtilInternal::MutexPtrLock lock(_mutex); + if(_sliceChecksums == 0) + { + _sliceChecksums = new SliceChecksumDict(); + } + + for(int i = 0; checksums[i] != 0; i += 2) + { + _sliceChecksums->insert(SliceChecksumDict::value_type(checksums[i], checksums[i + 1])); + } +} diff --git a/Sources/IceCpp/SlicedData.cpp b/Sources/IceCpp/SlicedData.cpp new file mode 100644 index 0000000..43b5338 --- /dev/null +++ b/Sources/IceCpp/SlicedData.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace std; +using namespace Ice; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* Ice::upCast(SliceInfo* p) { return p; } +IceUtil::Shared* Ice::upCast(SlicedData* p) { return p; } +IceUtil::Shared* Ice::upCast(UnknownSlicedValue* p) { return p; } + +Ice::SlicedData::~SlicedData() +{ + // Out of line to avoid weak vtable +} +#endif + +Ice::SlicedData::SlicedData(const SliceInfoSeq& seq) : + slices(seq) +{ +} + +void +Ice::SlicedData::clear() +{ + SliceInfoSeq tmp; + tmp.swap(const_cast(slices)); + for(SliceInfoSeq::const_iterator p = tmp.begin(); p != tmp.end(); ++p) + { + for(vector::const_iterator q = (*p)->instances.begin(); q != (*p)->instances.end(); ++q) + { + Ice::SlicedDataPtr slicedData = (*q)->ice_getSlicedData(); + if(slicedData) + { + slicedData->clear(); + } + } + } +} + +#ifndef ICE_CPP11_MAPPING +void +Ice::SlicedData::_iceGcVisitMembers(IceInternal::GCVisitor& visitor) +{ + // + // Iterate over the object references in each preserved slice. + // + for(SliceInfoSeq::const_iterator p = slices.begin(); p != slices.end(); ++p) + { + for(vector::iterator q = (*p)->instances.begin(); q != (*p)->instances.end(); ++q) + { + if(q->get()->_iceGcVisit(visitor)) + { + *q = 0; + } + } + } +} +#endif + +Ice::UnknownSlicedValue::UnknownSlicedValue(const string& unknownTypeId) : _unknownTypeId(unknownTypeId) +{ +} + +SlicedDataPtr +Ice::UnknownSlicedValue::ice_getSlicedData() const +{ + return _slicedData; +} + +#ifdef ICE_CPP11_MAPPING + +string +Ice::UnknownSlicedValue::ice_id() const +{ + return _unknownTypeId; +} + +shared_ptr +Ice::UnknownSlicedValue::ice_clone() const +{ + return static_pointer_cast(_iceCloneImpl()); +} + +shared_ptr +Ice::UnknownSlicedValue::_iceCloneImpl() const +{ + return make_shared(static_cast(*this)); +} + +#else + +const string& +Ice::UnknownSlicedValue::ice_id(const Current&) const +{ + return _unknownTypeId; +} + +void +Ice::UnknownSlicedValue::_iceGcVisitMembers(IceInternal::GCVisitor& _v) +{ + if(_slicedData) + { + _slicedData->_iceGcVisitMembers(_v); + } +} + +#endif + +void +Ice::UnknownSlicedValue::_iceWrite(Ice::OutputStream* ostr) const +{ + ostr->startValue(_slicedData); + ostr->endValue(); +} + +void +Ice::UnknownSlicedValue::_iceRead(Ice::InputStream* istr) +{ + istr->startValue(); + _slicedData = istr->endValue(true); +} diff --git a/Sources/IceCpp/StreamAcceptor.cpp b/Sources/IceCpp/StreamAcceptor.cpp new file mode 100644 index 0000000..20dcb09 --- /dev/null +++ b/Sources/IceCpp/StreamAcceptor.cpp @@ -0,0 +1,154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "StreamTransceiver.h" +#include "StreamEndpointI.h" +#include "StreamAcceptor.h" + +#include + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +NativeInfoPtr +IceObjC::StreamAcceptor::getNativeInfo() +{ + return this; +} + +void +IceObjC::StreamAcceptor::close() +{ + if(_fd != INVALID_SOCKET) + { + closeSocketNoThrow(_fd); + _fd = INVALID_SOCKET; + } +} + +EndpointIPtr +IceObjC::StreamAcceptor::listen() +{ + try + { + const_cast(_addr) = doBind(_fd, _addr); + doListen(_fd, _backlog); + } + catch(...) + { + _fd = INVALID_SOCKET; + throw; + } + + _endpoint = _endpoint->endpoint(this); + return _endpoint; +} + +TransceiverPtr +IceObjC::StreamAcceptor::accept() +{ + SOCKET fd = doAccept(_fd); + setBlock(fd, false); + setTcpBufSize(fd, _instance); + + // + // Create the read/write streams + // + UniqueRef readStream; + UniqueRef writeStream; + try + { + CFStreamCreatePairWithSocket(ICE_NULLPTR, fd, &readStream.get(), &writeStream.get()); + _instance->setupStreams(readStream.get(), writeStream.get(), true, ""); + return new StreamTransceiver(_instance, readStream.release(), writeStream.release(), fd); + } + catch(const Ice::LocalException& ex) + { + if(fd != INVALID_SOCKET) + { + closeSocketNoThrow(fd); + } + throw; + } +} + +string +IceObjC::StreamAcceptor::protocol() const +{ + return _instance->protocol(); +} + +string +IceObjC::StreamAcceptor::toString() const +{ + return addrToString(_addr); +} + +string +IceObjC::StreamAcceptor::toDetailedString() const +{ + ostringstream os; + os << "local address = " << toString(); + vector intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true); + if(!intfs.empty()) + { + os << "\nlocal interfaces = "; + os << IceUtilInternal::joinString(intfs, ", "); + } + return os.str(); +} + +int +IceObjC::StreamAcceptor::effectivePort() const +{ + return getPort(_addr); +} + +IceObjC::StreamAcceptor::StreamAcceptor(const StreamEndpointIPtr& endpoint, + const InstancePtr& instance, + const string& host, + int port) : + _endpoint(endpoint), + _instance(instance), + _addr(getAddressForServer(host, port, instance->protocolSupport(), instance->preferIPv6(), true)) +{ +#ifdef SOMAXCONN + _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); +#else + _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511); +#endif + + try + { + _fd = createSocket(false, _addr); + setBlock(_fd, false); + setTcpBufSize(_fd, _instance); + setReuseAddress(_fd, true); + } + catch(...) + { + _fd = INVALID_SOCKET; + throw; + } +} + +IceObjC::StreamAcceptor::~StreamAcceptor() +{ + assert(_fd == INVALID_SOCKET); +} + +#endif diff --git a/Sources/IceCpp/StreamAcceptor.h b/Sources/IceCpp/StreamAcceptor.h new file mode 100644 index 0000000..ca706cf --- /dev/null +++ b/Sources/IceCpp/StreamAcceptor.h @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_ACCEPTOR_H +#define ICE_STREAM_ACCEPTOR_H + +#include +#include + +namespace IceObjC +{ + +class StreamEndpointI; +#ifdef ICE_CPP11_MAPPING // C++11 mapping +typedef ::std::shared_ptr StreamEndpointIPtr; +#else +typedef IceUtil::Handle StreamEndpointIPtr; +#endif + +class StreamAcceptor : public IceInternal::Acceptor, public IceInternal::NativeInfo +{ +public: + + virtual IceInternal::NativeInfoPtr getNativeInfo(); + virtual void close(); + virtual IceInternal::EndpointIPtr listen(); + virtual IceInternal::TransceiverPtr accept(); + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + + int effectivePort() const; + +private: + + StreamAcceptor(const StreamEndpointIPtr&, const InstancePtr&, const std::string&, int); + virtual ~StreamAcceptor(); + friend class StreamEndpointI; + + StreamEndpointIPtr _endpoint; + InstancePtr _instance; + int _backlog; + IceInternal::Address _addr; +}; + +} + +#endif diff --git a/Sources/IceCpp/StreamConnector.cpp b/Sources/IceCpp/StreamConnector.cpp new file mode 100644 index 0000000..e69f4cd --- /dev/null +++ b/Sources/IceCpp/StreamConnector.cpp @@ -0,0 +1,146 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "StreamTransceiver.h" +#include "StreamEndpointI.h" +#include "StreamConnector.h" + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +TransceiverPtr +IceObjC::StreamConnector::connect() +{ + UniqueRef readStream; + UniqueRef writeStream; + UniqueRef h(CFStringCreateWithCString(ICE_NULLPTR, _host.c_str(), kCFStringEncodingUTF8)); + UniqueRef host(CFHostCreateWithName(ICE_NULLPTR, h.get())); + CFStreamCreatePairWithSocketToCFHost(ICE_NULLPTR, host.get(), _port, &readStream.get(), &writeStream.get()); + _instance->setupStreams(readStream.get(), writeStream.get(), false, _host); + return new StreamTransceiver(_instance, readStream.release(), writeStream.release(), _host, _port); +} + +Short +IceObjC::StreamConnector::type() const +{ + return _instance->type(); +} + +string +IceObjC::StreamConnector::toString() const +{ + string proxyHost = _instance->proxyHost(); + ostringstream os; + if(!proxyHost.empty()) + { + os << proxyHost << ":" << _instance->proxyPort(); + } + else + { + os << _host << ":" << _port; + } + return os.str(); +} + +bool +IceObjC::StreamConnector::operator==(const IceInternal::Connector& r) const +{ + const StreamConnector* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + if(_host != p->_host) + { + return false; + } + + if(_port != p->_port) + { + return false; + } + + return true; +} + +bool +IceObjC::StreamConnector::operator<(const IceInternal::Connector& r) const +{ + const StreamConnector* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + + if(_host < p->_host) + { + return true; + } + else if(p->_host < _host) + { + return false; + } + + return _port < p->_port; +} + +IceObjC::StreamConnector::StreamConnector(const InstancePtr& instance, + const string& host, + Ice::Int port, + Ice::Int timeout, + const string& connectionId) : + _instance(instance), + _host(host.empty() ? string("127.0.0.1") : host), + _port(port), + _timeout(timeout), + _connectionId(connectionId) +{ +} + +IceObjC::StreamConnector::~StreamConnector() +{ +} +#endif diff --git a/Sources/IceCpp/StreamConnector.h b/Sources/IceCpp/StreamConnector.h new file mode 100644 index 0000000..bbdaa2a --- /dev/null +++ b/Sources/IceCpp/StreamConnector.h @@ -0,0 +1,52 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_CONNECTOR_H +#define ICE_STREAM_CONNECTOR_H + +#include + +#if TARGET_OS_IPHONE != 0 + +#include +#include + +namespace IceObjC +{ + +class StreamEndpointI; + +class Instance; +typedef IceUtil::Handle InstancePtr; + +class StreamConnector : public IceInternal::Connector +{ +public: + + virtual IceInternal::TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const IceInternal::Connector&) const; + virtual bool operator<(const IceInternal::Connector&) const; + +private: + + StreamConnector(const InstancePtr&, const std::string&, Ice::Int, Ice::Int, const std::string&); + virtual ~StreamConnector(); + friend class StreamEndpointI; + + const InstancePtr _instance; + const std::string _host; + const Ice::Int _port; + const Ice::Int _timeout; + const std::string _connectionId; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/StreamEndpointI.cpp b/Sources/IceCpp/StreamEndpointI.cpp new file mode 100644 index 0000000..01aa7ec --- /dev/null +++ b/Sources/IceCpp/StreamEndpointI.cpp @@ -0,0 +1,477 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "StreamEndpointI.h" +#include "StreamAcceptor.h" +#include "StreamConnector.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +extern "C" +{ + +Plugin* +createIceTCP(const CommunicatorPtr& com, const string&, const StringSeq&) +{ + IceObjC::InstancePtr tcpInstance = new IceObjC::Instance(com, TCPEndpointType, "tcp", false); + return new EndpointFactoryPlugin(com, new IceObjC::StreamEndpointFactory(tcpInstance)); +} + +} + +#if TARGET_IPHONE_SIMULATOR == 0 +namespace +{ + +inline CFStringRef +toCFString(const string& s) +{ + return CFStringCreateWithCString(ICE_NULLPTR, s.c_str(), kCFStringEncodingUTF8); +} + +} +#endif + +IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const string& protocol, bool secure) : + ProtocolInstance(com, type, protocol, secure), + _communicator(com), + _proxySettings(0) +{ + const Ice::PropertiesPtr properties = com->getProperties(); + + // + // Proxy settings + // + _proxyHost = properties->getProperty("Ice.SOCKSProxyHost"); + if(!_proxyHost.empty()) + { +#if TARGET_IPHONE_SIMULATOR != 0 + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__, "SOCKS proxy not supported"); +#else + _proxySettings.reset(CFDictionaryCreateMutable(0, 3, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + + _proxyPort = properties->getPropertyAsIntWithDefault("Ice.SOCKSProxyPort", 1080); + + UniqueRef host(toCFString(_proxyHost)); + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSProxyHost, host.get()); + + UniqueRef port(CFNumberCreate(0, kCFNumberSInt32Type, &_proxyPort)); + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSProxyPort, port.get()); + + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSVersion, kCFStreamSocketSOCKSVersion4); +#endif + } +} + +IceObjC::Instance::~Instance() +{ +} + +void +IceObjC::Instance::setupStreams(CFReadStreamRef readStream, + CFWriteStreamRef writeStream, + bool server, + const string& /*host*/) const +{ + if(!server && _proxySettings) + { + if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySOCKSProxy, _proxySettings.get()) || + !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySOCKSProxy, _proxySettings.get())) + { + throw Ice::SyscallException(__FILE__, __LINE__); + } + } +} + +IceObjC::Instance* +IceObjC::Instance::clone(const ProtocolInstancePtr& instance) +{ + return new Instance(_communicator, instance->type(), instance->protocol(), instance->secure()); +} + +IceObjC::StreamEndpointI::StreamEndpointI(const InstancePtr& instance, const string& ho, Int po, + const Address& sourceAddr, Int ti, const string& conId, bool co) : + IceInternal::IPEndpointI(instance, ho, po, sourceAddr, conId), + _streamInstance(instance), + _timeout(ti), + _compress(co) +{ +} + +IceObjC::StreamEndpointI::StreamEndpointI(const InstancePtr& instance) : + IceInternal::IPEndpointI(instance), + _streamInstance(instance), + _timeout(instance->defaultTimeout()), + _compress(false) +{ +} + +IceObjC::StreamEndpointI::StreamEndpointI(const InstancePtr& instance, Ice::InputStream* s) : + IPEndpointI(instance, s), + _streamInstance(instance), + _timeout(-1), + _compress(false) +{ + s->read(const_cast(_timeout)); + s->read(const_cast(_compress)); +} + +EndpointInfoPtr +IceObjC::StreamEndpointI::getInfo() const ICE_NOEXCEPT +{ + TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, ICE_SHARED_FROM_CONST_THIS(StreamEndpointI)); + IPEndpointI::fillEndpointInfo(info.get()); + info->timeout = _timeout; + info->compress = _compress; + return info; +} + +Int +IceObjC::StreamEndpointI::timeout() const +{ + return _timeout; +} + +EndpointIPtr +IceObjC::StreamEndpointI::timeout(Int t) const +{ + if(t == _timeout) + { + return ICE_SHARED_FROM_CONST_THIS(StreamEndpointI); + } + else + { + return ICE_MAKE_SHARED(StreamEndpointI, _streamInstance, _host, _port, _sourceAddr, t, _connectionId, _compress); + } +} + +bool +IceObjC::StreamEndpointI::compress() const +{ + return _compress; +} + +EndpointIPtr +IceObjC::StreamEndpointI::compress(bool c) const +{ + if(c == _compress) + { + return ICE_SHARED_FROM_CONST_THIS(StreamEndpointI); + } + else + { + return ICE_MAKE_SHARED(StreamEndpointI, _streamInstance, _host, _port, _sourceAddr, _timeout, _connectionId, c); + } +} + +bool +IceObjC::StreamEndpointI::datagram() const +{ + return false; +} + +bool +IceObjC::StreamEndpointI::secure() const +{ + return _streamInstance->secure(); +} + +void +IceObjC::StreamEndpointI::connectors_async(Ice::EndpointSelectionType /*selType*/, + const EndpointI_connectorsPtr& cb) const +{ + vector connectors; + connectors.push_back(new StreamConnector(_streamInstance, _host, _port, _timeout, _connectionId)); + cb->connectors(connectors); +} + +TransceiverPtr +IceObjC::StreamEndpointI::transceiver() const +{ + return 0; +} + +AcceptorPtr +IceObjC::StreamEndpointI::acceptor(const string&) const +{ + return new StreamAcceptor(ICE_SHARED_FROM_CONST_THIS(StreamEndpointI), _streamInstance, _host, _port); +} + +IceObjC::StreamEndpointIPtr +IceObjC::StreamEndpointI::endpoint(const StreamAcceptorPtr& a) const +{ + int port = a->effectivePort(); + if(port == _port) + { + return ICE_DYNAMIC_CAST(StreamEndpointI, ICE_SHARED_FROM_CONST_THIS(StreamEndpointI)); + } + else + { + return ICE_MAKE_SHARED(StreamEndpointI, _streamInstance, _host, port, _sourceAddr, _timeout, _connectionId, + _compress); + } +} + +string +IceObjC::StreamEndpointI::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + + s << IPEndpointI::options(); + + if(_timeout == -1) + { + s << " -t infinite"; + } + else + { + s << " -t " << _timeout; + } + + if(_compress) + { + s << " -z"; + } + + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceObjC::StreamEndpointI::operator==(const Endpoint& r) const +#else +IceObjC::StreamEndpointI::operator==(const LocalObject& r) const +#endif +{ + if(!IPEndpointI::operator==(r)) + { + return false; + } + + const StreamEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(_compress != p->_compress) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceObjC::StreamEndpointI::operator<(const Endpoint& r) const +#else +IceObjC::StreamEndpointI::operator<(const LocalObject& r) const +#endif +{ + const StreamEndpointI* p = dynamic_cast(&r); + if(!p) + { + const IceInternal::EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + if(!_compress && p->_compress) + { + return true; + } + else if(p->_compress < _compress) + { + return false; + } + + return IPEndpointI::operator<(r); +} + +void +IceObjC::StreamEndpointI::streamWriteImpl(Ice::OutputStream* s) const +{ + IPEndpointI::streamWriteImpl(s); + s->write(_timeout); + s->write(_compress); +} + +void +IceObjC::StreamEndpointI::hashInit(Ice::Int& h) const +{ + IPEndpointI::hashInit(h); + hashAdd(h, _timeout); + hashAdd(h, _compress); +} + +bool +IceObjC::StreamEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + if(IPEndpointI::checkOption(option, argument, endpoint)) + { + return true; + } + + switch(option[1]) + { + case 't': + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -t option in endpoint " + + endpoint); + } + + if(argument == "infinite") + { + const_cast(_timeout) = -1; + } + else + { + istringstream t(argument); + if(!(t >> const_cast(_timeout)) || !t.eof() || _timeout < 1) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid timeout value `" + argument + + "' in endpoint " + endpoint); + } + } + return true; + } + + case 'z': + { + if(!argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -z option in " + endpoint); + } + const_cast(_compress) = true; + return true; + } + + default: + { + return false; + } + } +} + +ConnectorPtr +IceObjC::StreamEndpointI::createConnector(const Address& /*address*/, const NetworkProxyPtr& /*proxy*/) const +{ + assert(false); + return 0; +} + +IPEndpointIPtr +IceObjC::StreamEndpointI::createEndpoint(const string& host, int port, const string& connectionId) const +{ + return ICE_MAKE_SHARED(StreamEndpointI, _streamInstance, host, port, _sourceAddr, _timeout, connectionId, + _compress); +} + +IceObjC::StreamEndpointFactory::StreamEndpointFactory(const InstancePtr& instance) : _instance(instance) +{ +} + +IceObjC::StreamEndpointFactory::~StreamEndpointFactory() +{ +} + +Short +IceObjC::StreamEndpointFactory::type() const +{ + return _instance->type(); +} + +string +IceObjC::StreamEndpointFactory::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceObjC::StreamEndpointFactory::create(vector& args, bool oaEndpoint) const +{ + IPEndpointIPtr endpt = ICE_MAKE_SHARED(StreamEndpointI, _instance); + endpt->initWithOptions(args, oaEndpoint); + return endpt; +} + +EndpointIPtr +IceObjC::StreamEndpointFactory::read(Ice::InputStream* s) const +{ + return ICE_MAKE_SHARED(StreamEndpointI, _instance, s); +} + +void +IceObjC::StreamEndpointFactory::destroy() +{ + _instance = 0; +} + +EndpointFactoryPtr +IceObjC::StreamEndpointFactory::clone(const ProtocolInstancePtr& instance) const +{ + return new StreamEndpointFactory(_instance->clone(instance)); +} +#endif diff --git a/Sources/IceCpp/StreamEndpointI.h b/Sources/IceCpp/StreamEndpointI.h new file mode 100644 index 0000000..cf9b5fa --- /dev/null +++ b/Sources/IceCpp/StreamEndpointI.h @@ -0,0 +1,156 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_ENDPOINT_I_H +#define ICE_STREAM_ENDPOINT_I_H + +#include + +#if TARGET_OS_IPHONE != 0 + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +} + +namespace IceObjC +{ + +class Instance : public IceInternal::ProtocolInstance +{ +public: + + Instance(const Ice::CommunicatorPtr&, Ice::Short, const std::string&, bool); + virtual ~Instance(); + + const std::string& proxyHost() const + { + return _proxyHost; + } + + int proxyPort() const + { + return _proxyPort; + } + + void setupStreams(CFReadStreamRef, CFWriteStreamRef, bool, const std::string&) const; + + Instance* clone(const IceInternal::ProtocolInstancePtr&); + +private: + + const Ice::CommunicatorPtr _communicator; + IceInternal::UniqueRef _proxySettings; + std::string _proxyHost; + int _proxyPort; +}; +typedef IceUtil::Handle InstancePtr; + +class StreamAcceptor; +typedef IceUtil::Handle StreamAcceptorPtr; + +class StreamEndpointI; +ICE_DEFINE_PTR(StreamEndpointIPtr, StreamEndpointI); + +class StreamEndpointI : public IceInternal::IPEndpointI +{ +public: + + StreamEndpointI(const InstancePtr&, const std::string&, Ice::Int, const IceInternal::Address&, Ice::Int, + const std::string&, bool); + StreamEndpointI(const InstancePtr&); + StreamEndpointI(const InstancePtr&, Ice::InputStream*); + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + + virtual Ice::Int timeout() const; + virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; + virtual bool compress() const; + virtual IceInternal::EndpointIPtr compress(bool) const; + virtual bool datagram() const; + virtual bool secure() const; + + virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; + virtual IceInternal::TransceiverPtr transceiver() const; + virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; + virtual std::string options() const; + +#ifdef ICE_CPP11_MAPPING + + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(IceInternal::IPEndpointI::shared_from_this()); + } + + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + + StreamEndpointIPtr endpoint(const StreamAcceptorPtr&) const; + + using IPEndpointI::connectionId; + +protected: + + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual void hashInit(Ice::Int&) const; + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + + virtual IceInternal::ConnectorPtr createConnector(const IceInternal::Address&, + const IceInternal::NetworkProxyPtr&) const; + virtual IceInternal::IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const; + +private: + + const InstancePtr _streamInstance; + + // + // All members are const, because endpoints are immutable. + // + const Ice::Int _timeout; + const bool _compress; +}; + +class StreamEndpointFactory : public IceInternal::EndpointFactory +{ +public: + + StreamEndpointFactory(const InstancePtr&); + + virtual ~StreamEndpointFactory(); + + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual IceInternal::EndpointIPtr create(std::vector&, bool) const; + virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + +private: + + InstancePtr _instance; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/StreamSocket.cpp b/Sources/IceCpp/StreamSocket.cpp new file mode 100644 index 0000000..75f5ff7 --- /dev/null +++ b/Sources/IceCpp/StreamSocket.cpp @@ -0,0 +1,519 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace IceInternal; + +StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, + const NetworkProxyPtr& proxy, + const Address& addr, + const Address& sourceAddr) : + NativeInfo(createSocket(false, proxy ? proxy->getAddress() : addr)), + _instance(instance), + _proxy(proxy), + _addr(addr), + _sourceAddr(sourceAddr), + _state(StateNeedConnect) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), _write(SocketOperationWrite) +#endif +{ + init(); +#if !defined(ICE_USE_IOCP) + if(doConnect(_fd, _proxy ? _proxy->getAddress() : _addr, sourceAddr)) + { + _state = _proxy ? StateProxyWrite : StateConnected; + } +#endif + try + { + _desc = fdToString(_fd, _proxy, _addr); + } + catch(const Ice::Exception&) + { + closeSocketNoThrow(_fd); + throw; + } +} + +StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, SOCKET fd) : + NativeInfo(fd), + _instance(instance), + _addr(), + _sourceAddr(), + _state(StateConnected) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), _write(SocketOperationWrite) +#endif +{ + init(); + try + { + _desc = fdToString(fd); + } + catch(const Ice::Exception&) + { + closeSocketNoThrow(fd); + throw; + } +} + +StreamSocket::~StreamSocket() +{ + assert(_fd == INVALID_SOCKET); +} + +SocketOperation +StreamSocket::connect(Buffer& readBuffer, Buffer& writeBuffer) +{ + if(_state == StateNeedConnect) + { + _state = StateConnectPending; + return SocketOperationConnect; + } + else if(_state <= StateConnectPending) + { +#if defined(ICE_USE_IOCP) + doFinishConnectAsync(_fd, _write); +#else + doFinishConnect(_fd); +#endif + _desc = fdToString(_fd, _proxy, _addr); + _state = _proxy ? StateProxyWrite : StateConnected; + } + + if(_state == StateProxyWrite) + { + _proxy->beginWrite(_addr, writeBuffer); + return IceInternal::SocketOperationWrite; + } + else if(_state == StateProxyRead) + { + _proxy->beginRead(readBuffer); + return IceInternal::SocketOperationRead; + } + else if(_state == StateProxyConnected) + { + _proxy->finish(readBuffer, writeBuffer); + + readBuffer.b.clear(); + readBuffer.i = readBuffer.b.end(); + + writeBuffer.b.clear(); + writeBuffer.i = writeBuffer.b.end(); + + _state = StateConnected; + } + + assert(_state == StateConnected); + return IceInternal::SocketOperationNone; +} + +bool +StreamSocket::isConnected() +{ + return _state == StateConnected && _fd != INVALID_SOCKET; +} + +size_t +StreamSocket::getSendPacketSize(size_t length) +{ +#if defined(ICE_USE_IOCP) + return _maxSendPacketSize > 0 ? std::min(length, _maxSendPacketSize) : length; +#else + return length; +#endif +} + +size_t +StreamSocket::getRecvPacketSize(size_t length) +{ +#if defined(ICE_USE_IOCP) + return _maxRecvPacketSize > 0 ? std::min(length, _maxRecvPacketSize) : length; +#else + return length; +#endif +} + +void +StreamSocket::setBufferSize(int rcvSize, int sndSize) +{ + setTcpBufSize(_fd, rcvSize, sndSize, _instance); +} + +SocketOperation +StreamSocket::read(Buffer& buf) +{ + if(_state == StateProxyRead) + { + while(true) + { + ssize_t ret = read(reinterpret_cast(&*buf.i), static_cast(buf.b.end() - buf.i)); + if(ret == 0) + { + return SocketOperationRead; + } + buf.i += ret; + _state = toState(_proxy->endRead(buf)); + if(_state != StateProxyRead) + { + return SocketOperationNone; + } + } + } + buf.i += read(reinterpret_cast(&*buf.i), static_cast(buf.b.end() - buf.i)); + return buf.i != buf.b.end() ? SocketOperationRead : SocketOperationNone; +} + +SocketOperation +StreamSocket::write(Buffer& buf) +{ + if(_state == StateProxyWrite) + { + while(true) + { + ssize_t ret = write(reinterpret_cast(&*buf.i), static_cast(buf.b.end() - buf.i)); + if(ret == 0) + { + return SocketOperationWrite; + } + buf.i += ret; + _state = toState(_proxy->endWrite(buf)); + if(_state != StateProxyWrite) + { + return SocketOperationNone; + } + } + } + buf.i += write(reinterpret_cast(&*buf.i), static_cast(buf.b.end() - buf.i)); + return buf.i != buf.b.end() ? SocketOperationWrite : SocketOperationNone; +} + +ssize_t +StreamSocket::read(char* buf, size_t length) +{ + assert(_fd != INVALID_SOCKET); + + size_t packetSize = length; + ssize_t read = 0; + + while(length > 0) + { +#ifdef _WIN32 + ssize_t ret = ::recv(_fd, buf, static_cast(packetSize), 0); +#else + ssize_t ret = ::recv(_fd, buf, packetSize, 0); +#endif + if(ret == 0) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, 0); + } + else if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + continue; + } + + if(wouldBlock()) + { + return read; + } + + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + + buf += ret; + read += ret; + length -= static_cast(ret); + + if(packetSize > length) + { + packetSize = length; + } + } + return read; +} + +ssize_t +StreamSocket::write(const char* buf, size_t length) +{ + assert(_fd != INVALID_SOCKET); + +#ifdef ICE_USE_IOCP + // + // On Windows, limiting the buffer size is important to prevent + // poor throughput performances when sending large amount of + // data. See Microsoft KB article KB823764. + // + size_t packetSize = _maxSendPacketSize > 0 ? std::min(length, _maxSendPacketSize / 2) : length; +#else + size_t packetSize = length; +#endif + ssize_t sent = 0; + while(length > 0) + { +#ifdef _WIN32 + ssize_t ret = ::send(_fd, buf, static_cast(packetSize), 0); +#else + ssize_t ret = ::send(_fd, buf, packetSize, 0); +#endif + if(ret == 0) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, 0); + } + else if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + continue; + } + + if(wouldBlock()) + { + return sent; + } + + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + + buf += ret; + sent += ret; + length -= static_cast(ret); + + if(packetSize > length) + { + packetSize = length; + } + } + return sent; +} + +#if defined(ICE_USE_IOCP) +AsyncInfo* +StreamSocket::getAsyncInfo(SocketOperation op) +{ + switch(op) + { + case SocketOperationRead: + return &_read; + case SocketOperationWrite: + return &_write; + default: + assert(false); + return 0; + } +} +#endif + +#if defined(ICE_USE_IOCP) + +bool +StreamSocket::startWrite(Buffer& buf) +{ + if(_state == StateConnectPending) + { + doConnectAsync(_fd, _proxy ? _proxy->getAddress() : _addr, _sourceAddr, _write); + return false; + } + + size_t length = buf.b.end() - buf.i; + assert(length > 0); + size_t packetSize = getSendPacketSize(length); + + _write.buf.len = static_cast(packetSize); + _write.buf.buf = reinterpret_cast(&*buf.i); + _write.error = ERROR_SUCCESS; + int err = WSASend(_fd, &_write.buf, 1, &_write.count, 0, &_write, ICE_NULLPTR); + if(err == SOCKET_ERROR) + { + if(!wouldBlock()) + { + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } + return packetSize == length; +} + +void +StreamSocket::finishWrite(Buffer& buf) +{ + if(_fd == INVALID_SOCKET || (_state < StateConnected && _state != StateProxyWrite)) + { + return; + } + + if(_write.error != ERROR_SUCCESS) + { + WSASetLastError(_write.error); + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + + buf.i += _write.count; + if(_state == StateProxyWrite) + { + _state = toState(_proxy->endWrite(buf)); + } +} + +void +StreamSocket::startRead(Buffer& buf) +{ + size_t length = buf.b.end() - buf.i; + assert(length > 0); + + size_t packetSize = getRecvPacketSize(length); + _read.buf.len = static_cast(packetSize); + _read.buf.buf = reinterpret_cast(&*buf.i); + _read.error = ERROR_SUCCESS; + int err = WSARecv(_fd, &_read.buf, 1, &_read.count, &_read.flags, &_read, ICE_NULLPTR); + if(err == SOCKET_ERROR) + { + if(!wouldBlock()) + { + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } +} + +void +StreamSocket::finishRead(Buffer& buf) +{ + if(_fd == INVALID_SOCKET) + { + return; + } + + if(_read.error != ERROR_SUCCESS) + { + WSASetLastError(_read.error); + if(connectionLost()) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw Ice::SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + else if(_read.count == 0) + { + throw Ice::ConnectionLostException(__FILE__, __LINE__, 0); + } + + buf.i += _read.count; + + if(_state == StateProxyRead) + { + _state = toState(_proxy->endRead(buf)); + } + +} + +#endif + +void +StreamSocket::close() +{ + assert(_fd != INVALID_SOCKET); + try + { + closeSocket(_fd); + _fd = INVALID_SOCKET; + } + catch(const Ice::SocketException&) + { + _fd = INVALID_SOCKET; + throw; + } +} + +const std::string& +StreamSocket::toString() const +{ + return _desc; +} + +void +StreamSocket::init() +{ + setBlock(_fd, false); + setTcpBufSize(_fd, _instance); + +#if defined(ICE_USE_IOCP) + // + // For timeouts to work properly, we need to receive or send the + // data in several chunks when using IOCP WSARecv or WSASend. + // Otherwise, we would only be notified when all the data is + // received or written. The connection timeout could easily be + // triggered when receiging or sending large messages. + // + _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_fd)); + _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_fd)); +#endif +} + +StreamSocket::State +StreamSocket::toState(SocketOperation operation) const +{ + switch(operation) + { + case SocketOperationRead: + return StateProxyRead; + case SocketOperationWrite: + return StateProxyWrite; + default: + return StateProxyConnected; + } +} diff --git a/Sources/IceCpp/StreamTransceiver.cpp b/Sources/IceCpp/StreamTransceiver.cpp new file mode 100644 index 0000000..88485a3 --- /dev/null +++ b/Sources/IceCpp/StreamTransceiver.cpp @@ -0,0 +1,570 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "StreamTransceiver.h" +#include "StreamEndpointI.h" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +void selectorReadCallback(CFReadStreamRef, CFStreamEventType event, void* info) +{ + SelectorReadyCallback* callback = reinterpret_cast(info); + switch(event) + { + case kCFStreamEventOpenCompleted: + callback->readyCallback(static_cast(SocketOperationConnect | SocketOperationRead)); + break; + case kCFStreamEventHasBytesAvailable: + callback->readyCallback(SocketOperationRead); + break; + default: + callback->readyCallback(SocketOperationRead, -1); // Error + break; + } +} + +void selectorWriteCallback(CFWriteStreamRef, CFStreamEventType event, void* info) +{ + SelectorReadyCallback* callback = reinterpret_cast(info); + switch(event) + { + case kCFStreamEventOpenCompleted: + callback->readyCallback(static_cast(SocketOperationConnect | SocketOperationWrite)); + break; + case kCFStreamEventCanAcceptBytes: + callback->readyCallback(SocketOperationWrite); + break; + default: + callback->readyCallback(SocketOperationWrite, -1); // Error + break; + } +} + +} + +static inline string +fromCFString(CFStringRef ref) +{ + const char* s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); + if(s) + { + return string(s); + } + + // Not great, but is good enough for this purpose. + char buf[1024]; + CFStringGetCString(ref, buf, sizeof(buf), kCFStringEncodingUTF8); + return string(buf); +} + +IceInternal::NativeInfoPtr +IceObjC::StreamTransceiver::getNativeInfo() +{ + return this; +} + +void +IceObjC::StreamTransceiver::initStreams(SelectorReadyCallback* callback) +{ + CFOptionFlags events; + CFStreamClientContext ctx = { 0, callback, 0, 0, 0 }; + events = kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | + kCFStreamEventEndEncountered; + CFWriteStreamSetClient(_writeStream.get(), events, selectorWriteCallback, &ctx); + + events = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | + kCFStreamEventEndEncountered; + CFReadStreamSetClient(_readStream.get(), events, selectorReadCallback, &ctx); +} + +SocketOperation +IceObjC::StreamTransceiver::registerWithRunLoop(SocketOperation op) +{ + IceUtil::Mutex::Lock sync(_mutex); + SocketOperation readyOp = SocketOperationNone; + if(op & SocketOperationConnect) + { + if(CFWriteStreamGetStatus(_writeStream.get()) != kCFStreamStatusNotOpen || + CFReadStreamGetStatus(_readStream.get()) != kCFStreamStatusNotOpen) + { + return SocketOperationConnect; + } + + _opening = true; + + CFWriteStreamScheduleWithRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamScheduleWithRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + + _writeStreamRegistered = true; // Note: this must be set after the schedule call + _readStreamRegistered = true; // Note: this must be set after the schedule call + + CFReadStreamOpen(_readStream.get()); + CFWriteStreamOpen(_writeStream.get()); + } + else + { + if(op & SocketOperationWrite) + { + if(CFWriteStreamCanAcceptBytes(_writeStream.get())) + { + readyOp = static_cast(readyOp | SocketOperationWrite); + } + else if(!_writeStreamRegistered) + { + CFWriteStreamScheduleWithRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + _writeStreamRegistered = true; // Note: this must be set after the schedule call + if(CFWriteStreamCanAcceptBytes(_writeStream.get())) + { + readyOp = static_cast(readyOp | SocketOperationWrite); + } + } + } + + if(op & SocketOperationRead) + { + if(CFReadStreamHasBytesAvailable(_readStream.get())) + { + readyOp = static_cast(readyOp | SocketOperationRead); + } + else if(!_readStreamRegistered) + { + CFReadStreamScheduleWithRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + _readStreamRegistered = true; // Note: this must be set after the schedule call + if(CFReadStreamHasBytesAvailable(_readStream.get())) + { + readyOp = static_cast(readyOp | SocketOperationRead); + } + } + } + } + return readyOp; +} + +SocketOperation +IceObjC::StreamTransceiver::unregisterFromRunLoop(SocketOperation op, bool error) +{ + IceUtil::Mutex::Lock sync(_mutex); + _error |= error; + + if(_opening) + { + // Wait for the stream to be ready for write + if(op & SocketOperationWrite) + { + _writeStreamRegistered = false; + } + + // + // We don't wait for the stream to be ready for read (even if + // it's a client connection) because there's no guarantees that + // the server might actually send data right away. If we use + // the WebSocket transport, the server actually waits for the + // client to write the HTTP upgrade request. + // + //if(op & SocketOperationRead && (_fd != INVALID_SOCKET || !(op & SocketOperationConnect))) + if(op & (SocketOperationRead | SocketOperationConnect)) + { + _readStreamRegistered = false; + } + + if(error || (!_readStreamRegistered && !_writeStreamRegistered)) + { + CFWriteStreamUnscheduleFromRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamUnscheduleFromRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + _opening = false; + return SocketOperationConnect; + } + else + { + return SocketOperationNone; + } + } + else + { + if(op & SocketOperationWrite && _writeStreamRegistered) + { + CFWriteStreamUnscheduleFromRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + _writeStreamRegistered = false; + } + + if(op & SocketOperationRead && _readStreamRegistered) + { + CFReadStreamUnscheduleFromRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + _readStreamRegistered = false; + } + } + return op; +} + +void +IceObjC::StreamTransceiver::closeStreams() +{ + CFReadStreamSetClient(_readStream.get(), kCFStreamEventNone, 0, 0); + CFWriteStreamSetClient(_writeStream.get(), kCFStreamEventNone, 0, 0); + + CFReadStreamClose(_readStream.get()); + CFWriteStreamClose(_writeStream.get()); +} + +SocketOperation +IceObjC::StreamTransceiver::initialize(Buffer& /*readBuffer*/, Buffer& /*writeBuffer*/) +{ + IceUtil::Mutex::Lock sync(_mutex); + if(_state == StateNeedConnect) + { + _state = StateConnectPending; + return SocketOperationConnect; + } + + if(_state <= StateConnectPending) + { + if(_error) + { + checkErrorStatus(_writeStream.get(), _readStream.get(), __FILE__, __LINE__); + } + + _state = StateConnected; + + if(_fd == INVALID_SOCKET) + { + if(!CFReadStreamSetProperty(_readStream.get(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse) || + !CFWriteStreamSetProperty(_writeStream.get(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse)) + { + throw Ice::SocketException(__FILE__, __LINE__, 0); + } + + UniqueRef d(static_cast( + CFReadStreamCopyProperty(_readStream.get(), kCFStreamPropertySocketNativeHandle))); + CFDataGetBytes(d.get(), CFRangeMake(0, sizeof(SOCKET)), reinterpret_cast(&_fd)); + } + + ostringstream s; + Address localAddr; + fdToLocalAddress(_fd, localAddr); + s << "local address = " << addrToString(localAddr); + string proxyHost = _instance->proxyHost(); + if(!proxyHost.empty()) + { + s << "\nSOCKS proxy address = " << proxyHost << ":" << _instance->proxyPort(); + } + Address remoteAddr; + bool peerConnected = fdToRemoteAddress(_fd, remoteAddr); + if(peerConnected) + { + s << "\nremote address = " << addrToString(remoteAddr); + } + else + { + s << "\nremote address = " << _host << ":" << _port; + } + _desc = s.str(); + + setBlock(_fd, false); + setTcpBufSize(_fd, _instance); + } + assert(_state == StateConnected); + return SocketOperationNone; +} + +SocketOperation +IceObjC::StreamTransceiver::closing(bool initiator, const Ice::LocalException&) +{ + // If we are initiating the connection closure, wait for the peer + // to close the TCP/IP connection. Otherwise, close immediately. + return initiator ? SocketOperationRead : SocketOperationNone; +} + +void +IceObjC::StreamTransceiver::close() +{ + if(_fd != INVALID_SOCKET) + { + try + { + closeSocket(_fd); + _fd = INVALID_SOCKET; + } + catch(const SocketException&) + { + _fd = INVALID_SOCKET; + throw; + } + } +} + +SocketOperation +IceObjC::StreamTransceiver::write(Buffer& buf) +{ + // Don't hold the lock while calling on the CFStream API to avoid deadlocks in case the CFStream API calls + // the stream notification callbacks with an internal lock held. + { + IceUtil::Mutex::Lock sync(_mutex); + if(_error) + { + checkErrorStatus(_writeStream.get(), 0, __FILE__, __LINE__); + } + else if (_writeStreamRegistered) + { + return SocketOperationWrite; + } + } + + size_t packetSize = static_cast(buf.b.end() - buf.i); + while(buf.i != buf.b.end()) + { + if(!CFWriteStreamCanAcceptBytes(_writeStream.get())) + { + return SocketOperationWrite; + } + + assert(_fd != INVALID_SOCKET); + CFIndex ret = CFWriteStreamWrite(_writeStream.get(), reinterpret_cast(&*buf.i), + static_cast(packetSize)); + + if(ret == SOCKET_ERROR) + { + checkErrorStatus(_writeStream.get(), 0, __FILE__, __LINE__); + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + } + continue; + } + + buf.i += ret; + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + return SocketOperationNone; +} + +SocketOperation +IceObjC::StreamTransceiver::read(Buffer& buf) +{ + // Don't hold the lock while calling on the CFStream API to avoid deadlocks in case the CFStream API calls + // the stream notification callbacks with an internal lock held. + { + IceUtil::Mutex::Lock sync(_mutex); + if (_error) + { + checkErrorStatus(0, _readStream.get(), __FILE__, __LINE__); + } + else if (_readStreamRegistered) + { + return SocketOperationRead; + } + } + + size_t packetSize = static_cast(buf.b.end() - buf.i); + while(buf.i != buf.b.end()) + { + if(!CFReadStreamHasBytesAvailable(_readStream.get())) + { + return SocketOperationRead; + } + + assert(_fd != INVALID_SOCKET); + CFIndex ret = CFReadStreamRead(_readStream.get(), reinterpret_cast(&*buf.i), + static_cast(packetSize)); + + if(ret == 0) + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + + if(ret == SOCKET_ERROR) + { + checkErrorStatus(0, _readStream.get(), __FILE__, __LINE__); + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + } + continue; + } + + buf.i += ret; + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + + return SocketOperationNone; +} + +string +IceObjC::StreamTransceiver::protocol() const +{ + return _instance->protocol(); +} + +string +IceObjC::StreamTransceiver::toString() const +{ + return _desc; +} + +string +IceObjC::StreamTransceiver::toDetailedString() const +{ + return _desc; +} + +Ice::ConnectionInfoPtr +IceObjC::StreamTransceiver::getInfo() const +{ + Ice::TCPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo); + fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + info->rcvSize = getRecvBufferSize(_fd); + info->sndSize = getSendBufferSize(_fd); + return info; +} + +void +IceObjC::StreamTransceiver::checkSendSize(const Buffer& /*buf*/) +{ +} + +void +IceObjC::StreamTransceiver::setBufferSize(int rcvSize, int sndSize) +{ + setTcpBufSize(_fd, rcvSize, sndSize, _instance); +} + +IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance, + CFReadStreamRef readStream, + CFWriteStreamRef writeStream, + const string& host, + Ice::Int port) : + StreamNativeInfo(INVALID_SOCKET), + _instance(instance), + _host(host), + _port(port), + _readStream(readStream), + _writeStream(writeStream), + _readStreamRegistered(false), + _writeStreamRegistered(false), + _opening(false), + _error(false), + _state(StateNeedConnect) +{ + ostringstream s; + s << "local address = "; + string proxyHost = instance->proxyHost(); + if(!proxyHost.empty()) + { + s << "\nSOCKS proxy address = " << proxyHost << ":" << instance->proxyPort(); + } + s << "\nremote address = " << host << ":" << port; + _desc = s.str(); +} + +IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance, + CFReadStreamRef readStream, + CFWriteStreamRef writeStream, + SOCKET fd) : + StreamNativeInfo(fd), + _instance(instance), + _port(0), + _readStream(readStream), + _writeStream(writeStream), + _readStreamRegistered(false), + _writeStreamRegistered(false), + _opening(false), + _error(false), + _state(StateNeedConnect), + _desc(fdToString(fd)) +{ +} + +IceObjC::StreamTransceiver::~StreamTransceiver() +{ + assert(_fd == INVALID_SOCKET); +} + +void +IceObjC::StreamTransceiver::checkErrorStatus(CFWriteStreamRef writeStream, CFReadStreamRef readStream, + const char* file, int line) +{ + assert(writeStream || readStream); + + CFStreamStatus status = writeStream ? CFWriteStreamGetStatus(writeStream) : CFReadStreamGetStatus(readStream); + + if (status == kCFStreamStatusAtEnd || status == kCFStreamStatusClosed) + { + throw ConnectionLostException(file, line); + } + + assert(status == kCFStreamStatusError); + + UniqueRef err; + err.reset(writeStream ? CFWriteStreamCopyError(writeStream) : CFReadStreamCopyError(readStream)); + assert(err.get()); + + CFStringRef domain = CFErrorGetDomain(err.get()); + if(CFStringCompare(domain, kCFErrorDomainPOSIX, 0) == kCFCompareEqualTo) + { + errno = static_cast(CFErrorGetCode(err.get())); + if(interrupted() || noBuffers()) + { + return; + } + else if(connectionLost()) + { + throw ConnectionLostException(file, line, getSocketErrno()); + } + else if(connectionRefused()) + { + throw ConnectionRefusedException(file, line, getSocketErrno()); + } + else if(connectFailed()) + { + throw ConnectFailedException(file, line, getSocketErrno()); + } + else + { + throw SocketException(file, line, getSocketErrno()); + } + } + + CFIndex error = CFErrorGetCode(err.get()); + if(error == kCFHostErrorHostNotFound || error == kCFHostErrorUnknown) + { + int rs = 0; + if(error == kCFHostErrorUnknown) + { + UniqueRef dict(CFErrorCopyUserInfo(err.get())); + CFNumberRef d = static_cast(CFDictionaryGetValue(dict.get(), kCFGetAddrInfoFailureKey)); + if(d != 0) + { + CFNumberGetValue(d, kCFNumberSInt32Type, &rs); + } + } + throw DNSException(file, line, rs, _host); + } + throw CFNetworkException(file, line, static_cast(CFErrorGetCode(err.get())), fromCFString(domain)); +} +#endif diff --git a/Sources/IceCpp/StreamTransceiver.h b/Sources/IceCpp/StreamTransceiver.h new file mode 100644 index 0000000..8b2b499 --- /dev/null +++ b/Sources/IceCpp/StreamTransceiver.h @@ -0,0 +1,93 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_TRANSCEIVER_H +#define ICE_STREAM_TRANSCEIVER_H + +#include + +#if TARGET_OS_IPHONE != 0 + +#include +#include +#include +#include + +struct __CFError; +typedef struct __CFError * CFErrorRef; + +struct __CFWriteStream; +typedef struct __CFWriteStream * CFWriteStreamRef; + +struct __CFReadStream; +typedef struct __CFReadStream * CFReadStreamRef; + +namespace IceObjC +{ + +class Instance; +typedef IceUtil::Handle InstancePtr; + +class StreamTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo +{ + enum State + { + StateNeedConnect, + StateConnectPending, + StateConnected + }; + +public: + + StreamTransceiver(const InstancePtr&, CFReadStreamRef, CFWriteStreamRef, const std::string&, Ice::Int); + StreamTransceiver(const InstancePtr&, CFReadStreamRef, CFWriteStreamRef, SOCKET); + + virtual ~StreamTransceiver(); + + virtual IceInternal::NativeInfoPtr getNativeInfo(); + + virtual void initStreams(IceInternal::SelectorReadyCallback*); + virtual IceInternal::SocketOperation registerWithRunLoop(IceInternal::SocketOperation); + virtual IceInternal::SocketOperation unregisterFromRunLoop(IceInternal::SocketOperation, bool); + virtual void closeStreams(); + + virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&); + virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&); + virtual void close(); + + virtual IceInternal::SocketOperation write(IceInternal::Buffer&); + virtual IceInternal::SocketOperation read(IceInternal::Buffer&); + + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const IceInternal::Buffer&); + virtual void setBufferSize(int, int); + +private: + + void checkErrorStatus(CFWriteStreamRef, CFReadStreamRef, const char*, int); + + const InstancePtr _instance; + const std::string _host; + const Ice::Int _port; + IceInternal::UniqueRef _readStream; + IceInternal::UniqueRef _writeStream; + bool _readStreamRegistered; + bool _writeStreamRegistered; + bool _opening; + + IceUtil::Mutex _mutex; + bool _error; + + State _state; + std::string _desc; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/StringConverter.cpp b/Sources/IceCpp/StringConverter.cpp new file mode 100644 index 0000000..2af835d --- /dev/null +++ b/Sources/IceCpp/StringConverter.cpp @@ -0,0 +1,690 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// TODO codecvt was deprecated in C++17 and cause build failures in C++17 mode +// For VC++ we should replace this code with MultiByteToWideChar() and WideCharToMultiByte() +#if defined(_MSC_VER) && (_MSVC_LANG >= 201703L) +# define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING +#elif (__cplusplus >= 201703L) +# include +#endif + +#include +#include +#include +#include + +#ifdef ICE_HAS_CODECVT_UTF8 +#include +#include +#else +#include +#endif + +using namespace IceUtil; +using namespace IceUtilInternal; +using namespace std; + +namespace +{ + +IceUtil::Mutex* processStringConverterMutex = 0; +IceUtil::StringConverterPtr processStringConverter; +IceUtil::WstringConverterPtr processWstringConverter; + +#ifndef ICE_HAS_THREAD_SAFE_LOCAL_STATIC +IceUtil::WstringConverterPtr unicodeWstringConverter; +#endif + +#ifdef ICE_HAS_CODECVT_UTF8 + +template +struct SelectCodeCvt; + +template<> +struct SelectCodeCvt<2> +{ + typedef std::codecvt_utf8_utf16 Type; +}; + +template<> +struct SelectCodeCvt<4> +{ + typedef std::codecvt_utf8 Type; +}; + +class UnicodeWstringConverter : public WstringConverter +{ +public: + +#if defined(_MSC_VER) && (_MSC_VER <= 1800) + // + // VS 2013 needs a default ctor + // + UnicodeWstringConverter() + { + } +#endif + + virtual Byte* toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, UTF8Buffer& buffer) const + { + // + // Max bytes for a character encoding in UTF-8 is 4, + // however MSVC returns 6 + // +#ifdef _MSC_VER + assert(_codecvt.max_length() == 4 || _codecvt.max_length() == 6); +#else + assert(_codecvt.max_length() == 4); +#endif + if(sourceStart == sourceEnd) + { + return buffer.getMoreBytes(1, 0); + } + + char* targetStart = 0; + char* targetEnd = 0; + char* targetNext = 0; + + mbstate_t state = mbstate_t(); // must be initialized! + const wchar_t* sourceNext = sourceStart; + + bool more = false; + + // + // The number of bytes we request from buffer for each remaining source character + // + size_t factor = 2; + + do + { + assert(factor <= 4); + const size_t chunkSize = std::max(static_cast(sourceEnd - sourceStart) * factor, 4); + ++factor; // at the next round, we'll allocate more bytes per remaining source character + + targetStart = reinterpret_cast(buffer.getMoreBytes(chunkSize, reinterpret_cast(targetNext))); + targetEnd = targetStart + chunkSize; + targetNext = targetStart; + + codecvt_base::result result = + _codecvt.out(state, sourceStart, sourceEnd, sourceNext, targetStart, targetEnd, targetNext); + + switch(result) + { + case codecvt_base::ok: + // + // MSVC returns ok when target is exhausted + // + more = sourceNext < sourceEnd; + break; + + case codecvt_base::partial: + // + // clang/libc++ and g++5 return partial when target is exhausted + // + more = true; + assert(sourceNext < sourceEnd); + break; + + case codecvt_base::noconv: + // + // Unexpected + // + assert(0); + throw IllegalConversionException(__FILE__, __LINE__, "codecvt.out noconv"); + + default: + throw IllegalConversionException(__FILE__, __LINE__, "codecvt.out error"); + } + + if(targetStart == targetNext) + { + // We didn't convert a single character + throw IllegalConversionException(__FILE__, __LINE__, + "no character converted by codecvt.out"); + } + + sourceStart = sourceNext; + } while (more); + + return reinterpret_cast(targetNext); + } + + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const + { + const size_t sourceSize = static_cast(sourceEnd - sourceStart); + + if(sourceSize == 0) + { + target = L""; + } + else + { + target.resize(sourceSize); + wchar_t* targetStart = const_cast(target.data()); + wchar_t* targetEnd = targetStart + sourceSize; + wchar_t* targetNext = targetStart; + + const char* sourceNext = reinterpret_cast(sourceStart); + + mbstate_t state = mbstate_t(); + + codecvt_base::result result = _codecvt.in(state, + reinterpret_cast(sourceStart), + reinterpret_cast(sourceEnd), + sourceNext, + targetStart, targetEnd, targetNext); + + if(result != codecvt_base::ok) + { + throw IllegalConversionException(__FILE__, __LINE__, "codecvt.in failure"); + } + + target.resize(static_cast(targetNext - targetStart)); + } + } + +private: + + typedef SelectCodeCvt::Type CodeCvt; + const CodeCvt _codecvt; +}; + +#else + +class UnicodeWstringConverter : public WstringConverter +{ +public: + + virtual Byte* toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, UTF8Buffer& buffer) const + { + if(sourceStart == sourceEnd) + { + return buffer.getMoreBytes(1, 0); + } + + Byte* targetStart = 0; + Byte* targetEnd = 0; + + // + // The number of bytes we request from buffer for each remaining source character + // + size_t factor = 2; + + do + { + assert(factor <= 4); + const size_t chunkSize = std::max((sourceEnd - sourceStart) * factor, 4); + ++factor; // at the next round, we'll allocate more bytes per remaining source character + + targetStart = buffer.getMoreBytes(chunkSize, targetStart); + targetEnd = targetStart + chunkSize; + } + while(convertUTFWstringToUTF8(sourceStart, sourceEnd, targetStart, targetEnd) == false); + + return targetStart; + } + + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const + { + if(sourceStart == sourceEnd) + { + target = L""; + } + else + { + convertUTF8ToUTFWstring(sourceStart, sourceEnd, target); + } + } +}; + +#endif + +class Init +{ +public: + + Init() + { + processStringConverterMutex = new IceUtil::Mutex; +#ifndef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + unicodeWstringConverter = ICE_MAKE_SHARED(UnicodeWstringConverter); +#endif + } + + ~Init() + { + delete processStringConverterMutex; + processStringConverterMutex = 0; + } +}; + +Init init; + +const WstringConverterPtr& +getUnicodeWstringConverter() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const WstringConverterPtr unicodeWstringConverter = ICE_MAKE_SHARED(UnicodeWstringConverter); +#endif + return unicodeWstringConverter; +} + +class UTF8BufferI : public UTF8Buffer +{ +public: + + // + // Returns the first unused byte in the resized buffer + // + Byte* getMoreBytes(size_t howMany, Byte* firstUnused) + { + size_t bytesUsed = 0; + if(firstUnused != 0) + { + bytesUsed = static_cast(firstUnused - reinterpret_cast(_buffer.data())); + } + + if(_buffer.size() < howMany + bytesUsed) + { + _buffer.resize(bytesUsed + howMany); + } + + return const_cast(reinterpret_cast(_buffer.data())) + bytesUsed; + } + + void swap(string& other, const Byte* tail) + { + assert(tail >= reinterpret_cast(_buffer.data())); + _buffer.resize(static_cast(tail - reinterpret_cast(_buffer.data()))); + other.swap(_buffer); + } + +private: + string _buffer; +}; + +} + +IceUtil::UTF8Buffer::~UTF8Buffer() +{ + // Out of line to avoid weak vtable +} + +WstringConverterPtr +IceUtil::createUnicodeWstringConverter() +{ + return getUnicodeWstringConverter(); +} + +StringConverterPtr +IceUtil::getProcessStringConverter() +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + return processStringConverter; +} + +void +IceUtil::setProcessStringConverter(const StringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + processStringConverter = converter; +} + +WstringConverterPtr +IceUtil::getProcessWstringConverter() +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + if(processWstringConverter) + { + return processWstringConverter; + } + else + { + return getUnicodeWstringConverter(); + } +} + +void +IceUtil::setProcessWstringConverter(const WstringConverterPtr& converter) +{ + IceUtilInternal::MutexPtrLock lock(processStringConverterMutex); + processWstringConverter = converter; +} + +string +IceUtil::wstringToString(const wstring& v, const StringConverterPtr& converter, const WstringConverterPtr& wConverter) +{ + string target; + if(!v.empty()) + { + const WstringConverterPtr& wConverterWithDefault = wConverter ? wConverter : getUnicodeWstringConverter(); + + // + // First convert to UTF-8 narrow string. + // + UTF8BufferI buffer; + Byte* last = wConverterWithDefault->toUTF8(v.data(), v.data() + v.size(), buffer); + buffer.swap(target, last); + + // + // If narrow string converter is present convert to the native narrow string encoding, otherwise + // native narrow string encoding is UTF8 and we are done. + // + if(converter) + { + string tmp; + converter->fromUTF8(reinterpret_cast(target.data()), + reinterpret_cast(target.data() + target.size()), tmp); + tmp.swap(target); + } + } + return target; +} + +wstring +IceUtil::stringToWstring(const string& v, const StringConverterPtr& converter, const WstringConverterPtr& wConverter) +{ + wstring target; + if(!v.empty()) + { + // + // If there is a narrow string converter use it to convert to UTF8, otherwise the narrow + // string is already UTF8 encoded. + // + string tmp; + if(converter) + { + UTF8BufferI buffer; + Byte* last = converter->toUTF8(v.data(), v.data() + v.size(), buffer); + buffer.swap(tmp, last); + } + else + { + tmp = v; + } + + const WstringConverterPtr& wConverterWithDefault = wConverter ? wConverter : getUnicodeWstringConverter(); + + // + // Convert from UTF-8 to the wide string encoding + // + wConverterWithDefault->fromUTF8(reinterpret_cast(tmp.data()), + reinterpret_cast(tmp.data() + tmp.size()), target); + + } + return target; +} + +string +IceUtil::nativeToUTF8(const string& str, const IceUtil::StringConverterPtr& converter) +{ + if(!converter || str.empty()) + { + return str; + } + UTF8BufferI buffer; + Byte* last = converter->toUTF8(str.data(), str.data() + str.size(), buffer); + string result; + buffer.swap(result, last); + return result; +} + +string +IceUtil::UTF8ToNative(const string& str, const IceUtil::StringConverterPtr& converter) +{ + if(!converter || str.empty()) + { + return str; + } + string tmp; + converter->fromUTF8(reinterpret_cast(str.data()), + reinterpret_cast(str.data() + str.size()), tmp); + return tmp; +} + +#ifdef ICE_HAS_CODECVT_UTF8 + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +// +// Workaround for compiler bug - see http://stackoverflow.com/questions/32055357 +// +typedef unsigned short Char16T; +typedef unsigned int Char32T; + +#else +typedef char16_t Char16T; +typedef char32_t Char32T; +#endif + +#endif + +vector +IceUtilInternal::toUTF16(const vector& source) +{ + vector result; + if(!source.empty()) + { + +#ifdef ICE_HAS_CODECVT_UTF8 + assert(sizeof(Char16T) == sizeof(unsigned short)); + + typedef wstring_convert, Char16T> Convert; + + Convert convert; + + try + { + Convert::wide_string ws = convert.from_bytes(reinterpret_cast(&source.front()), + reinterpret_cast(&source.front() + source.size())); + + result = vector(reinterpret_cast(ws.data()), + reinterpret_cast(ws.data()) + ws.length()); + } + catch(const std::range_error& ex) + { + throw IllegalConversionException(__FILE__, __LINE__, ex.what()); + } + +#else + convertUTF8ToUTF16(source, result); +#endif + } + return result; +} + +vector +IceUtilInternal::toUTF32(const vector& source) +{ + vector result; + if(!source.empty()) + { + +#ifdef ICE_HAS_CODECVT_UTF8 + assert(sizeof(Char32T) == sizeof(unsigned int)); + + typedef wstring_convert, Char32T> Convert; + Convert convert; + + try + { + Convert::wide_string ws = convert.from_bytes(reinterpret_cast(&source.front()), + reinterpret_cast(&source.front() + source.size())); + + result = vector(reinterpret_cast(ws.data()), + reinterpret_cast(ws.data()) + ws.length()); + } + catch(const std::range_error& ex) + { + throw IllegalConversionException(__FILE__, __LINE__, ex.what()); + } + +#else + convertUTF8ToUTF32(source, result); +#endif + } + return result; +} + +vector +IceUtilInternal::fromUTF32(const vector& source) +{ + vector result; + if(!source.empty()) + { + +#ifdef ICE_HAS_CODECVT_UTF8 + assert(sizeof(Char32T) == sizeof(unsigned int)); + + typedef wstring_convert, Char32T> Convert; + Convert convert; + + try + { + Convert::byte_string bs = convert.to_bytes(reinterpret_cast(&source.front()), + reinterpret_cast(&source.front() + source.size())); + + result = vector(reinterpret_cast(bs.data()), + reinterpret_cast(bs.data()) + bs.length()); + } + catch(const std::range_error& ex) + { + throw IllegalConversionException(__FILE__, __LINE__, ex.what()); + } + +#else + convertUTF32ToUTF8(source, result); +#endif + } + return result; +} + +#ifdef _WIN32 + +namespace +{ +// +// Converts to/from UTF-8 using MultiByteToWideChar and WideCharToMultiByte +// +class WindowsStringConverter : public StringConverter +{ +public: + + explicit WindowsStringConverter(unsigned int); + + virtual Byte* toUTF8(const char*, const char*, UTF8Buffer&) const; + + virtual void fromUTF8(const Byte*, const Byte*, string& target) const; + +private: + unsigned int _cp; +}; + +WindowsStringConverter::WindowsStringConverter(unsigned int cp) : + _cp(cp) +{ +} + +Byte* +WindowsStringConverter::toUTF8(const char* sourceStart, const char* sourceEnd, UTF8Buffer& buffer) const +{ + // + // First convert to UTF-16 + // + int sourceSize = static_cast(sourceEnd - sourceStart); + if(sourceSize == 0) + { + return buffer.getMoreBytes(1, 0); + } + + int writtenWchar = 0; + wstring wbuffer; + + // + // The following code pages doesn't support MB_ERR_INVALID_CHARS flag + // see http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx + // + DWORD flags = + (_cp == 50220 || _cp == 50221 || _cp == 50222 || + _cp == 50225 || _cp == 50227 || _cp == 50229 || + _cp == 65000 || _cp == 42 || (_cp >= 57002 && _cp <= 57011)) ? 0 : MB_ERR_INVALID_CHARS; + + do + { + wbuffer.resize(wbuffer.size() == 0 ? sourceSize + 2 : 2 * wbuffer.size()); + writtenWchar = MultiByteToWideChar(_cp, flags, sourceStart, sourceSize, + const_cast(wbuffer.data()), static_cast(wbuffer.size())); + } while(writtenWchar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenWchar == 0) + { + throw IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); + } + + wbuffer.resize(static_cast(writtenWchar)); + + // + // Then convert this UTF-16 wbuffer into UTF-8 + // + return getUnicodeWstringConverter()->toUTF8(wbuffer.data(), wbuffer.data() + wbuffer.size(), buffer); +} + +void +WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, string& target) const +{ + if(sourceStart == sourceEnd) + { + target = ""; + return; + } + + if(_cp == CP_UTF8) + { + string tmp(reinterpret_cast(sourceStart), sourceEnd - sourceStart); + tmp.swap(target); + return; + } + + // + // First convert to wstring (UTF-16) + // + wstring wtarget; + getUnicodeWstringConverter()->fromUTF8(sourceStart, sourceEnd, wtarget); + + // + // WC_ERR_INVALID_CHARS conversion flag is only supported with 65001 (UTF-8) and + // 54936 (GB18030 Simplified Chinese) + // + DWORD flags = (_cp == 65001 || _cp == 54936) ? WC_ERR_INVALID_CHARS : 0; + + // + // And then to a multi-byte narrow string + // + int writtenChar = -1; + do + { + target.resize(writtenChar == -1 ? + std::max(sourceEnd - sourceStart + 2, target.size()) : + 2 * target.size()); + + writtenChar = WideCharToMultiByte(_cp, flags, wtarget.data(), static_cast(wtarget.size()), + const_cast(target.data()), static_cast(target.size()), + 0, 0); + } while(writtenChar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenChar == 0) + { + throw IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString()); + } + + target.resize(static_cast(writtenChar)); +} +} + +StringConverterPtr +IceUtil::createWindowsStringConverter(unsigned int cp) +{ + return ICE_MAKE_SHARED(WindowsStringConverter, cp); +} +#endif diff --git a/Sources/IceCpp/StringConverterPlugin.cpp b/Sources/IceCpp/StringConverterPlugin.cpp new file mode 100644 index 0000000..98257e6 --- /dev/null +++ b/Sources/IceCpp/StringConverterPlugin.cpp @@ -0,0 +1,192 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include +#include +#include +#include +#include + +using namespace Ice; +using namespace std; + +namespace +{ + +class StringConverterPlugin : public Plugin +{ +public: + + StringConverterPlugin(const CommunicatorPtr&, + const StringConverterPtr&, const WstringConverterPtr&); + + virtual void initialize(); + + virtual void destroy(); +}; + +StringConverterPlugin::StringConverterPlugin(const CommunicatorPtr& /*notused*/, + const StringConverterPtr& stringConverter, + const WstringConverterPtr& wstringConverter) +{ + setProcessStringConverter(stringConverter); + setProcessWstringConverter(wstringConverter); +} + +void +StringConverterPlugin::initialize() +{ + // no op +} + +void +StringConverterPlugin::destroy() +{ + // no op +} + +} + +// +// The entry point for the string converter plugin built-in the Ice library +// +extern "C" +{ + +ICE_API Plugin* +createStringConverter(const CommunicatorPtr& communicator, const string& name, const StringSeq& args) +{ + StringConverterPtr stringConverter; + WstringConverterPtr wstringConverter; + + if(args.size() > 2) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": too many arguments"; + return 0; + } + + try + { + +#ifdef _WIN32 + int cp = -1; + + for(size_t i = 0; i < args.size(); ++i) + { + if(args[i].find("windows=") == 0) + { + cp = atoi(args[i].substr(strlen("windows=")).c_str()); + } + else if(args[i].find("iconv=") != 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; + return 0; + } + } + + if(cp == -1) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": missing windows= argument"; + return 0; + } + + if(cp == 0 || cp == INT_MAX || cp < 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid Windows code page"; + return 0; + } + + stringConverter = createWindowsStringConverter(static_cast(cp)); +#else + StringSeq iconvArgs; + + for(size_t i = 0; i < args.size(); ++i) + { + if(args[i].find("iconv=") == 0) + { + if(!IceUtilInternal::splitString(args[i].substr(strlen("iconv=")), ", \t\r\n", iconvArgs)) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid iconv argument"; + return 0; + } + } + else if(args[i].find("windows=") != 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": invalid \"" << args[i] << "\" argument"; + return 0; + } + } + + switch(iconvArgs.size()) + { + case 0: + { + stringConverter = createIconvStringConverter(); + break; + } + case 1: + { + stringConverter = createIconvStringConverter(iconvArgs[0]); + break; + } + case 2: + { + stringConverter = createIconvStringConverter(iconvArgs[0]); + wstringConverter = createIconvStringConverter(iconvArgs[1]); + break; + } + default: + { + assert(0); + } + } + +#endif + + return new StringConverterPlugin(communicator, stringConverter, wstringConverter); + } + catch(const std::exception& ex) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": creation failed with " << ex.what(); + return 0; + } + catch(...) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": creation failed with unknown exception"; + return 0; + } +} + +} + +namespace Ice +{ + +ICE_API void +registerIceStringConverter(bool loadOnInitialize) +{ + registerPluginFactory("IceStringConverter", createStringConverter, loadOnInitialize); +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_API void +ICEregisterIceStringConverter(bool loadOnInitialize) +{ + Ice::registerIceStringConverter(loadOnInitialize); +} diff --git a/Sources/IceCpp/StringUtil.cpp b/Sources/IceCpp/StringUtil.cpp new file mode 100644 index 0000000..9789e2f --- /dev/null +++ b/Sources/IceCpp/StringUtil.cpp @@ -0,0 +1,1135 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include // for strerror_r + +#include +#include + +using namespace std; +using namespace IceUtil; + +namespace +{ + +char +toHexDigit(Byte b) +{ + assert(b < 16); + if(b < 10) + { + return static_cast('0' + b); + } + else + { + return static_cast('a' - 10 + b); + } +} + +unsigned int +addContinuationByte(string::iterator& p, string::iterator end, unsigned int codePoint) +{ + if(p == end) + { + throw IllegalArgumentException(__FILE__, __LINE__, "UTF-8 sequence too short"); + } + + Byte b = static_cast(*p++); + + if((b >> 6) != 2) + { + throw IllegalArgumentException(__FILE__, __LINE__, "Invalid UTF-8 sequence"); + } + return (codePoint << 6) + (b & 0x3F); +} + +// +// Appends a 2 to 4 bytes UTF-8 sequence as a universal character name +// +void +appendUniversalName(char c, string::iterator& p, string::iterator end, string& result) +{ + unsigned int codePoint; + + Byte b = static_cast(c); + if((b >> 5) == 0x06) + { + // 2 bytes + codePoint = (b & 0x1F); + codePoint = addContinuationByte(p, end, codePoint); + } + else if((b >> 4) == 0x0E) + { + // 3 bytes + codePoint = (b & 0x0F); + codePoint = addContinuationByte(p, end, codePoint); + codePoint = addContinuationByte(p, end, codePoint); + } + else if((b >> 3) == 0x1E) + { + // 4 bytes + codePoint = (b & 0x07); + codePoint = addContinuationByte(p, end, codePoint); + codePoint = addContinuationByte(p, end, codePoint); + codePoint = addContinuationByte(p, end, codePoint); + } + else + { + ostringstream ostr; + ostr << "Invalid first byte 0x" << hex << static_cast(b) << " in UTF-8 sequence" << endl; + throw IllegalArgumentException(__FILE__, __LINE__, ostr.str()); + } + + if(codePoint > 0xFFFF) + { + result.append("\\U"); + for(int j = 7; j >= 0; j--) + { + result.push_back(toHexDigit(static_cast((codePoint >> (j * 4)) & 0x0F))); + } + } + else + { + result.append("\\u"); + for(int j = 3; j >= 0; j--) + { + result.push_back(toHexDigit(static_cast((codePoint >> (j * 4)) & 0x0F))); + } + } +} + +} + +// +// Add escape sequences. Any characters that appear in special are prefixed with a backslash in the returned string. +// +string +IceUtilInternal::escapeString(const string& s, const string& special, ToStringMode toStringMode) +{ + for(string::size_type i = 0; i < special.size(); ++i) + { + if(static_cast(special[i]) < 32 || static_cast(special[i]) > 126) + { + throw IllegalArgumentException(__FILE__, __LINE__, "Special characters must be in ASCII range 32-126"); + } + } + + // + // First convert to UTF-8 + // + string u8s = nativeToUTF8(s, getProcessStringConverter()); + + string::iterator p = u8s.begin(); + + string result; + + while(p != u8s.end()) + { + char c = *p++; + + switch(c) + { + case '\\': + { + result.append("\\\\"); + break; + } + case '\'': + { + result.append("\\'"); + break; + } + case '"': + { + result.append("\\\""); + break; + } + case '\a': + { + if(toStringMode == ICE_ENUM(ToStringMode, Compat)) + { + // Octal escape for compatibility with 3.6 and earlier + result.append("\\007"); + } + else + { + result.append("\\a"); + } + break; + } + case '\b': + { + result.append("\\b"); + break; + } + case '\f': + { + result.append("\\f"); + break; + } + case '\n': + { + result.append("\\n"); + break; + } + case '\r': + { + result.append("\\r"); + break; + } + case '\t': + { + result.append("\\t"); + break; + } + case '\v': + { + if(toStringMode == ICE_ENUM(ToStringMode, Compat)) + { + // Octal escape for compatibility with 3.6 and earlier + result.append("\\013"); + } + else + { + result.append("\\v"); + } + break; + } + default: + { + if(special.find(c) != string::npos) + { + result.push_back('\\'); + result.push_back(c); + } + else + { + unsigned char i = static_cast(c); + + if(i < 32 || i > 126) + { + if(toStringMode == ICE_ENUM(ToStringMode, Compat)) + { + // append octal string + + // Add leading zeroes so that we avoid problems during + // decoding. For example, consider the escaped string + // \0013 (i.e., a character with value 1 followed by the + // character '3'). If the leading zeroes were omitted, the + // result would be incorrectly interpreted as a single + // character with value 11. + // + ostringstream os; + os << '\\' << oct << setfill('0') << setw(3) << static_cast(i); + result.append(os.str()); + } + else if(i < 32 || i == 127) + { + // append \u00nn + result.append("\\u00"); + result.push_back(toHexDigit(i >> 4)); + result.push_back(toHexDigit(i & 0x0F)); + } + else if(toStringMode == ICE_ENUM(ToStringMode, ASCII)) + { + // append \unnnn or \Unnnnnnnn after reading more UTF-8 bytes + appendUniversalName(c, p, u8s.end(), result); + } + else + { + // keep as is + result.push_back(c); + } + } + else + { + // printable ASCII character + result.push_back(c); + } + } + break; + } + } + } + + if(toStringMode == ICE_ENUM(ToStringMode, Unicode)) + { + // + // Convert back to Native + // + result = UTF8ToNative(result, getProcessStringConverter()); + } + // else it's a pure ASCII string + + return result; +} + +namespace +{ + +char +checkChar(const string& s, string::size_type pos) +{ + unsigned char c = static_cast(s[pos]); + if(c < 32 || c == 127) + { + ostringstream ostr; + if(pos > 0) + { + ostr << "character after `" << s.substr(0, pos) << "'"; + } + else + { + ostr << "first character"; + } + ostr << " has invalid ordinal value " << static_cast(c); + throw IllegalArgumentException(__FILE__, __LINE__, ostr.str()); + } + return static_cast(c); +} + +// +// Append codePoint as a UTF-8 sequence +// +void +appendUTF8(unsigned int codePoint, string& result) +{ + if(codePoint >= 0xD800 && codePoint <= 0xDFFF) + { + throw IllegalArgumentException(__FILE__, __LINE__, + "A universal character name cannot designate a surrogate"); + } + + if(codePoint <= 0x7F) + { + // ASCII + result.push_back(static_cast(codePoint)); + } + else if(codePoint <= 0x7FF) + { + // 2 bytes + result.push_back(static_cast((codePoint >> 6) | 0xC0)); + result.push_back(static_cast((codePoint & 0x3F) | 0x80)); + } + else if(codePoint <= 0xFFFF) + { + // 3 bytes + result.push_back(static_cast((codePoint >> 12) | 0xE0)); + result.push_back(static_cast(((codePoint >> 6) & 0x3F) | 0x80)); + result.push_back(static_cast((codePoint & 0x3F) | 0x80)); + } + else if(codePoint <= 0x10FFFF) + { + // 4 bytes + result.push_back(static_cast((codePoint >> 18) | 0xF0)); + result.push_back(static_cast(((codePoint >> 12) & 0x3F) | 0x80)); + result.push_back(static_cast(((codePoint >> 6) & 0x3F) | 0x80)); + result.push_back(static_cast((codePoint & 0x3F) | 0x80)); + } + else + { + throw IllegalArgumentException(__FILE__, __LINE__, "Invalid universal character name"); + } +} + +// +// Decode the character or escape sequence starting at start and appends it to result; +// end marks the one-past-the-end position of the substring to be scanned. +// nextStart is set to the index of the first character following the decoded +// character or escape sequence. +// +bool +decodeChar(const string& s, string::size_type start, string::size_type end, string::size_type& nextStart, + const string& special, string& result) +{ + assert(start < end); + assert(end <= s.size()); + + bool pureASCII = true; + + if(s[start] != '\\') + { + result.push_back(checkChar(s, start++)); + } + else if(start + 1 == end) + { + // Keep trailing backslash + ++start; + result.push_back('\\'); + } + else + { + char c = s[++start]; + + switch(c) + { + case '\\': + case '\'': + case '"': + case '?': + { + ++start; + result.push_back(c); + break; + } + case 'a': + { + ++start; + result.push_back('\a'); + break; + } + case 'b': + { + ++start; + result.push_back('\b'); + break; + } + case 'f': + { + ++start; + result.push_back('\f'); + break; + } + case 'n': + { + ++start; + result.push_back('\n'); + break; + } + case 'r': + { + ++start; + result.push_back('\r'); + break; + } + case 't': + { + ++start; + result.push_back('\t'); + break; + } + case 'v': + { + ++start; + result.push_back('\v'); + break; + } + case 'u': + case 'U': + { + unsigned int codePoint = 0; + bool inBMP = (c == 'u'); + int size = inBMP ? 4 : 8; + ++start; + while(size > 0 && start < end) + { + c = s[start++]; + int charVal = 0; + if(c >= '0' && c <= '9') + { + charVal = c - '0'; + } + else if(c >= 'a' && c <= 'f') + { + charVal = 10 + (c - 'a'); + } + else if(c >= 'A' && c <= 'F') + { + charVal = 10 + (c - 'A'); + } + else + { + break; // while + } + codePoint = codePoint * 16 + static_cast(charVal); + --size; + } + if(size > 0) + { + throw IllegalArgumentException(__FILE__, __LINE__, + "Invalid universal character name: too few hex digits"); + } + + appendUTF8(codePoint, result); + if(codePoint > 127) + { + pureASCII = false; + } + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int val = 0; + for(int j = 0; j < 3 && start < end; ++j) + { + int charVal = s[start++] - '0'; + if(charVal < 0 || charVal > 7) + { + --start; + break; + } + val = val * 8 + charVal; + } + if(val > 255) + { + ostringstream ostr; + ostr << "octal value \\" << oct << val << dec << " (" << val << ") is out of range"; + throw IllegalArgumentException(__FILE__, __LINE__, ostr.str()); + } + result.push_back(static_cast(val)); + if(val > 127) + { + pureASCII = false; + } + break; + } + case 'x': + { + int val = 0; + int size = 2; + ++start; + while(size > 0 && start < end) + { + c = s[start++]; + int charVal = 0; + if(c >= '0' && c <= '9') + { + charVal = c - '0'; + } + else if(c >= 'a' && c <= 'f') + { + charVal = 10 + (c - 'a'); + } + else if(c >= 'A' && c <= 'F') + { + charVal = 10 + (c - 'A'); + } + else + { + --start; // move back + break; // while + } + val = val * 16 + charVal; + --size; + } + if(size == 2) + { + throw IllegalArgumentException(__FILE__, __LINE__, + "Invalid \\x escape sequence: no hex digit"); + } + result.push_back(static_cast(val)); + if(val > 127) + { + pureASCII = false; + } + break; + } + default: + { + if(static_cast(c) > 127) + { + pureASCII = false; + } + if(special.empty() || special.find(c) == string::npos) + { + result.push_back('\\'); // not in special, so we keep the backslash + } + result.push_back(checkChar(s, start++)); + break; + } + } + } + nextStart = start; + return pureASCII; +} + +} + +// +// Remove escape sequences added by escapeString. +// +string +IceUtilInternal::unescapeString(const string& s, string::size_type start, string::size_type end, const string& special) +{ + assert(start <= end && end <= s.size()); + + for(string::size_type i = 0; i < special.size(); ++i) + { + if(static_cast(special[i]) < 32 || static_cast(special[i]) > 126) + { + throw IllegalArgumentException(__FILE__, __LINE__, "Special characters must be in ASCII range 32-126"); + } + } + + // Optimization for strings without escapes + string::size_type p = s.find('\\', start); + if(p == string::npos || p >= end) + { + p = start; + while(p < end) + { + checkChar(s, p++); + } + return s.substr(start, end); + } + else + { + StringConverterPtr stringConverter = getProcessStringConverter(); + + const string* inputStringPtr = &s; + string u8s; + + if(stringConverter) + { + bool inputIsPureASCII = true; + string::size_type i = start; + while(i < end && inputIsPureASCII) + { + inputIsPureASCII = static_cast(s[i++]) <= 127; + } + + if(!inputIsPureASCII) + { + u8s = nativeToUTF8(s.substr(start, end), stringConverter); + inputStringPtr = &u8s; + start = 0; + end = u8s.size(); + } + } + + bool resultIsPureASCII = true; + string result; + result.reserve(end - start); + while(start < end) + { + if(decodeChar(*inputStringPtr, start, end, start, special, result)) + { + resultIsPureASCII = false; + } + } + + if(stringConverter && !resultIsPureASCII) + { + // Need to convert from UTF-8 to Native + result = UTF8ToNative(result, stringConverter); + } + + return result; + } +} + +bool +IceUtilInternal::splitString(const string& str, const string& delim, vector& result) +{ + string::size_type pos = 0; + string::size_type length = str.length(); + string elt; + + char quoteChar = '\0'; + while(pos < length) + { + if(quoteChar == '\0' && (str[pos] == '"' || str[pos] == '\'')) + { + quoteChar = str[pos++]; + continue; // Skip the quote + } + else if(quoteChar == '\0' && str[pos] == '\\' && pos + 1 < length && + (str[pos + 1] == '\'' || str[pos + 1] == '"')) + { + ++pos; + } + else if(quoteChar != '\0' && str[pos] == '\\' && pos + 1 < length && str[pos + 1] == quoteChar) + { + ++pos; + } + else if(quoteChar != '\0' && str[pos] == quoteChar) + { + ++pos; + quoteChar = '\0'; + continue; // Skip the end quote + } + else if(delim.find(str[pos]) != string::npos) + { + if(quoteChar == '\0') + { + ++pos; + if(elt.length() > 0) + { + result.push_back(elt); + elt = ""; + } + continue; + } + } + + if(pos < length) + { + elt += str[pos++]; + } + } + + if(elt.length() > 0) + { + result.push_back(elt); + } + if(quoteChar != '\0') + { + return false; // Unmatched quote. + } + return true; +} + +string +IceUtilInternal::joinString(const std::vector& values, const std::string& delimiter) +{ + ostringstream out; + for(unsigned int i = 0; i < values.size(); i++) + { + if(i != 0) + { + out << delimiter; + } + out << values[i]; + } + return out.str(); +} + +// +// Trim white space (" \t\r\n") +// +string +IceUtilInternal::trim(const string& s) +{ + static const string delim = " \t\r\n"; + string::size_type beg = s.find_first_not_of(delim); + if(beg == string::npos) + { + return ""; + } + else + { + return s.substr(beg, s.find_last_not_of(delim) - beg + 1); + } +} + +// +// If a single or double quotation mark is found at the start position, +// then the position of the matching closing quote is returned. If no +// quotation mark is found at the start position, then 0 is returned. +// If no matching closing quote is found, then -1 is returned. +// +string::size_type +IceUtilInternal::checkQuote(const string& s, string::size_type start) +{ + string::value_type quoteChar = s[start]; + if(quoteChar == '"' || quoteChar == '\'') + { + start++; + string::size_type pos; + while(start < s.size() && (pos = s.find(quoteChar, start)) != string::npos) + { + if(s[pos - 1] != '\\') + { + return pos; + } + start = pos + 1; + } + return string::npos; // Unmatched quote. + } + return 0; // Not quoted. +} + +// +// Match `s' against the pattern `pat'. A * in the pattern acts +// as a wildcard: it matches any non-empty sequence of characters. +// We match by hand here because it's portable across platforms +// (whereas regex() isn't). Only one * per pattern is supported. +// +bool +IceUtilInternal::match(const string& s, const string& pat, bool emptyMatch) +{ + assert(!s.empty()); + assert(!pat.empty()); + + // + // If pattern does not contain a wildcard just compare strings. + // + string::size_type beginIndex = pat.find('*'); + if(beginIndex == string::npos) + { + return s == pat; + } + + // + // Make sure start of the strings match + // + if(beginIndex > s.length() || s.substr(0, beginIndex) != pat.substr(0, beginIndex)) + { + return false; + } + + // + // Make sure there is something present in the middle to match the + // wildcard. If emptyMatch is true, allow a match of "". + // + string::size_type endLength = pat.length() - beginIndex - 1; + if(endLength > s.length()) + { + return false; + } + string::size_type endIndex = s.length() - endLength; + if(endIndex < beginIndex || (!emptyMatch && endIndex == beginIndex)) + { + return false; + } + + // + // Make sure end of the strings match + // + if(s.substr(endIndex, s.length()) != pat.substr(beginIndex + 1, pat.length())) + { + return false; + } + + return true; +} + +#ifdef _WIN32 + +string +IceUtilInternal::errorToString(int error, LPCVOID source) +{ + if(error < WSABASEERR) + { + LPWSTR msg = 0; + + DWORD stored = FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS | + (source != ICE_NULLPTR ? FORMAT_MESSAGE_FROM_HMODULE : 0), + source, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + reinterpret_cast(&msg), + 0, + ICE_NULLPTR); + + if(stored > 0) + { + assert(msg && wcslen(msg) > 0); + wstring result = msg; + if(result[result.length() - 1] == L'\n') + { + result = result.substr(0, result.length() - 2); + } + if(msg) + { + LocalFree(msg); + } + return wstringToString(result, getProcessStringConverter(), getProcessWstringConverter()); + } + else + { + ostringstream os; + os << "unknown error: " << error; + return os.str(); + } + } + + switch(error) + { + case WSAEINTR: + return "WSAEINTR"; + + case WSAEBADF: + return "WSAEBADF"; + + case WSAEACCES: + return "WSAEACCES"; + + case WSAEFAULT: + return "WSAEFAULT"; + + case WSAEINVAL: + return "WSAEINVAL"; + + case WSAEMFILE: + return "WSAEMFILE"; + + case WSAEWOULDBLOCK: + return "WSAEWOULDBLOCK"; + + case WSAEINPROGRESS: + return "WSAEINPROGRESS"; + + case WSAEALREADY: + return "WSAEALREADY"; + + case WSAENOTSOCK: + return "WSAENOTSOCK"; + + case WSAEDESTADDRREQ: + return "WSAEDESTADDRREQ"; + + case WSAEMSGSIZE: + return "WSAEMSGSIZE"; + + case WSAEPROTOTYPE: + return "WSAEPROTOTYPE"; + + case WSAENOPROTOOPT: + return "WSAENOPROTOOPT"; + + case WSAEPROTONOSUPPORT: + return "WSAEPROTONOSUPPORT"; + + case WSAESOCKTNOSUPPORT: + return "WSAESOCKTNOSUPPORT"; + + case WSAEOPNOTSUPP: + return "WSAEOPNOTSUPP"; + + case WSAEPFNOSUPPORT: + return "WSAEPFNOSUPPORT"; + + case WSAEAFNOSUPPORT: + return "WSAEAFNOSUPPORT"; + + case WSAEADDRINUSE: + return "WSAEADDRINUSE"; + + case WSAEADDRNOTAVAIL: + return "WSAEADDRNOTAVAIL"; + + case WSAENETDOWN: + return "WSAENETDOWN"; + + case WSAENETUNREACH: + return "WSAENETUNREACH"; + + case WSAENETRESET: + return "WSAENETRESET"; + + case WSAECONNABORTED: + return "WSAECONNABORTED"; + + case WSAECONNRESET: + return "WSAECONNRESET"; + + case WSAENOBUFS: + return "WSAENOBUFS"; + + case WSAEISCONN: + return "WSAEISCONN"; + + case WSAENOTCONN: + return "WSAENOTCONN"; + + case WSAESHUTDOWN: + return "WSAESHUTDOWN"; + + case WSAETOOMANYREFS: + return "WSAETOOMANYREFS"; + + case WSAETIMEDOUT: + return "WSAETIMEDOUT"; + + case WSAECONNREFUSED: + return "WSAECONNREFUSED"; + + case WSAELOOP: + return "WSAELOOP"; + + case WSAENAMETOOLONG: + return "WSAENAMETOOLONG"; + + case WSAEHOSTDOWN: + return "WSAEHOSTDOWN"; + + case WSAEHOSTUNREACH: + return "WSAEHOSTUNREACH"; + + case WSAENOTEMPTY: + return "WSAENOTEMPTY"; + + case WSAEPROCLIM: + return "WSAEPROCLIM"; + + case WSAEUSERS: + return "WSAEUSERS"; + + case WSAEDQUOT: + return "WSAEDQUOT"; + + case WSAESTALE: + return "WSAESTALE"; + + case WSAEREMOTE: + return "WSAEREMOTE"; + + case WSAEDISCON: + return "WSAEDISCON"; + + case WSASYSNOTREADY: + return "WSASYSNOTREADY"; + + case WSAVERNOTSUPPORTED: + return "WSAVERNOTSUPPORTED"; + + case WSANOTINITIALISED: + return "WSANOTINITIALISED"; + + case WSAHOST_NOT_FOUND: + return "WSAHOST_NOT_FOUND"; + + case WSATRY_AGAIN: + return "WSATRY_AGAIN"; + + case WSANO_RECOVERY: + return "WSANO_RECOVERY"; + + case WSANO_DATA: + return "WSANO_DATA"; + + default: + { + ostringstream os; + os << "unknown socket error: " << error; + return os.str(); + } + } +} + +string +IceUtilInternal::lastErrorToString() +{ + return errorToString(GetLastError()); +} + +#else + +string +IceUtilInternal::errorToString(int error) +{ + vector buffer(500); + while(true) + { +#if !defined(__GLIBC__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) + // + // Use the XSI-compliant version of strerror_r + // + int err = strerror_r(error, &buffer[0], buffer.size()); + if(err == 0) + { + return string(&buffer[0]); + } +#else + // + // Use the GNU-specific version of strerror_r + // + int oerrno = errno; + errno = 0; + const char* msg = strerror_r(error, &buffer[0], buffer.size()); + int err = errno; + errno = oerrno; + if(err == 0) + { + return msg; + } +#endif + if(err == ERANGE && buffer.size() < 1024 * 1024) + { + buffer.resize(buffer.size() * 2); + } + else + { + ostringstream os; + os << "Unknown error `" << error << "'"; + return os.str(); + } + } +} + +string +IceUtilInternal::lastErrorToString() +{ + return errorToString(errno); +} + +#endif + +string +IceUtilInternal::toLower(const std::string& s) +{ + string result; + result.reserve(s.size()); + for(unsigned int i = 0; i < s.length(); ++i) + { + if(isascii(s[i])) + { + result += static_cast(tolower(static_cast(s[i]))); + } + else + { + result += s[i]; + } + } + return result; +} + +string +IceUtilInternal::toUpper(const std::string& s) +{ + string result; + result.reserve(s.size()); + for(unsigned int i = 0; i < s.length(); ++i) + { + if(isascii(s[i])) + { + result += static_cast(toupper(static_cast(s[i]))); + } + else + { + result += s[i]; + } + } + return result; +} + +bool +IceUtilInternal::isAlpha(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +bool +IceUtilInternal::isDigit(char c) +{ + return c >= '0' && c <= '9'; +} + +string +IceUtilInternal::removeWhitespace(const std::string& s) +{ + string result; + for(unsigned int i = 0; i < s.length(); ++ i) + { + if(!isspace(static_cast(s[i]))) + { + result += s[i]; + } + } + return result; +} diff --git a/Sources/IceCpp/SysLoggerI.cpp b/Sources/IceCpp/SysLoggerI.cpp new file mode 100644 index 0000000..4850bfa --- /dev/null +++ b/Sources/IceCpp/SysLoggerI.cpp @@ -0,0 +1,166 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef _WIN32 + +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Ice::SysLoggerI::SysLoggerI(const string& prefix, const string& facilityString) : + _facility(0), + _prefix(prefix) +{ + if(facilityString == "LOG_KERN") + { + _facility = LOG_KERN; + } + else if(facilityString == "LOG_USER") + { + _facility = LOG_USER; + } + else if(facilityString == "LOG_MAIL") + { + _facility = LOG_MAIL; + } + else if(facilityString == "LOG_DAEMON") + { + _facility = LOG_DAEMON; + } + else if(facilityString == "LOG_AUTH") + { + _facility = LOG_AUTH; + } + else if(facilityString == "LOG_SYSLOG") + { + _facility = LOG_SYSLOG; + } + else if(facilityString == "LOG_LPR") + { + _facility = LOG_LPR; + } + else if(facilityString == "LOG_NEWS") + { + _facility = LOG_NEWS; + } + else if(facilityString == "LOG_UUCP") + { + _facility = LOG_UUCP; + } + else if(facilityString == "LOG_CRON") + { + _facility = LOG_CRON; + } +#ifdef LOG_AUTHPRIV + else if(facilityString == "LOG_AUTHPRIV") + { + _facility = LOG_AUTHPRIV; + } +#endif +#ifdef LOG_FTP + else if(facilityString == "LOG_FTP") + { + _facility = LOG_FTP; + } +#endif + else if(facilityString == "LOG_LOCAL0") + { + _facility = LOG_LOCAL0; + } + else if(facilityString == "LOG_LOCAL1") + { + _facility = LOG_LOCAL1; + } + else if(facilityString == "LOG_LOCAL2") + { + _facility = LOG_LOCAL2; + } + else if(facilityString == "LOG_LOCAL3") + { + _facility = LOG_LOCAL3; + } + else if(facilityString == "LOG_LOCAL4") + { + _facility = LOG_LOCAL4; + } + else if(facilityString == "LOG_LOCAL5") + { + _facility = LOG_LOCAL5; + } + else if(facilityString == "LOG_LOCAL6") + { + _facility = LOG_LOCAL6; + } + else if(facilityString == "LOG_LOCAL7") + { + _facility = LOG_LOCAL7; + } + else + { + throw InitializationException(__FILE__, __LINE__, "Invalid value for Ice.SyslogFacility: " + facilityString); + } + + int logopt = LOG_PID | LOG_CONS; + openlog(_prefix.c_str(), logopt, _facility); +} + +Ice::SysLoggerI::SysLoggerI(const string& prefix, int facility) : + _facility(facility), + _prefix(prefix) +{ + int logopt = LOG_PID | LOG_CONS; + openlog(_prefix.c_str(), logopt, facility); +} + +Ice::SysLoggerI::~SysLoggerI() +{ + closelog(); +} + +void +Ice::SysLoggerI::print(const string& message) +{ + IceUtil::Mutex::Lock sync(*this); + syslog(LOG_INFO, "%s", message.c_str()); +} + +void +Ice::SysLoggerI::trace(const string& category, const string& message) +{ + IceUtil::Mutex::Lock sync(*this); + string s = category + ": " + message; + syslog(LOG_INFO, "%s", s.c_str()); +} + +void +Ice::SysLoggerI::warning(const string& message) +{ + IceUtil::Mutex::Lock sync(*this); + syslog(LOG_WARNING, "%s", message.c_str()); +} + +void +Ice::SysLoggerI::error(const string& message) +{ + IceUtil::Mutex::Lock sync(*this); + syslog(LOG_ERR, "%s", message.c_str()); +} + +string +Ice::SysLoggerI::getPrefix() +{ + return _prefix; +} + +Ice::LoggerPtr +Ice::SysLoggerI::cloneWithPrefix(const string& prefix) +{ + return ICE_MAKE_SHARED(SysLoggerI, prefix, _facility); +} + +#endif diff --git a/Sources/IceCpp/SystemdJournalI.cpp b/Sources/IceCpp/SystemdJournalI.cpp new file mode 100644 index 0000000..cef24be --- /dev/null +++ b/Sources/IceCpp/SystemdJournalI.cpp @@ -0,0 +1,66 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifdef ICE_USE_SYSTEMD + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +Ice::SystemdJournalI::SystemdJournalI(const string& prefix) : + _prefix(prefix) +{ +} + +void +Ice::SystemdJournalI::print(const string& message) +{ + write(LOG_INFO, message); +} + +void +Ice::SystemdJournalI::trace(const string& category, const string& message) +{ + write(LOG_INFO, category + ": " + message); +} + +void +Ice::SystemdJournalI::warning(const string& message) +{ + write(LOG_WARNING, message); +} + +void +Ice::SystemdJournalI::error(const string& message) +{ + write(LOG_ERR, message); +} + +string +Ice::SystemdJournalI::getPrefix() +{ + return _prefix; +} + +Ice::LoggerPtr +Ice::SystemdJournalI::cloneWithPrefix(const string& prefix) +{ + return ICE_MAKE_SHARED(SystemdJournalI, prefix); +} + +void +Ice::SystemdJournalI::write(int priority, const string& message) const +{ + sd_journal_send("MESSAGE=%s", message.c_str(), + "PRIORITY=%i", priority, + "SYSLOG_IDENTIFIER=%s", _prefix.c_str(), + NULL); // Using NULL is necessary for EL7, see #293 +} + +#endif diff --git a/Sources/IceCpp/TcpAcceptor.cpp b/Sources/IceCpp/TcpAcceptor.cpp new file mode 100644 index 0000000..0528123 --- /dev/null +++ b/Sources/IceCpp/TcpAcceptor.cpp @@ -0,0 +1,234 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(ICE_USE_IOCP) +# include +#endif + +// +// Use the system default for the listen() backlog or 511 if not defined. +// +#ifndef SOMAXCONN +# define SOMAXCONN 511 +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(TcpAcceptor* p) { return p; } + +NativeInfoPtr +IceInternal::TcpAcceptor::getNativeInfo() +{ + return this; +} + +void +IceInternal::TcpAcceptor::close() +{ +#if defined(ICE_USE_IOCP) + if(_acceptFd != INVALID_SOCKET) + { + closeSocketNoThrow(_acceptFd); + _acceptFd = INVALID_SOCKET; + } +#endif + if(_fd != INVALID_SOCKET) + { + closeSocketNoThrow(_fd); + _fd = INVALID_SOCKET; + } +} + +EndpointIPtr +IceInternal::TcpAcceptor::listen() +{ + try + { + const_cast(_addr) = doBind(_fd, _addr); + doListen(_fd, _backlog); + } + catch(...) + { + _fd = INVALID_SOCKET; + throw; + } + _endpoint = _endpoint->endpoint(this); + return _endpoint; +} + +#if defined(ICE_USE_IOCP) + +AsyncInfo* +IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation) +{ + return &_info; +} + +void +IceInternal::TcpAcceptor::startAccept() +{ + LPFN_ACCEPTEX AcceptEx = ICE_NULLPTR; // a pointer to the 'AcceptEx()' function + GUID GuidAcceptEx = WSAID_ACCEPTEX; // The Guid + DWORD dwBytes; + if(WSAIoctl(_fd, + SIO_GET_EXTENSION_FUNCTION_POINTER, + &GuidAcceptEx, + sizeof(GuidAcceptEx), + &AcceptEx, + sizeof(AcceptEx), + &dwBytes, + ICE_NULLPTR, + ICE_NULLPTR) == SOCKET_ERROR) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + assert(_acceptFd == INVALID_SOCKET); + _acceptFd = createSocket(false, _addr); + const int sz = static_cast(_acceptBuf.size() / 2); + _info.error = ERROR_SUCCESS; + if(!AcceptEx(_fd, _acceptFd, &_acceptBuf[0], 0, sz, sz, &_info.count, &_info)) + { + if(!wouldBlock()) + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } +} + +void +IceInternal::TcpAcceptor::finishAccept() +{ + if(_info.error != ERROR_SUCCESS || _fd == INVALID_SOCKET) + { + closeSocketNoThrow(_acceptFd); + _acceptFd = INVALID_SOCKET; + _acceptError = _info.error; + } +} + +TransceiverPtr +IceInternal::TcpAcceptor::accept() +{ + if(_acceptFd == INVALID_SOCKET) + { + throw SocketException(__FILE__, __LINE__, _acceptError); + } + if(setsockopt(_acceptFd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&_acceptFd, sizeof(_acceptFd)) == + SOCKET_ERROR) + { + closeSocketNoThrow(_acceptFd); + _acceptFd = INVALID_SOCKET; + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + SOCKET fd = _acceptFd; + _acceptFd = INVALID_SOCKET; + return new TcpTransceiver(_instance, new StreamSocket(_instance, fd)); +} +#else + +TransceiverPtr +IceInternal::TcpAcceptor::accept() +{ + return new TcpTransceiver(_instance, new StreamSocket(_instance, doAccept(_fd))); +} + +#endif + +string +IceInternal::TcpAcceptor::protocol() const +{ + return _instance->protocol(); +} + +string +IceInternal::TcpAcceptor::toString() const +{ + return addrToString(_addr); +} + +string +IceInternal::TcpAcceptor::toDetailedString() const +{ + ostringstream os; + os << "local address = " << toString(); + vector intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true); + if(!intfs.empty()) + { + os << "\nlocal interfaces = "; + os << IceUtilInternal::joinString(intfs, ", "); + } + return os.str(); +} + +int +IceInternal::TcpAcceptor::effectivePort() const +{ + return getPort(_addr); +} + +IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint, + const ProtocolInstancePtr& instance, + const string& host, + int port) : + _endpoint(endpoint), + _instance(instance), + _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6(), true)) +#ifdef ICE_USE_IOCP + , _acceptFd(INVALID_SOCKET), _info(SocketOperationRead) +#endif +{ + _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); + _fd = createServerSocket(false, _addr, instance->protocolSupport()); + +#ifdef ICE_USE_IOCP + _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2); +#endif + + setBlock(_fd, false); + setTcpBufSize(_fd, _instance); + +#ifndef _WIN32 + // + // Enable SO_REUSEADDR on Unix platforms to allow re-using the + // socket even if it's in the TIME_WAIT state. On Windows, + // this doesn't appear to be necessary and enabling + // SO_REUSEADDR would actually not be a good thing since it + // allows a second process to bind to an address even it's + // already bound by another process. + // + // TODO: using SO_EXCLUSIVEADDRUSE on Windows would probably + // be better but it's only supported by recent Windows + // versions (XP SP2, Windows Server 2003). + // + setReuseAddress(_fd, true); +#endif +} + +IceInternal::TcpAcceptor::~TcpAcceptor() +{ + assert(_fd == INVALID_SOCKET); +#ifdef ICE_USE_IOCP + assert(_acceptFd == INVALID_SOCKET); +#endif +} + +#endif diff --git a/Sources/IceCpp/TcpConnector.cpp b/Sources/IceCpp/TcpConnector.cpp new file mode 100644 index 0000000..39346fb --- /dev/null +++ b/Sources/IceCpp/TcpConnector.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +TransceiverPtr +IceInternal::TcpConnector::connect() +{ + return new TcpTransceiver(_instance, new StreamSocket(_instance, _proxy, _addr, _sourceAddr)); +} + +Short +IceInternal::TcpConnector::type() const +{ + return _instance->type(); +} + +string +IceInternal::TcpConnector::toString() const +{ + return addrToString(!_proxy ? _addr : _proxy->getAddress()); +} + +bool +IceInternal::TcpConnector::operator==(const Connector& r) const +{ + const TcpConnector* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(compareAddress(_addr, p->_addr) != 0) + { + return false; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(compareAddress(_sourceAddr, p->_sourceAddr) != 0) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + return true; +} + +bool +IceInternal::TcpConnector::operator<(const Connector& r) const +{ + const TcpConnector* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + int rc = compareAddress(_sourceAddr, p->_sourceAddr); + if(rc < 0) + { + return true; + } + else if(rc > 0) + { + return false; + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + return compareAddress(_addr, p->_addr) < 0; +} + +IceInternal::TcpConnector::TcpConnector(const ProtocolInstancePtr& instance, const Address& addr, + const NetworkProxyPtr& proxy, const Address& sourceAddr, + Ice::Int timeout, const string& connectionId) : + _instance(instance), + _addr(addr), + _proxy(proxy), + _sourceAddr(sourceAddr), + _timeout(timeout), + _connectionId(connectionId) +{ +} + +IceInternal::TcpConnector::~TcpConnector() +{ +} +#endif diff --git a/Sources/IceCpp/TcpEndpointI.cpp b/Sources/IceCpp/TcpEndpointI.cpp new file mode 100644 index 0000000..5ea6292 --- /dev/null +++ b/Sources/IceCpp/TcpEndpointI.cpp @@ -0,0 +1,385 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(TcpEndpointI* p) { return p; } +#endif + +extern "C" +{ + +Plugin* +createIceTCP(const CommunicatorPtr& c, const string&, const StringSeq&) +{ + return new EndpointFactoryPlugin(c, new TcpEndpointFactory(new ProtocolInstance(c, TCPEndpointType, "tcp", false))); +} + +} + +IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, const string& host, Int port, + const Address& sourceAddr, Int timeout, const string& connectionId, + bool compress) : + IPEndpointI(instance, host, port, sourceAddr, connectionId), + _timeout(timeout), + _compress(compress) +{ +} + +IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance) : + IPEndpointI(instance), + _timeout(instance->defaultTimeout()), + _compress(false) +{ +} + +IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : + IPEndpointI(instance, s), + _timeout(-1), + _compress(false) +{ + s->read(const_cast(_timeout)); + s->read(const_cast(_compress)); +} + +void +IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const +{ + IPEndpointI::streamWriteImpl(s); + s->write(_timeout); + s->write(_compress); +} + +EndpointInfoPtr +IceInternal::TcpEndpointI::getInfo() const ICE_NOEXCEPT +{ + TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, ICE_SHARED_FROM_CONST_THIS(TcpEndpointI)); + fillEndpointInfo(info.get()); + return info; +} + +Int +IceInternal::TcpEndpointI::timeout() const +{ + return _timeout; +} + +EndpointIPtr +IceInternal::TcpEndpointI::timeout(Int timeout) const +{ + if(timeout == _timeout) + { + return ICE_SHARED_FROM_CONST_THIS(TcpEndpointI); + } + else + { + return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _sourceAddr, timeout, _connectionId, _compress); + } +} + +bool +IceInternal::TcpEndpointI::compress() const +{ + return _compress; +} + +EndpointIPtr +IceInternal::TcpEndpointI::compress(bool compress) const +{ + if(compress == _compress) + { + return ICE_SHARED_FROM_CONST_THIS(TcpEndpointI); + } + else + { + return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _sourceAddr, _timeout, _connectionId, compress); + } +} + +bool +IceInternal::TcpEndpointI::datagram() const +{ + return false; +} + +TransceiverPtr +IceInternal::TcpEndpointI::transceiver() const +{ + return ICE_NULLPTR; +} + +AcceptorPtr +IceInternal::TcpEndpointI::acceptor(const string&) const +{ + return new TcpAcceptor(ICE_DYNAMIC_CAST(TcpEndpointI, ICE_SHARED_FROM_CONST_THIS(TcpEndpointI)), _instance, _host, _port); +} + +TcpEndpointIPtr +IceInternal::TcpEndpointI::endpoint(const TcpAcceptorPtr& acceptor) const +{ + int port = acceptor->effectivePort(); + if(_port == port) + { + return ICE_DYNAMIC_CAST(TcpEndpointI, ICE_SHARED_FROM_CONST_THIS(TcpEndpointI)); + } + else + { + return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, port, _sourceAddr, _timeout, _connectionId, _compress); + } +} + +string +IceInternal::TcpEndpointI::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + + s << IPEndpointI::options(); + + if(_timeout == -1) + { + s << " -t infinite"; + } + else + { + s << " -t " << _timeout; + } + + if(_compress) + { + s << " -z"; + } + + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::TcpEndpointI::operator==(const Endpoint& r) const +#else +IceInternal::TcpEndpointI::operator==(const LocalObject& r) const +#endif +{ + if(!IPEndpointI::operator==(r)) + { + return false; + } + + const TcpEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(_compress != p->_compress) + { + return false; + } + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::TcpEndpointI::operator<(const Endpoint& r) const +#else +IceInternal::TcpEndpointI::operator<(const LocalObject& r) const +#endif +{ + const TcpEndpointI* p = dynamic_cast(&r); + if(!p) + { + const EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + if(!_compress && p->_compress) + { + return true; + } + else if(p->_compress < _compress) + { + return false; + } + + return IPEndpointI::operator<(r); +} + +void +IceInternal::TcpEndpointI::hashInit(Ice::Int& h) const +{ + IPEndpointI::hashInit(h); + hashAdd(h, _timeout); + hashAdd(h, _compress); +} + +void +IceInternal::TcpEndpointI::fillEndpointInfo(IPEndpointInfo* info) const +{ + IPEndpointI::fillEndpointInfo(info); + info->timeout = _timeout; + info->compress = _compress; +} + +bool +IceInternal::TcpEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + if(IPEndpointI::checkOption(option, argument, endpoint)) + { + return true; + } + + switch(option[1]) + { + case 't': + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -t option in endpoint " + + endpoint); + } + + if(argument == "infinite") + { + const_cast(_timeout) = -1; + } + else + { + istringstream t(argument); + if(!(t >> const_cast(_timeout)) || !t.eof() || _timeout < 1) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid timeout value `" + argument + + "' in endpoint " + endpoint); + } + } + return true; + } + + case 'z': + { + if(!argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -z option in " + endpoint); + } + const_cast(_compress) = true; + return true; + } + + default: + { + return false; + } + } +} + +ConnectorPtr +IceInternal::TcpEndpointI::createConnector(const Address& address, const NetworkProxyPtr& proxy) const +{ + return new TcpConnector(_instance, address, proxy, _sourceAddr, _timeout, _connectionId); +} + +IPEndpointIPtr +IceInternal::TcpEndpointI::createEndpoint(const string& host, int port, const string& connectionId) const +{ + return ICE_MAKE_SHARED(TcpEndpointI, _instance, host, port, _sourceAddr, _timeout, connectionId, _compress); +} + +IceInternal::TcpEndpointFactory::TcpEndpointFactory(const ProtocolInstancePtr& instance) : _instance(instance) +{ +} + +IceInternal::TcpEndpointFactory::~TcpEndpointFactory() +{ +} + +Short +IceInternal::TcpEndpointFactory::type() const +{ + return _instance->type(); +} + +string +IceInternal::TcpEndpointFactory::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceInternal::TcpEndpointFactory::create(vector& args, bool oaEndpoint) const +{ + IPEndpointIPtr endpt = ICE_MAKE_SHARED(TcpEndpointI, _instance); + endpt->initWithOptions(args, oaEndpoint); + return endpt; +} + +EndpointIPtr +IceInternal::TcpEndpointFactory::read(InputStream* s) const +{ + return ICE_MAKE_SHARED(TcpEndpointI, _instance, s); +} + +void +IceInternal::TcpEndpointFactory::destroy() +{ + _instance = 0; +} + +EndpointFactoryPtr +IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance) const +{ + return new TcpEndpointFactory(instance); +} +#endif diff --git a/Sources/IceCpp/TcpTransceiver.cpp b/Sources/IceCpp/TcpTransceiver.cpp new file mode 100644 index 0000000..2bf1ba2 --- /dev/null +++ b/Sources/IceCpp/TcpTransceiver.cpp @@ -0,0 +1,135 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +NativeInfoPtr +IceInternal::TcpTransceiver::getNativeInfo() +{ + return _stream; +} + +SocketOperation +IceInternal::TcpTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) +{ + return _stream->connect(readBuffer, writeBuffer); +} + +SocketOperation +IceInternal::TcpTransceiver::closing(bool initiator, const Ice::LocalException&) +{ + // If we are initiating the connection closure, wait for the peer + // to close the TCP/IP connection. Otherwise, close immediately. + return initiator ? SocketOperationRead : SocketOperationNone; +} + +void +IceInternal::TcpTransceiver::close() +{ + _stream->close(); +} + +SocketOperation +IceInternal::TcpTransceiver::write(Buffer& buf) +{ + return _stream->write(buf); +} + +SocketOperation +IceInternal::TcpTransceiver::read(Buffer& buf) +{ + return _stream->read(buf); +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::TcpTransceiver::startWrite(Buffer& buf) +{ + return _stream->startWrite(buf); +} + +void +IceInternal::TcpTransceiver::finishWrite(Buffer& buf) +{ + _stream->finishWrite(buf); +} + +void +IceInternal::TcpTransceiver::startRead(Buffer& buf) +{ + _stream->startRead(buf); +} + +void +IceInternal::TcpTransceiver::finishRead(Buffer& buf) +{ + _stream->finishRead(buf); +} +#endif + +string +IceInternal::TcpTransceiver::protocol() const +{ + return _instance->protocol(); +} + +string +IceInternal::TcpTransceiver::toString() const +{ + return _stream->toString(); +} + +string +IceInternal::TcpTransceiver::toDetailedString() const +{ + return toString(); +} + +Ice::ConnectionInfoPtr +IceInternal::TcpTransceiver::getInfo() const +{ + TCPConnectionInfoPtr info = ICE_MAKE_SHARED(TCPConnectionInfo); + fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + if(_stream->fd() != INVALID_SOCKET) + { + info->rcvSize = getRecvBufferSize(_stream->fd()); + info->sndSize = getSendBufferSize(_stream->fd()); + } + return info; +} + +void +IceInternal::TcpTransceiver::checkSendSize(const Buffer&) +{ +} + +void +IceInternal::TcpTransceiver::setBufferSize(int rcvSize, int sndSize) +{ + _stream->setBufferSize(rcvSize, sndSize); +} + +IceInternal::TcpTransceiver::TcpTransceiver(const ProtocolInstancePtr& instance, const StreamSocketPtr& stream) : + _instance(instance), + _stream(stream) +{ +} + +IceInternal::TcpTransceiver::~TcpTransceiver() +{ +} +#endif diff --git a/Sources/IceCpp/Thread.cpp b/Sources/IceCpp/Thread.cpp new file mode 100644 index 0000000..529a4ad --- /dev/null +++ b/Sources/IceCpp/Thread.cpp @@ -0,0 +1,569 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifdef __sun +// +// Solaris 10 bug: it's supposed to be defined in pthread.h +// +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 + #include + #include +#endif + +using namespace std; +using namespace IceInternal; + +#if defined(_WIN32) + +IceUtil::ThreadControl::ThreadControl() : + _handle(0), + _id(GetCurrentThreadId()) +{ +} + +IceUtil::ThreadControl::ThreadControl(HANDLE handle, IceUtil::ThreadControl::ID id) : + _handle(handle), + _id(id) +{ +} + +bool +IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const +{ + return _id == rhs._id; +} + +bool +IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const +{ + return _id != rhs._id; +} + +void +IceUtil::ThreadControl::join() +{ + if(_handle == 0) + { + throw BadThreadControlException(__FILE__, __LINE__); + } + + DWORD rc = WaitForSingleObjectEx(_handle, INFINITE, true); + if(rc != WAIT_OBJECT_0) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + + detach(); +} + +void +IceUtil::ThreadControl::detach() +{ + if(_handle == 0) + { + throw BadThreadControlException(__FILE__, __LINE__); + } + + if(CloseHandle(_handle) == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +IceUtil::ThreadControl::ID +IceUtil::ThreadControl::id() const +{ + return _id; +} + +void +IceUtil::ThreadControl::sleep(const Time& timeout) +{ + IceUtil::Int64 msTimeout = timeout.toMilliSeconds(); + if(msTimeout < 0 || msTimeout > 0x7FFFFFFF) + { + throw IceUtil::InvalidTimeoutException(__FILE__, __LINE__, timeout); + } + Sleep(static_cast(timeout.toMilliSeconds())); +} + +void +IceUtil::ThreadControl::yield() +{ + // + // A value of zero causes the thread to relinquish the remainder + // of its time slice to any other thread of equal priority that is + // ready to run. + // + Sleep(0); +} + +IceUtil::Thread::Thread() : + _started(false), + _running(false), + _handle(0), + _id(0) +{ +} + +IceUtil::Thread::Thread(const string& name) : + _name(name), + _started(false), + _running(false), + _handle(0), + _id(0) +{ +} + +IceUtil::Thread::~Thread() +{ +} + +static unsigned int +WINAPI startHook(void* arg) +{ + // Ensure that the thread doesn't go away until run() has + // completed. + // + IceUtil::ThreadPtr thread; + + try + { + IceUtil::Thread* rawThread = static_cast(arg); + + // + // Ensure that the thread doesn't go away until run() has + // completed. + // + thread = rawThread; + + // + // Initialize the random number generator in each thread on + // Windows (the rand() seed is thread specific). + // + unsigned int seed = static_cast(IceUtil::Time::now().toMicroSeconds()); + srand(seed ^ thread->getThreadControl().id()); + + // + // See the comment in IceUtil::Thread::start() for details. + // + rawThread->__decRef(); + thread->run(); + } + catch(...) + { + if(!thread->name().empty()) + { + consoleErr << thread->name() << " terminating" << endl; + } + std::terminate(); + } + + thread->_done(); + + return 0; +} + +#include + +IceUtil::ThreadControl +IceUtil::Thread::start(size_t stackSize) +{ + return start(stackSize, THREAD_PRIORITY_NORMAL); +} + +IceUtil::ThreadControl +IceUtil::Thread::start(size_t stackSize, int priority) +{ + // + // Keep this alive for the duration of start + // + IceUtil::ThreadPtr keepMe = this; + + IceUtil::Mutex::Lock lock(_stateMutex); + + if(_started) + { + throw ThreadStartedException(__FILE__, __LINE__); + } + + // + // It's necessary to increment the reference count since + // pthread_create won't necessarily call the thread function until + // later. If the user does (new MyThread)->start() then the thread + // object could be deleted before the thread object takes + // ownership. It's also necessary to increment the reference count + // prior to calling pthread_create since the thread itself calls + // __decRef(). + // + __incRef(); + + unsigned int id; + _handle = + reinterpret_cast( + _beginthreadex(0, + static_cast(stackSize), + startHook, this, + CREATE_SUSPENDED, + &id)); + _id = id; + assert(_handle != (HANDLE)-1L); + if(_handle == 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + if(SetThreadPriority(_handle, priority) == 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + if(static_cast(ResumeThread(_handle)) == -1) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + + _started = true; + _running = true; + + return ThreadControl(_handle, _id); +} + +IceUtil::ThreadControl +IceUtil::Thread::getThreadControl() const +{ + IceUtil::Mutex::Lock lock(_stateMutex); + if(!_started) + { + throw ThreadNotStartedException(__FILE__, __LINE__); + } + return ThreadControl(_handle, _id); +} + +bool +IceUtil::Thread::operator==(const Thread& rhs) const +{ + return this == &rhs; +} + +bool +IceUtil::Thread::operator<(const Thread& rhs) const +{ + return this < &rhs; +} + +bool +IceUtil::Thread::isAlive() const +{ + IceUtil::Mutex::Lock lock(_stateMutex); + return _running; +} + +void +IceUtil::Thread::_done() +{ + IceUtil::Mutex::Lock lock(_stateMutex); + _running = false; +} + +const string& +IceUtil::Thread::name() const +{ + return _name; +} + +#else + +IceUtil::ThreadControl::ThreadControl(pthread_t thread) : + _thread(thread), + _detachable(true) +{ +} + +IceUtil::ThreadControl::ThreadControl() : + _thread(pthread_self()), + _detachable(false) +{ +} + +bool +IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const +{ + return pthread_equal(_thread, rhs._thread) != 0; +} + +bool +IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const +{ + return !operator==(rhs); +} + +void +IceUtil::ThreadControl::join() +{ + if(!_detachable) + { + throw BadThreadControlException(__FILE__, __LINE__); + } + + void* status = 0; + int rc = pthread_join(_thread, &status); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +void +IceUtil::ThreadControl::detach() +{ + if(!_detachable) + { + throw BadThreadControlException(__FILE__, __LINE__); + } + + int rc = pthread_detach(_thread); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +IceUtil::ThreadControl::ID +IceUtil::ThreadControl::id() const +{ + return _thread; +} + +void +IceUtil::ThreadControl::sleep(const Time& timeout) +{ + IceUtil::Int64 msTimeout = timeout.toMilliSeconds(); + if(msTimeout < 0 || msTimeout > 0x7FFFFFFF) + { + throw IceUtil::InvalidTimeoutException(__FILE__, __LINE__, timeout); + } + struct timeval tv = timeout; + struct timespec ts; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000L; + nanosleep(&ts, 0); +} + +void +IceUtil::ThreadControl::yield() +{ + sched_yield(); +} + +IceUtil::Thread::Thread() : + _started(false), + _running(false) +{ +} + +IceUtil::Thread::Thread(const string& name) : + _name(name), + _started(false), + _running(false) +{ +} + +IceUtil::Thread::~Thread() +{ +} + +extern "C" +{ +static void* +startHook(void* arg) +{ + // + // Ensure that the thread doesn't go away until run() has + // completed. + // + IceUtil::ThreadPtr thread; + + try + { + IceUtil::Thread* rawThread = static_cast(arg); + + thread = rawThread; + + // + // See the comment in IceUtil::Thread::start() for details. + // + rawThread->__decRef(); + thread->run(); + } + catch(...) + { + if(!thread->name().empty()) + { + consoleErr << thread->name() << " terminating" << endl; + } + std::terminate(); + } + + thread->_done(); + + return 0; +} +} + +IceUtil::ThreadControl +IceUtil::Thread::start(size_t stackSize) +{ + return start(stackSize, false, 0); +} + +IceUtil::ThreadControl +IceUtil::Thread::start(size_t stackSize, int priority) +{ + return start(stackSize, true, priority); +} +IceUtil::ThreadControl +IceUtil::Thread::start(size_t stackSize, bool realtimeScheduling, int priority) +{ + // + // Keep this alive for the duration of start + // + IceUtil::ThreadPtr keepMe = this; + + IceUtil::Mutex::Lock lock(_stateMutex); + + if(_started) + { + throw ThreadStartedException(__FILE__, __LINE__); + } + + // + // It's necessary to increment the reference count since + // pthread_create won't necessarily call the thread function until + // later. If the user does (new MyThread)->start() then the thread + // object could be deleted before the thread object takes + // ownership. It's also necessary to increment the reference count + // prior to calling pthread_create since the thread itself calls + // __decRef(). + // + __incRef(); + + pthread_attr_t attr; + int rc = pthread_attr_init(&attr); + if(rc != 0) + { + __decRef(); + pthread_attr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + if(stackSize > 0) + { + if(stackSize < static_cast(PTHREAD_STACK_MIN)) + { + stackSize = static_cast(PTHREAD_STACK_MIN); + } +#ifdef __APPLE__ + if(stackSize % 4096 > 0) + { + stackSize = stackSize / 4096 * 4096 + 4096; + } +#endif + rc = pthread_attr_setstacksize(&attr, stackSize); + if(rc != 0) + { + __decRef(); + pthread_attr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + + if(realtimeScheduling) + { + rc = pthread_attr_setschedpolicy(&attr, SCHED_RR); + if(rc != 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + sched_param param; + param.sched_priority = priority; + rc = pthread_attr_setschedparam(&attr, ¶m); + if(rc != 0) + { + __decRef(); + pthread_attr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + } + rc = pthread_create(&_thread, &attr, startHook, this); + pthread_attr_destroy(&attr); + if(rc != 0) + { + __decRef(); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + _started = true; + _running = true; + return ThreadControl(_thread); +} + +IceUtil::ThreadControl +IceUtil::Thread::getThreadControl() const +{ + IceUtil::Mutex::Lock lock(_stateMutex); + if(!_started) + { + throw ThreadNotStartedException(__FILE__, __LINE__); + } + return ThreadControl(_thread); +} + +bool +IceUtil::Thread::operator==(const Thread& rhs) const +{ + return this == &rhs; +} + +bool +IceUtil::Thread::operator<(const Thread& rhs) const +{ + return this < &rhs; +} + +bool +IceUtil::Thread::isAlive() const +{ + IceUtil::Mutex::Lock lock(_stateMutex); + return _running; +} + +void +IceUtil::Thread::_done() +{ + IceUtil::Mutex::Lock lock(_stateMutex); + _running = false; +} + +const string& +IceUtil::Thread::name() const +{ + return _name; +} + +#endif diff --git a/Sources/IceCpp/ThreadException.cpp b/Sources/IceCpp/ThreadException.cpp new file mode 100644 index 0000000..2ba724a --- /dev/null +++ b/Sources/IceCpp/ThreadException.cpp @@ -0,0 +1,130 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; + +IceUtil::ThreadSyscallException::ThreadSyscallException(const char* file, int line, int err ): + SyscallExceptionHelper(file, line, err) +{ +} + +string +IceUtil::ThreadSyscallException::ice_id() const +{ + return "::IceUtil::ThreadSyscallException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::ThreadSyscallException* +IceUtil::ThreadSyscallException::ice_clone() const +{ + return new ThreadSyscallException(*this); +} +#endif + +IceUtil::ThreadLockedException::ThreadLockedException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +string +IceUtil::ThreadLockedException::ice_id() const +{ + return "::IceUtil::ThreadLockedException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::ThreadLockedException* +IceUtil::ThreadLockedException::ice_clone() const +{ + return new ThreadLockedException(*this); +} +#endif + +IceUtil::ThreadStartedException::ThreadStartedException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +string +IceUtil::ThreadStartedException::ice_id() const +{ + return "::IceUtil::ThreadStartedException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::ThreadStartedException* +IceUtil::ThreadStartedException::ice_clone() const +{ + return new ThreadStartedException(*this); +} +#endif + +IceUtil::ThreadNotStartedException::ThreadNotStartedException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +string +IceUtil::ThreadNotStartedException::ice_id() const +{ + return "::IceUtil::ThreadNotStartedException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::ThreadNotStartedException* +IceUtil::ThreadNotStartedException::ice_clone() const +{ + return new ThreadNotStartedException(*this); +} +#endif + +IceUtil::BadThreadControlException::BadThreadControlException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +string +IceUtil::BadThreadControlException::ice_id() const +{ + return "::IceUtil::BadThreadControlException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::BadThreadControlException* +IceUtil::BadThreadControlException::ice_clone() const +{ + return new BadThreadControlException(*this); +} +#endif + +IceUtil::InvalidTimeoutException::InvalidTimeoutException(const char* file, int line, + const IceUtil::Time& timeout) : + ExceptionHelper(file, line), + _timeout(timeout) +{ +} + +string +IceUtil::InvalidTimeoutException::ice_id() const +{ + return "::IceUtil::InvalidTimeoutException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::InvalidTimeoutException* +IceUtil::InvalidTimeoutException::ice_clone() const +{ + return new InvalidTimeoutException(*this); +} +#endif + +void +IceUtil::InvalidTimeoutException::ice_print(ostream& os) const +{ + Exception::ice_print(os); + os << ":\ninvalid timeout: " << _timeout << " seconds"; +} diff --git a/Sources/IceCpp/ThreadPool.cpp b/Sources/IceCpp/ThreadPool.cpp new file mode 100644 index 0000000..5a56c74 --- /dev/null +++ b/Sources/IceCpp/ThreadPool.cpp @@ -0,0 +1,1292 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__FreeBSD__) +# include +#endif + +using namespace std; +using namespace Ice; +using namespace Ice::Instrumentation; +using namespace IceInternal; + +ICE_API IceUtil::Shared* IceInternal::upCast(ThreadPool* p) { return p; } + +namespace +{ + +class ShutdownWorkItem : public ThreadPoolWorkItem +{ +public: + + ShutdownWorkItem(const InstancePtr& instance) : _instance(instance) + { + } + + virtual void + execute(ThreadPoolCurrent& current) + { + current.ioCompleted(); + try + { + _instance->objectAdapterFactory()->shutdown(); + } + catch(const CommunicatorDestroyedException&) + { + } + } + +private: + + const InstancePtr _instance; +}; + +class FinishedWorkItem : public ThreadPoolWorkItem +{ +public: + + FinishedWorkItem(const EventHandlerPtr& handler, bool close) : _handler(handler), _close(close) + { + } + + virtual void + execute(ThreadPoolCurrent& current) + { + _handler->finished(current, _close); + + // + // Break cyclic reference count. + // + if(_handler->getNativeInfo()) + { + _handler->getNativeInfo()->setReadyCallback(0); + } + } + +private: + + const EventHandlerPtr _handler; + const bool _close; +}; + +class JoinThreadWorkItem : public ThreadPoolWorkItem +{ +public: + + JoinThreadWorkItem(const IceUtil::ThreadPtr& thread) : _thread(thread) + { + } + + virtual void + execute(ThreadPoolCurrent&) + { + // No call to ioCompleted, this shouldn't block (and we don't want to cause + // a new thread to be started). + _thread->getThreadControl().join(); + } + +private: + + IceUtil::ThreadPtr _thread; +}; + +// +// Exception raised by the thread pool work queue when the thread pool +// is destroyed. +// +class ThreadPoolDestroyedException +{ +}; + +#ifdef ICE_SWIFT +string +prefixToDispatchQueueLabel(const std::string& prefix) +{ + if(prefix == "Ice.ThreadPool.Client") + { + return "com.zeroc.ice.client"; + } + + if(prefix == "Ice.ThreadPool.Server") + { + return "com.zeroc.ice.server"; + } + + string::size_type end = prefix.find_last_of(".ThreadPool"); + if(end == string::npos) + { + end = prefix.size(); + } + + return "com.zeroc.ice.oa." + prefix.substr(0, end); +} +#endif +} + +Ice::DispatcherCall::~DispatcherCall() +{ + // Out of line to avoid weak vtable +} + +Ice::Dispatcher::~Dispatcher() +{ + // Out of line to avoid weak vtable +} + +IceInternal::DispatchWorkItem::DispatchWorkItem() +{ +} + +IceInternal::DispatchWorkItem::DispatchWorkItem(const Ice::ConnectionPtr& connection) : _connection(connection) +{ +} + +void +IceInternal::DispatchWorkItem::execute(ThreadPoolCurrent& current) +{ + current.ioCompleted(); // Promote follower + current.dispatchFromThisThread(this); +} + +IceInternal::ThreadPoolWorkQueue::ThreadPoolWorkQueue(ThreadPool& threadPool) : + _threadPool(threadPool), + _destroyed(false) +{ + _registered = SocketOperationRead; +} + +void +IceInternal::ThreadPoolWorkQueue::destroy() +{ + //Lock sync(*this); Called with the thread pool locked + assert(!_destroyed); + _destroyed = true; +#if defined(ICE_USE_IOCP) + _threadPool._selector.completed(this, SocketOperationRead); +#else + _threadPool._selector.ready(this, SocketOperationRead, true); +#endif +} + +void +IceInternal::ThreadPoolWorkQueue::queue(const ThreadPoolWorkItemPtr& item) +{ + //Lock sync(*this); Called with the thread pool locked + _workItems.push_back(item); +#if defined(ICE_USE_IOCP) + _threadPool._selector.completed(this, SocketOperationRead); +#else + if(_workItems.size() == 1) + { + _threadPool._selector.ready(this, SocketOperationRead, true); + } +#endif +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::ThreadPoolWorkQueue::startAsync(SocketOperation) +{ + assert(false); + return false; +} + +bool +IceInternal::ThreadPoolWorkQueue::finishAsync(SocketOperation) +{ + assert(false); + return false; +} +#endif + +void +IceInternal::ThreadPoolWorkQueue::message(ThreadPoolCurrent& current) +{ + ThreadPoolWorkItemPtr workItem; + { + IceUtil::Monitor::Lock sync(_threadPool); + if(!_workItems.empty()) + { + workItem = _workItems.front(); + _workItems.pop_front(); + } +#if defined(ICE_USE_IOCP) + else + { + assert(_destroyed); + _threadPool._selector.completed(this, SocketOperationRead); + } +#else + if(_workItems.empty() && !_destroyed) + { + _threadPool._selector.ready(this, SocketOperationRead, false); + } +#endif + } + + if(workItem) + { + workItem->execute(current); + } + else + { + assert(_destroyed); + current.ioCompleted(); + throw ThreadPoolDestroyedException(); + } +} + +void +IceInternal::ThreadPoolWorkQueue::finished(ThreadPoolCurrent&, bool) +{ + assert(false); +} + +string +IceInternal::ThreadPoolWorkQueue::toString() const +{ + return "work queue"; +} + +NativeInfoPtr +IceInternal::ThreadPoolWorkQueue::getNativeInfo() +{ + return 0; +} + +IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& prefix, int timeout) : + _instance(instance), +#ifdef ICE_SWIFT + _dispatchQueue(dispatch_queue_create(prefixToDispatchQueueLabel(prefix).c_str(), + DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL)), +#else + _dispatcher(_instance->initializationData().dispatcher), +#endif + _destroyed(false), + _prefix(prefix), + _selector(instance), + _nextThreadId(0), + _size(0), + _sizeIO(0), + _sizeMax(0), + _sizeWarn(0), + _serialize(_instance->initializationData().properties->getPropertyAsInt(_prefix + ".Serialize") > 0), + _hasPriority(false), + _priority(0), + _serverIdleTime(timeout), + _threadIdleTime(0), + _stackSize(0), + _inUse(0), +#if !defined(ICE_USE_IOCP) + _inUseIO(0), + _nextHandler(_handlers.end()), +#endif + _promote(true) +{ + PropertiesPtr properties = _instance->initializationData().properties; +#ifdef _WIN32 + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + int nProcessors = sysInfo.dwNumberOfProcessors; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + static int ncpu[2] = { CTL_HW, HW_NCPU }; + int nProcessors; + size_t sz = sizeof(nProcessors); + if(sysctl(ncpu, 2, &nProcessors, &sz, 0, 0) == -1) + { + nProcessors = 1; + } +#else + int nProcessors = static_cast(sysconf(_SC_NPROCESSORS_ONLN)); + if(nProcessors == -1) + { + nProcessors = 1; + } +#endif + + // + // We use just one thread as the default. This is the fastest + // possible setting, still allows one level of nesting, and + // doesn't require to make the servants thread safe. + // + int size = properties->getPropertyAsIntWithDefault(_prefix + ".Size", 1); + if(size < 1) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".Size < 1; Size adjusted to 1"; + size = 1; + } + + int sizeMax = properties->getPropertyAsIntWithDefault(_prefix + ".SizeMax", size); + if(sizeMax == -1) + { + sizeMax = nProcessors; + } + + if(sizeMax < size) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".SizeMax < " << _prefix << ".Size; SizeMax adjusted to Size (" << size << ")"; + sizeMax = size; + } + + int sizeWarn = properties->getPropertyAsInt(_prefix + ".SizeWarn"); + if(sizeWarn != 0 && sizeWarn < size) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".SizeWarn < " << _prefix << ".Size; adjusted SizeWarn to Size (" << size << ")"; + sizeWarn = size; + } + else if(sizeWarn > sizeMax) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".SizeWarn > " << _prefix << ".SizeMax; adjusted SizeWarn to SizeMax (" << sizeMax << ")"; + sizeWarn = sizeMax; + } + + int threadIdleTime = properties->getPropertyAsIntWithDefault(_prefix + ".ThreadIdleTime", 60); + if(threadIdleTime < 0) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".ThreadIdleTime < 0; ThreadIdleTime adjusted to 0"; + threadIdleTime = 0; + } + + const_cast(_size) = size; + const_cast(_sizeMax) = sizeMax; + const_cast(_sizeWarn) = sizeWarn; + const_cast(_sizeIO) = min(sizeMax, nProcessors); + const_cast(_threadIdleTime) = threadIdleTime; + +#ifdef ICE_USE_IOCP + _selector.setup(_sizeIO); +#endif + +#if defined(__APPLE__) + // + // We use a default stack size of 1MB on macOS and the new C++11 mapping to allow transmitting + // class graphs with a depth of 100 (maximum default), 512KB is not enough otherwise. + // + int defaultStackSize = 1024 * 1024; // 1MB +#else + int defaultStackSize = 0; +#endif + int stackSize = properties->getPropertyAsIntWithDefault(_prefix + ".StackSize", defaultStackSize); + if(stackSize < 0) + { + Warning out(_instance->initializationData().logger); + out << _prefix << ".StackSize < 0; Size adjusted to OS default"; + stackSize = 0; + } + const_cast(_stackSize) = static_cast(stackSize); + + const_cast(_hasPriority) = properties->getProperty(_prefix + ".ThreadPriority") != ""; + const_cast(_priority) = properties->getPropertyAsInt(_prefix + ".ThreadPriority"); + if(!_hasPriority) + { + const_cast(_hasPriority) = properties->getProperty("Ice.ThreadPriority") != ""; + const_cast(_priority) = properties->getPropertyAsInt("Ice.ThreadPriority"); + } + + _workQueue = ICE_MAKE_SHARED(ThreadPoolWorkQueue, *this); + _selector.initialize(_workQueue.get()); + + if(_instance->traceLevels()->threadPool >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->threadPoolCat); + out << "creating " << _prefix << ": Size = " << _size << ", SizeMax = " << _sizeMax << ", SizeWarn = " + << _sizeWarn; + } + + __setNoDelete(true); + try + { + for(int i = 0 ; i < _size ; ++i) + { + EventHandlerThreadPtr thread = new EventHandlerThread(this, nextThreadId()); + if(_hasPriority) + { + thread->start(_stackSize, _priority); + } + else + { + thread->start(_stackSize); + } + _threads.insert(thread); + } + } + catch(const IceUtil::Exception& ex) + { + { + Error out(_instance->initializationData().logger); + out << "cannot create thread for `" << _prefix << "':\n" << ex; + } + + destroy(); + joinWithAllThreads(); + __setNoDelete(false); + throw; + } + catch(...) + { + __setNoDelete(false); + throw; + } + __setNoDelete(false); +} + +IceInternal::ThreadPool::~ThreadPool() +{ + assert(_destroyed); +#ifdef ICE_SWIFT + dispatch_release(_dispatchQueue); +#endif +} + +void +IceInternal::ThreadPool::destroy() +{ + Lock sync(*this); + if(_destroyed) + { + return; + } + _destroyed = true; + _workQueue->destroy(); +} + +void +IceInternal::ThreadPool::updateObservers() +{ + Lock sync(*this); + for(set::iterator p = _threads.begin(); p != _threads.end(); ++p) + { + (*p)->updateObserver(); + } +} + +void +IceInternal::ThreadPool::initialize(const EventHandlerPtr& handler) +{ + Lock sync(*this); + assert(!_destroyed); + _selector.initialize(handler.get()); + + class ReadyCallbackI : public ReadyCallback + { + public: + + ReadyCallbackI(const ThreadPoolPtr& threadPool, const EventHandlerPtr& handler) : + _threadPool(threadPool), _handler(handler) + { + } + + virtual void + ready(SocketOperation op, bool value) + { + _threadPool->ready(_handler, op, value); + } + + private: + + const ThreadPoolPtr _threadPool; + const EventHandlerPtr _handler; + }; + handler->getNativeInfo()->setReadyCallback(new ReadyCallbackI(this, handler)); +} + +void +IceInternal::ThreadPool::update(const EventHandlerPtr& handler, SocketOperation remove, SocketOperation add) +{ + Lock sync(*this); + assert(!_destroyed); + + // Don't remove what needs to be added + remove = static_cast(remove & ~add); + + // Don't remove/add if already un-registered or registered + remove = static_cast(handler->_registered & remove); + add = static_cast(~handler->_registered & add); + if(remove == add) + { + return; + } + + _selector.update(handler.get(), remove, add); +} + +bool +IceInternal::ThreadPool::finish(const EventHandlerPtr& handler, bool closeNow) +{ + Lock sync(*this); + assert(!_destroyed); +#if !defined(ICE_USE_IOCP) + closeNow = _selector.finish(handler.get(), closeNow); // This must be called before! + _workQueue->queue(new FinishedWorkItem(handler, !closeNow)); + return closeNow; +#else + UNREFERENCED_PARAMETER(closeNow); + + // If there are no pending asynchronous operations, we can call finish on the handler now. + if(!handler->_pending) + { + _workQueue->queue(new FinishedWorkItem(handler, false)); + _selector.finish(handler.get()); + } + else + { + handler->_finish = true; + } + return true; // Always close now to interrupt the pending call. +#endif +} + +void +IceInternal::ThreadPool::ready(const EventHandlerPtr& handler, SocketOperation op, bool value) +{ + Lock sync(*this); + if(_destroyed) + { + return; + } + _selector.ready(handler.get(), op, value); +} + +void +IceInternal::ThreadPool::dispatchFromThisThread(const DispatchWorkItemPtr& workItem) +{ +#ifdef ICE_SWIFT + dispatch_sync(_dispatchQueue, ^ + { + workItem->run(); + }); +#else + if(_dispatcher) + { + try + { +#ifdef ICE_CPP11_MAPPING + _dispatcher([workItem]() + { + workItem->run(); + }, + workItem->getConnection()); +#else + _dispatcher->dispatch(workItem, workItem->getConnection()); +#endif + } + catch(const std::exception& ex) + { + if(_instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) + { + Warning out(_instance->initializationData().logger); + out << "dispatch exception:\n" << ex; + } + } + catch(...) + { + if(_instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) + { + Warning out(_instance->initializationData().logger); + out << "dispatch exception:\nunknown c++ exception"; + } + } + } + else + { + workItem->run(); + } +#endif +} + +void +IceInternal::ThreadPool::dispatch(const DispatchWorkItemPtr& workItem) +{ + Lock sync(*this); + if(_destroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + _workQueue->queue(workItem); +} + +void +IceInternal::ThreadPool::joinWithAllThreads() +{ + assert(_destroyed); + + // + // _threads is immutable after destroy() has been called, + // therefore no synchronization is needed. (Synchronization + // wouldn't be possible here anyway, because otherwise the other + // threads would never terminate.) + // + for(set::iterator p = _threads.begin(); p != _threads.end(); ++p) + { + (*p)->getThreadControl().join(); + } + _selector.destroy(); +} + +string +IceInternal::ThreadPool::prefix() const +{ + return _prefix; +} + +#ifdef ICE_SWIFT + +dispatch_queue_t +IceInternal::ThreadPool::getDispatchQueue() const ICE_NOEXCEPT +{ + return _dispatchQueue; +} + +#endif + +void +IceInternal::ThreadPool::run(const EventHandlerThreadPtr& thread) +{ +#if !defined(ICE_USE_IOCP) + ThreadPoolCurrent current(_instance, this, thread); + bool select = false; + while(true) + { + if(current._handler) + { + try + { + current._handler->message(current); + } + catch(const ThreadPoolDestroyedException&) + { + Lock sync(*this); + --_inUse; + thread->setState(ICE_ENUM(ThreadState, ThreadStateIdle)); + return; + } + catch(const exception& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in `" << _prefix << "':\n" << ex << "\nevent handler: " + << current._handler->toString(); + } + catch(...) + { + Error out(_instance->initializationData().logger); + out << "exception in `" << _prefix << "':\nevent handler: " << current._handler->toString(); + } + } + else if(select) + { + try + { + _selector.select(_serverIdleTime); + } + catch(const SelectorTimeoutException&) + { + Lock sync(*this); + if(!_destroyed && _inUse == 0) + { + _workQueue->queue(new ShutdownWorkItem(_instance)); // Select timed-out. + } + continue; + } + } + + { + Lock sync(*this); + if(!current._handler) + { + if(select) + { + _selector.finishSelect(_handlers); + _nextHandler = _handlers.begin(); + select = false; + } + else if(!current._leader && followerWait(current)) + { + return; // Wait timed-out. + } + } + else if(_sizeMax > 1) + { + if(!current._ioCompleted) + { + // + // The handler didn't call ioCompleted() so we take care of decreasing + // the IO thread count now. + // + --_inUseIO; + } + else + { + // + // If the handler called ioCompleted(), we re-enable the handler in + // case it was disabled and we decrease the number of thread in use. + // + if(_serialize && current._handler.get() != _workQueue.get()) + { + _selector.enable(current._handler.get(), current.operation); + } + assert(_inUse > 0); + --_inUse; + } + + if(!current._leader && followerWait(current)) + { + return; // Wait timed-out. + } + } + + // + // Get the next ready handler. + // + while(_nextHandler != _handlers.end() && + !(_nextHandler->second & ~_nextHandler->first->_disabled & _nextHandler->first->_registered)) + { + ++_nextHandler; + } + if(_nextHandler != _handlers.end()) + { + current._ioCompleted = false; + current._handler = ICE_GET_SHARED_FROM_THIS(_nextHandler->first); + current.operation = _nextHandler->second; + ++_nextHandler; + thread->setState(ICE_ENUM(ThreadState, ThreadStateInUseForIO)); + } + else + { + current._handler = 0; + } + + if(!current._handler) + { + // + // If there are no more ready handlers and there are still threads busy performing + // IO, we give up leadership and promote another follower (which will perform the + // select() only once all the IOs are completed). Otherwise, if there are no more + // threads peforming IOs, it's time to do another select(). + // + if(_inUseIO > 0) + { + promoteFollower(current); + } + else + { + _handlers.clear(); + _selector.startSelect(); + select = true; + thread->setState(ICE_ENUM(ThreadState, ThreadStateIdle)); + } + } + else if(_sizeMax > 1) + { + // + // Increment the IO thread count and if there are still threads available + // to perform IO and more handlers ready, we promote a follower. + // + ++_inUseIO; + if(_nextHandler != _handlers.end() && _inUseIO < _sizeIO) + { + promoteFollower(current); + } + } + } + } +#else + ThreadPoolCurrent current(_instance, this, thread); + while(true) + { + try + { + current._ioCompleted = false; + current._handler = ICE_GET_SHARED_FROM_THIS(_selector.getNextHandler(current.operation, current._count, + current._error, _threadIdleTime)); + } + catch(const SelectorTimeoutException&) + { + if(_sizeMax > 1) + { + Lock sync(*this); + + if(_destroyed) + { + continue; + } + else if(_inUse < static_cast(_threads.size() - 1)) // If not the last idle thread, we can exit. + { + BOOL hasIO = false; + GetThreadIOPendingFlag(GetCurrentThread(), &hasIO); + if(hasIO) + { + continue; + } + + if(_instance->traceLevels()->threadPool >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->threadPoolCat); + out << "shrinking " << _prefix << ": Size = " << (_threads.size() - 1); + } + _threads.erase(thread); + _workQueue->queue(new JoinThreadWorkItem(thread)); + return; + } + else if(_inUse > 0) + { + // + // If this is the last idle thread but there are still other threads + // busy dispatching, we go back waiting with _threadIdleTime. We only + // wait with _serverIdleTime when there's only one thread left. + // + continue; + } + assert(_threads.size() == 1); + } + + try + { + current._handler = ICE_GET_SHARED_FROM_THIS(_selector.getNextHandler(current.operation, current._count, + current._error, _serverIdleTime)); + } + catch(const SelectorTimeoutException&) + { + Lock sync(*this); + if(!_destroyed) + { + _workQueue->queue(new ShutdownWorkItem(_instance)); + } + continue; + } + } + + { + IceUtil::Monitor::Lock sync(*this); + thread->setState(ICE_ENUM(ThreadState, ThreadStateInUseForIO)); + } + + try + { + assert(current._handler); + current._handler->message(current); + } + catch(const ThreadPoolDestroyedException&) + { + return; + } + catch(const exception& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in `" << _prefix << "':\n" << ex << "\nevent handler: " << current._handler->toString(); + } + catch(...) + { + Error out(_instance->initializationData().logger); + out << "exception in `" << _prefix << "':\nevent handler: " << current._handler->toString(); + } + + { + Lock sync(*this); + if(_sizeMax > 1 && current._ioCompleted) + { + assert(_inUse > 0); + --_inUse; + } + thread->setState(ICE_ENUM(ThreadState, ThreadStateIdle)); + } + } +#endif +} + +bool +IceInternal::ThreadPool::ioCompleted(ThreadPoolCurrent& current) +{ + IceUtil::Monitor::Lock sync(*this); + + current._ioCompleted = true; // Set the IO completed flag to specifiy that ioCompleted() has been called. + + current._thread->setState(ICE_ENUM(ThreadState, ThreadStateInUseForUser)); + + if(_sizeMax > 1) + { + +#if !defined(ICE_USE_IOCP) + --_inUseIO; + + if(!_destroyed) + { + if(_serialize && current._handler.get() != _workQueue.get()) + { + _selector.disable(current._handler.get(), current.operation); + } + } + + if(current._leader) + { + // + // If this thread is still the leader, it's time to promote a new leader. + // + promoteFollower(current); + } + else if(_promote && (_nextHandler != _handlers.end() || _inUseIO == 0)) + { + notify(); + } +#endif + + assert(_inUse >= 0); + ++_inUse; + + if(_inUse == _sizeWarn) + { + Warning out(_instance->initializationData().logger); + out << "thread pool `" << _prefix << "' is running low on threads\n" + << "Size=" << _size << ", " << "SizeMax=" << _sizeMax << ", " << "SizeWarn=" << _sizeWarn; + } + + if(!_destroyed) + { + assert(_inUse <= static_cast(_threads.size())); + if(_inUse < _sizeMax && _inUse == static_cast(_threads.size())) + { + if(_instance->traceLevels()->threadPool >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->threadPoolCat); + out << "growing " << _prefix << ": Size=" << _threads.size() + 1; + } + + try + { + EventHandlerThreadPtr thread = new EventHandlerThread(this, nextThreadId()); + if(_hasPriority) + { + thread->start(_stackSize, _priority); + } + else + { + thread->start(_stackSize); + } + _threads.insert(thread); + } + catch(const IceUtil::Exception& ex) + { + Error out(_instance->initializationData().logger); + out << "cannot create thread for `" << _prefix << "':\n" << ex; + } + } + } + } + + return _serialize && current._handler.get() != _workQueue.get(); +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::ThreadPool::startMessage(ThreadPoolCurrent& current) +{ + assert(current._handler->_pending & current.operation); + + if(current._handler->_started & current.operation) + { + assert(!(current._handler->_completed & current.operation)); + current._handler->_completed = static_cast(current._handler->_completed | current.operation); + current._handler->_started = static_cast(current._handler->_started & ~current.operation); + + AsyncInfo* info = current._handler->getNativeInfo()->getAsyncInfo(current.operation); + info->count = current._count; + info->error = current._error; + + if(!current._handler->finishAsync(current.operation)) // Returns false if the handler is finished. + { + current._handler->_pending = static_cast(current._handler->_pending & ~current.operation); + if(!current._handler->_pending && current._handler->_finish) + { + Lock sync(*this); + _workQueue->queue(new FinishedWorkItem(current._handler, false)); + _selector.finish(current._handler.get()); + } + return false; + } + } + else if(!(current._handler->_completed & current.operation) && (current._handler->_registered & current.operation)) + { + assert(!(current._handler->_started & current.operation)); + if(current._handler->_ready & current.operation) + { + return true; + } + else if(!current._handler->startAsync(current.operation)) + { + current._handler->_pending = static_cast(current._handler->_pending & ~current.operation); + if(!current._handler->_pending && current._handler->_finish) + { + Lock sync(*this); + _workQueue->queue(new FinishedWorkItem(current._handler, false)); + _selector.finish(current._handler.get()); + } + return false; + } + else + { + current._handler->_started = static_cast(current._handler->_started | current.operation); + return false; + } + } + + if(current._handler->_registered & current.operation) + { + assert(current._handler->_completed & current.operation); + current._handler->_completed = static_cast(current._handler->_completed & ~current.operation); + return true; + } + else + { + current._handler->_pending = static_cast(current._handler->_pending & ~current.operation); + if(!current._handler->_pending && current._handler->_finish) + { + Lock sync(*this); + _workQueue->queue(new FinishedWorkItem(current._handler, false)); + _selector.finish(current._handler.get()); + } + return false; + } +} + +void +IceInternal::ThreadPool::finishMessage(ThreadPoolCurrent& current) +{ + if(current._handler->_registered & current.operation && !current._handler->_finish) + { + assert(!(current._handler->_completed & current.operation)); + if(current._handler->_ready & current.operation) + { + _selector.completed(current._handler.get(), current.operation); + } + else if(!current._handler->startAsync(current.operation)) + { + current._handler->_pending = static_cast(current._handler->_pending & ~current.operation); + } + else + { + assert(current._handler->_pending & current.operation); + current._handler->_started = static_cast(current._handler->_started | current.operation); + } + } + else + { + current._handler->_pending = static_cast(current._handler->_pending & ~current.operation); + } + + if(!current._handler->_pending && current._handler->_finish) + { + // There are no more pending async operations, it's time to call finish. + Lock sync(*this); + _workQueue->queue(new FinishedWorkItem(current._handler, false)); + _selector.finish(current._handler.get()); + } +} +#else +void +IceInternal::ThreadPool::promoteFollower(ThreadPoolCurrent& current) +{ + assert(!_promote && current._leader); + _promote = true; + if(_inUseIO < _sizeIO && (_nextHandler != _handlers.end() || _inUseIO == 0)) + { + notify(); + } + current._leader = false; +} + +bool +IceInternal::ThreadPool::followerWait(ThreadPoolCurrent& current) +{ + assert(!current._leader); + + current._thread->setState(ICE_ENUM(ThreadState, ThreadStateIdle)); + + // + // It's important to clear the handler before waiting to make sure that + // resources for the handler are released now if it's finished. We also + // clear the per-thread stream. + // + current._handler = 0; + current.stream.clear(); + current.stream.b.clear(); + + // + // Wait to be promoted and for all the IO threads to be done. + // + while(!_promote || _inUseIO == _sizeIO || (_nextHandler == _handlers.end() && _inUseIO > 0)) + { + if(_threadIdleTime) + { + if(!timedWait(IceUtil::Time::seconds(_threadIdleTime))) + { + if(!_destroyed && (!_promote || _inUseIO == _sizeIO || + (_nextHandler == _handlers.end() && _inUseIO > 0))) + { + if(_instance->traceLevels()->threadPool >= 1) + { + Trace out(_instance->initializationData().logger, _instance->traceLevels()->threadPoolCat); + out << "shrinking " << _prefix << ": Size=" << (_threads.size() - 1); + } + assert(_threads.size() > 1); // Can only be called by a waiting follower thread. + _threads.erase(current._thread); + _workQueue->queue(new JoinThreadWorkItem(current._thread)); + return true; + } + } + } + else + { + wait(); + } + } + current._leader = true; // The current thread has become the leader. + _promote = false; + return false; +} +#endif + +string +IceInternal::ThreadPool::nextThreadId() +{ + ostringstream os; + os << _prefix << "-" << _nextThreadId++; + return os.str(); +} + +IceInternal::ThreadPool::EventHandlerThread::EventHandlerThread(const ThreadPoolPtr& pool, const string& name) : + IceUtil::Thread(name), + _pool(pool), + _state(ICE_ENUM(ThreadState, ThreadStateIdle)) +{ + updateObserver(); +} + +void +IceInternal::ThreadPool::EventHandlerThread::updateObserver() +{ + // Must be called with the thread pool mutex locked + const CommunicatorObserverPtr& obsv = _pool->_instance->initializationData().observer; + if(obsv) + { + _observer.attach(obsv->getThreadObserver(_pool->_prefix, name(), _state, _observer.get())); + } +} + +void +IceInternal::ThreadPool::EventHandlerThread::setState(Ice::Instrumentation::ThreadState s) +{ + // Must be called with the thread pool mutex locked + if(_observer) + { + if(_state != s) + { + _observer->stateChanged(_state, s); + } + } + _state = s; +} + +void +IceInternal::ThreadPool::EventHandlerThread::run() +{ +#ifdef ICE_CPP11_MAPPING + if(_pool->_instance->initializationData().threadStart) +#else + if(_pool->_instance->initializationData().threadHook) +#endif + { + try + { +#ifdef ICE_CPP11_MAPPING + _pool->_instance->initializationData().threadStart(); +#else + _pool->_instance->initializationData().threadHook->start(); +#endif + } + catch(const exception& ex) + { + Error out(_pool->_instance->initializationData().logger); + out << "thread hook start() method raised an unexpected exception in `" << _pool->_prefix << "':\n" << ex; + } + catch(...) + { + Error out(_pool->_instance->initializationData().logger); + out << "thread hook start() method raised an unexpected exception in `" << _pool->_prefix << "'"; + } + } + + try + { + _pool->run(this); + } + catch(const exception& ex) + { + Error out(_pool->_instance->initializationData().logger); + out << "exception in `" << _pool->_prefix << "':\n" << ex; + } + catch(...) + { + Error out(_pool->_instance->initializationData().logger); + out << "unknown exception in `" << _pool->_prefix << "'"; + } + + _observer.detach(); + +#ifdef ICE_CPP11_MAPPING + if(_pool->_instance->initializationData().threadStop) +#else + if(_pool->_instance->initializationData().threadHook) +#endif + { + try + { +#ifdef ICE_CPP11_MAPPING + _pool->_instance->initializationData().threadStop(); +#else + _pool->_instance->initializationData().threadHook->stop(); +#endif + } + catch(const exception& ex) + { + Error out(_pool->_instance->initializationData().logger); + out << "thread hook stop() method raised an unexpected exception in `" << _pool->_prefix << "':\n" << ex; + } + catch(...) + { + Error out(_pool->_instance->initializationData().logger); + out << "thread hook stop() method raised an unexpected exception in `" << _pool->_prefix << "'"; + } + } + + _pool = 0; // Break cyclic dependency. +} + +ThreadPoolCurrent::ThreadPoolCurrent(const InstancePtr& instance, + const ThreadPoolPtr& threadPool, + const ThreadPool::EventHandlerThreadPtr& thread) : + operation(SocketOperationNone), + stream(instance.get(), Ice::currentProtocolEncoding), + _threadPool(threadPool.get()), + _thread(thread), + _ioCompleted(false) +#if !defined(ICE_USE_IOCP) + , _leader(false) +#endif +{ +} diff --git a/Sources/IceCpp/Time.cpp b/Sources/IceCpp/Time.cpp new file mode 100644 index 0000000..1c9a111 --- /dev/null +++ b/Sources/IceCpp/Time.cpp @@ -0,0 +1,307 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +#ifdef __APPLE__ +# include +# include +#endif + +using namespace IceUtil; + +#ifdef _WIN32 + +namespace +{ + +double frequency = -1.0; + +// +// Initialize the frequency +// +class InitializeFrequency +{ +public: + + InitializeFrequency() + { + // + // Get the frequency of performance counters. We also make a call to + // QueryPerformanceCounter to ensure it works. If it fails or if the + // call to QueryPerformanceFrequency fails, the frequency will remain + // set to -1.0 and ftime will be used instead. + // + Int64 v; + if(QueryPerformanceCounter(reinterpret_cast(&v))) + { + if(QueryPerformanceFrequency(reinterpret_cast(&v))) + { + frequency = static_cast(v); + } + } + } +}; +InitializeFrequency frequencyInitializer; + +} +#endif + +#if defined(__APPLE__) +namespace +{ + +double machMultiplier = 1.0; +class InitializeTime +{ +public: + + InitializeTime() + { + mach_timebase_info_data_t initTimeBase = { 0, 0 }; + mach_timebase_info(&initTimeBase); + machMultiplier = static_cast(initTimeBase.numer) / initTimeBase.denom / ICE_INT64(1000); + } +}; +InitializeTime initializeTime; + +} +#endif + +Time::Time() : + _usec(0) +{ +} + +Time +IceUtil::Time::now(Clock clock) +{ + if(clock == Realtime) + { +#ifdef _WIN32 +# if defined(_MSC_VER) + struct _timeb tb; + _ftime(&tb); +# elif defined(__MINGW32__) + struct timeb tb; + ftime(&tb); +# endif + return Time(static_cast(tb.time) * ICE_INT64(1000000) + Int64(tb.millitm) * 1000); +#else + struct timeval tv; + if(gettimeofday(&tv, 0) < 0) + { + assert(0); + throw SyscallException(__FILE__, __LINE__, errno); + } + return Time(tv.tv_sec * ICE_INT64(1000000) + tv.tv_usec); +#endif + } + else // Monotonic + { +#if defined(_WIN32) + if(frequency > 0.0) + { + Int64 count; + if(!QueryPerformanceCounter(reinterpret_cast(&count))) + { + assert(0); + throw SyscallException(__FILE__, __LINE__, GetLastError()); + } + return Time(static_cast(count / frequency * 1000000.0)); + } + else + { +# if defined(_MSC_VER) + struct _timeb tb; + _ftime(&tb); +# elif defined(__MINGW32__) + struct timeb tb; + ftime(&tb); +# endif + return Time(static_cast(tb.time) * ICE_INT64(1000000) + Int64(tb.millitm) * 1000); + } +#elif defined(__hppa) + // + // HP does not support CLOCK_MONOTONIC + // + struct timeval tv; + if(gettimeofday(&tv, 0) < 0) + { + assert(0); + throw SyscallException(__FILE__, __LINE__, errno); + } + return Time(tv.tv_sec * ICE_INT64(1000000) + tv.tv_usec); +#elif defined(__APPLE__) + return Time(static_cast(mach_absolute_time() * machMultiplier)); +#else + struct timespec ts; + if(clock_gettime(CLOCK_MONOTONIC, &ts) < 0) + { + assert(0); + throw SyscallException(__FILE__, __LINE__, errno); + } + return Time(ts.tv_sec * ICE_INT64(1000000) + ts.tv_nsec / ICE_INT64(1000)); +#endif + } +} + +Time +IceUtil::Time::seconds(Int64 t) +{ + return Time(t * ICE_INT64(1000000)); +} + +Time +IceUtil::Time::milliSeconds(Int64 t) +{ + return Time(t * ICE_INT64(1000)); +} + +Time +IceUtil::Time::microSeconds(Int64 t) +{ + return Time(t); +} + +Time +IceUtil::Time::secondsDouble(double t) +{ + return Time(Int64(t * 1000000)); +} + +Time +IceUtil::Time::milliSecondsDouble(double t) +{ + return Time(Int64(t * 1000)); +} + +Time +IceUtil::Time::microSecondsDouble(double t) +{ + return Time(Int64(t)); +} + +#ifndef _WIN32 +IceUtil::Time::operator timeval() const +{ + timeval tv; + tv.tv_sec = static_cast(_usec / 1000000); + tv.tv_usec = static_cast(_usec % 1000000); + return tv; +} +#endif + +Int64 +IceUtil::Time::toSeconds() const +{ + return _usec / 1000000; +} + +Int64 +IceUtil::Time::toMilliSeconds() const +{ + return _usec / 1000; +} + +Int64 +IceUtil::Time::toMicroSeconds() const +{ + return _usec; +} + +double +IceUtil::Time::toSecondsDouble() const +{ + return _usec / 1000000.0; +} + +double +IceUtil::Time::toMilliSecondsDouble() const +{ + return _usec / 1000.0; +} + +double +IceUtil::Time::toMicroSecondsDouble() const +{ + return static_cast(_usec); +} + +std::string +IceUtil::Time::toDateTime() const +{ + std::ostringstream os; + os << toString("%x %H:%M:%S") << "."; + os.fill('0'); + os.width(3); + os << static_cast(_usec % 1000000 / 1000); + return os.str(); +} + +std::string +IceUtil::Time::toDuration() const +{ + Int64 usecs = _usec % 1000000; + Int64 secs = _usec / 1000000 % 60; + Int64 mins = _usec / 1000000 / 60 % 60; + Int64 hours = _usec / 1000000 / 60 / 60 % 24; + Int64 days = _usec / 1000000 / 60 / 60 / 24; + + using namespace std; + + ostringstream os; + if(days != 0) + { + os << days << "d "; + } + os << setfill('0') << setw(2) << hours << ":" << setw(2) << mins << ":" << setw(2) << secs; + if(usecs != 0) + { + os << "." << setw(3) << (usecs / 1000); + } + + return os.str(); +} + +std::string +IceUtil::Time::toString(const std::string& format) const +{ + time_t time = static_cast(_usec / 1000000); + + struct tm tr; +#ifdef _MSC_VER + localtime_s(&tr, &time); +#else + localtime_r(&time, &tr); +#endif + + char buf[32]; + if(strftime(buf, sizeof(buf), format.c_str(), &tr) == 0) + { + return std::string(); + } + return std::string(buf); +} + +Time::Time(Int64 usec) : + _usec(usec) +{ +} + +std::ostream& +IceUtil::operator<<(std::ostream& out, const Time& tm) +{ + return out << tm.toMicroSeconds() / 1000000.0; +} diff --git a/Sources/IceCpp/Timer.cpp b/Sources/IceCpp/Timer.cpp new file mode 100644 index 0000000..4f4e2e3 --- /dev/null +++ b/Sources/IceCpp/Timer.cpp @@ -0,0 +1,263 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace std; +using namespace IceUtil; +using namespace IceInternal; + +TimerTask::~TimerTask() +{ + // Out of line to avoid weak vtable +} + +Timer::Timer() : + Thread("IceUtil timer thread"), + _destroyed(false) +{ + __setNoDelete(true); + start(); + __setNoDelete(false); +} + +Timer::Timer(int priority) : + Thread("IceUtil timer thread"), + _destroyed(false) +{ + __setNoDelete(true); + start(0, priority); + __setNoDelete(false); +} + +void +Timer::destroy() +{ + { + IceUtil::Monitor::Lock sync(_monitor); + if(_destroyed) + { + return; + } + _destroyed = true; + _monitor.notify(); + _tasks.clear(); + _tokens.clear(); + } + + if(getThreadControl() == ThreadControl()) + { + getThreadControl().detach(); + } + else + { + getThreadControl().join(); + } +} + +void +Timer::schedule(const TimerTaskPtr& task, const IceUtil::Time& delay) +{ + IceUtil::Monitor::Lock sync(_monitor); + if(_destroyed) + { + throw IllegalArgumentException(__FILE__, __LINE__, "timer destroyed"); + } + + IceUtil::Time now = IceUtil::Time::now(IceUtil::Time::Monotonic); + IceUtil::Time time = now + delay; + if(delay > IceUtil::Time() && time < now) + { + throw IllegalArgumentException(__FILE__, __LINE__, "invalid delay"); + } + + bool inserted = _tasks.insert(make_pair(task, time)).second; + if(!inserted) + { + throw IllegalArgumentException(__FILE__, __LINE__, "task is already scheduled"); + } + _tokens.insert(Token(time, IceUtil::Time(), task)); + + if(_wakeUpTime == IceUtil::Time() || time < _wakeUpTime) + { + _monitor.notify(); + } +} + +void +Timer::scheduleRepeated(const TimerTaskPtr& task, const IceUtil::Time& delay) +{ + IceUtil::Monitor::Lock sync(_monitor); + if(_destroyed) + { + throw IllegalArgumentException(__FILE__, __LINE__, "timer destroyed"); + } + + IceUtil::Time now = IceUtil::Time::now(IceUtil::Time::Monotonic); + const Token token(now + delay, delay, task); + if(delay > IceUtil::Time() && token.scheduledTime < now) + { + throw IllegalArgumentException(__FILE__, __LINE__, "invalid delay"); + } + + bool inserted = _tasks.insert(make_pair(task, token.scheduledTime)).second; + if(!inserted) + { + throw IllegalArgumentException(__FILE__, __LINE__, "task is already scheduled"); + } + _tokens.insert(token); + + if(_wakeUpTime == IceUtil::Time() || token.scheduledTime < _wakeUpTime) + { + _monitor.notify(); + } +} + +bool +Timer::cancel(const TimerTaskPtr& task) +{ + IceUtil::Monitor::Lock sync(_monitor); + if(_destroyed) + { + return false; + } + + map::iterator p = _tasks.find(task); + if(p == _tasks.end()) + { + return false; + } + + _tokens.erase(Token(p->second, IceUtil::Time(), p->first)); + _tasks.erase(p); + + return true; +} + +void +Timer::run() +{ + Token token(IceUtil::Time(), IceUtil::Time(), 0); + while(true) + { + { + IceUtil::Monitor::Lock sync(_monitor); + + if(!_destroyed) + { + // + // If the task we just ran is a repeated task, schedule it + // again for executation if it wasn't canceled. + // + if(token.delay != IceUtil::Time()) + { + map::iterator p = _tasks.find(token.task); + if(p != _tasks.end()) + { + token.scheduledTime = IceUtil::Time::now(IceUtil::Time::Monotonic) + token.delay; + p->second = token.scheduledTime; + _tokens.insert(token); + } + } + token = Token(IceUtil::Time(), IceUtil::Time(), 0); + + if(_tokens.empty()) + { + _wakeUpTime = IceUtil::Time(); + _monitor.wait(); + } + } + + if(_destroyed) + { + break; + } + + while(!_tokens.empty() && !_destroyed) + { + const IceUtil::Time now = IceUtil::Time::now(IceUtil::Time::Monotonic); + const Token& first = *(_tokens.begin()); + if(first.scheduledTime <= now) + { + token = first; + _tokens.erase(_tokens.begin()); + if(token.delay == IceUtil::Time()) + { + _tasks.erase(token.task); + } + break; + } + + _wakeUpTime = first.scheduledTime; + try + { + _monitor.timedWait(first.scheduledTime - now); + } + catch(const IceUtil::InvalidTimeoutException&) + { + IceUtil::Time timeout = (first.scheduledTime - now) / 2; + while(timeout > IceUtil::Time()) + { + try + { + _monitor.timedWait(timeout); + break; + } + catch(const IceUtil::InvalidTimeoutException&) + { + timeout = timeout / 2; + } + } + } + } + + if(_destroyed) + { + break; + } + } + + if(token.task) + { + try + { + runTimerTask(token.task); + } + catch(const IceUtil::Exception& e) + { + consoleErr << "IceUtil::Timer::run(): uncaught exception:\n" << e.what(); +#ifdef __GNUC__ + consoleErr << "\n" << e.ice_stackTrace(); +#endif + consoleErr << endl; + } + catch(const std::exception& e) + { + consoleErr << "IceUtil::Timer::run(): uncaught exception:\n" << e.what() << endl; + } + catch(...) + { + consoleErr << "IceUtil::Timer::run(): uncaught exception" << endl; + } + + if(token.delay == IceUtil::Time()) + { + // + // If thisthe task is not a repeated task, clear the task reference now rather than + // in the synchronization block above. Clearing the task reference might end up + // calling user code which could trigger a deadlock. See also issue #352. + // + token.task = ICE_NULLPTR; + } + } + } +} + +void +Timer::runTimerTask(const TimerTaskPtr& task) +{ + task->runTimerTask(); +} diff --git a/Sources/IceCpp/TraceLevels.cpp b/Sources/IceCpp/TraceLevels.cpp new file mode 100644 index 0000000..f4cd2dc --- /dev/null +++ b/Sources/IceCpp/TraceLevels.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(TraceLevels* p) { return p; } + +IceInternal::TraceLevels::TraceLevels(const PropertiesPtr& properties) : + network(0), + networkCat("Network"), + protocol(0), + protocolCat("Protocol"), + retry(0), + retryCat("Retry"), + location(0), + locationCat("Locator"), + slicing(0), + slicingCat("Slicing"), + gc(0), + gcCat("GC"), + threadPool(0), + threadPoolCat("ThreadPool") +{ + const string keyBase = "Ice.Trace."; + const_cast(network) = properties->getPropertyAsInt(keyBase + networkCat); + const_cast(protocol) = properties->getPropertyAsInt(keyBase + protocolCat); + const_cast(retry) = properties->getPropertyAsInt(keyBase + retryCat); + const_cast(location) = properties->getPropertyAsInt(keyBase + locationCat); + const_cast(slicing) = properties->getPropertyAsInt(keyBase + slicingCat); + const_cast(gc) = properties->getPropertyAsInt(keyBase + gcCat); + const_cast(threadPool) = properties->getPropertyAsInt(keyBase + threadPoolCat); +} diff --git a/Sources/IceCpp/TraceUtil.cpp b/Sources/IceCpp/TraceUtil.cpp new file mode 100644 index 0000000..e612e2d --- /dev/null +++ b/Sources/IceCpp/TraceUtil.cpp @@ -0,0 +1,478 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +static void +printIdentityFacetOperation(ostream& s, InputStream& stream) +{ + ToStringMode toStringMode = ICE_ENUM(ToStringMode, Unicode); + if(stream.instance()) + { + toStringMode = stream.instance()->toStringMode(); + } + + Identity identity; + stream.read(identity); + s << "\nidentity = " << Ice::identityToString(identity, toStringMode); + + vector facet; + stream.read(facet); + s << "\nfacet = "; + if(!facet.empty()) + { + s << escapeString(facet[0], "", toStringMode); + } + + string operation; + stream.read(operation, false); + s << "\noperation = " << operation; +} + +static string +getMessageTypeAsString(Byte type) +{ + switch(type) + { + case requestMsg: + return "request"; + case requestBatchMsg: + return "batch request"; + case replyMsg: + return "reply"; + case closeConnectionMsg: + return "close connection"; + case validateConnectionMsg: + return "validate connection"; + default: + return "unknown"; + } +} + +static void +printRequestHeader(ostream& s, InputStream& stream) +{ + printIdentityFacetOperation(s, stream); + + Byte mode; + stream.read(mode); + s << "\nmode = " << static_cast(mode) << ' '; + switch(static_cast(mode)) + { + case ICE_ENUM(OperationMode, Normal): + { + s << "(normal)"; + break; + } + + case ICE_ENUM(OperationMode, Nonmutating): + { + s << "(nonmutating)"; + break; + } + + case ICE_ENUM(OperationMode, Idempotent): + { + s << "(idempotent)"; + break; + } + + default: + { + s << "(unknown)"; + break; + } + } + + Int sz = stream.readSize(); + s << "\ncontext = "; + while(sz--) + { + pair pair; + stream.read(pair.first); + stream.read(pair.second); + s << pair.first << '/' << pair.second; + if(sz) + { + s << ", "; + } + } + + Ice::EncodingVersion v = stream.skipEncapsulation(); + if(v > Ice::Encoding_1_0) + { + s << "\nencoding = " << v; + } +} + +static Byte +printHeader(ostream& s, InputStream& stream) +{ + Byte magicNumber; + stream.read(magicNumber); // Don't bother printing the magic number + stream.read(magicNumber); + stream.read(magicNumber); + stream.read(magicNumber); + + Byte pMajor; + Byte pMinor; + stream.read(pMajor); + stream.read(pMinor); +// s << "\nprotocol version = " << static_cast(pMajor) +// << "." << static_cast(pMinor); + + Byte eMajor; + Byte eMinor; + stream.read(eMajor); + stream.read(eMinor); +// s << "\nencoding version = " << static_cast(eMajor) +// << "." << static_cast(eMinor); + + Byte type; + stream.read(type); + s << "\nmessage type = " << static_cast(type) << " (" << getMessageTypeAsString(type) << ')'; + + Byte compress; + stream.read(compress); + s << "\ncompression status = " << static_cast(compress) << ' '; + + switch(compress) + { + case 0: + { + s << "(not compressed; do not compress response, if any)"; + break; + } + + case 1: + { + s << "(not compressed; compress response, if any)"; + break; + } + + case 2: + { + s << "(compressed; compress response, if any)"; + break; + } + + default: + { + s << "(unknown)"; + break; + } + } + + Int size; + stream.read(size); + s << "\nmessage size = " << size; + + return type; +} + +static void +printRequest(ostream& s, InputStream& stream) +{ + Int requestId; + stream.read(requestId); + s << "\nrequest id = " << requestId; + if(requestId == 0) + { + s << " (oneway)"; + } + + printRequestHeader(s, stream); +} + +static void +printBatchRequest(ostream& s, InputStream& stream) +{ + int batchRequestNum; + stream.read(batchRequestNum); + s << "\nnumber of requests = " << batchRequestNum; + + for(int i = 0; i < batchRequestNum; ++i) + { + s << "\nrequest #" << i << ':'; + printRequestHeader(s, stream); + } +} + +static void +printReply(ostream& s, InputStream& stream) +{ + Int requestId; + stream.read(requestId); + s << "\nrequest id = " << requestId; + + Byte replyStatus; + stream.read(replyStatus); + s << "\nreply status = " << static_cast(replyStatus) << ' '; + switch(replyStatus) + { + case replyOK: + { + s << "(ok)"; + break; + } + + case replyUserException: + { + s << "(user exception)"; + break; + } + + case replyObjectNotExist: + case replyFacetNotExist: + case replyOperationNotExist: + { + switch(replyStatus) + { + case replyObjectNotExist: + { + s << "(object not exist)"; + break; + } + + case replyFacetNotExist: + { + s << "(facet not exist)"; + break; + } + + case replyOperationNotExist: + { + s << "(operation not exist)"; + break; + } + + default: + { + assert(false); + break; + } + } + + printIdentityFacetOperation(s, stream); + break; + } + + case replyUnknownException: + case replyUnknownLocalException: + case replyUnknownUserException: + { + switch(replyStatus) + { + case replyUnknownException: + { + s << "(unknown exception)"; + break; + } + + case replyUnknownLocalException: + { + s << "(unknown local exception)"; + break; + } + + case replyUnknownUserException: + { + s << "(unknown user exception)"; + break; + } + + default: + { + assert(false); + break; + } + } + + string unknown; + stream.read(unknown, false); + s << "\nunknown = " << unknown; + break; + } + + default: + { + s << "(unknown)"; + break; + } + } + + if(replyStatus == replyOK || replyStatus == replyUserException) + { + Ice::EncodingVersion v = stream.skipEncapsulation(); + if(v > Ice::Encoding_1_0) + { + s << "\nencoding = " << v; + } + } +} + +static Byte +printMessage(ostream& s, InputStream& stream) +{ + Byte type = printHeader(s, stream); + + switch(type) + { + case closeConnectionMsg: + case validateConnectionMsg: + { + // We're done. + break; + } + + case requestMsg: + { + printRequest(s, stream); + break; + } + + case requestBatchMsg: + { + printBatchRequest(s, stream); + break; + } + + case replyMsg: + { + printReply(s, stream); + break; + } + + default: + { + break; + } + } + + return type; +} + +namespace +{ + +IceUtil::Mutex* slicingMutex = 0; + +class Init +{ +public: + + Init() + { + slicingMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete slicingMutex; + slicingMutex = 0; + } +}; + +Init init; + +} + +void +IceInternal::traceSlicing(const char* kind, const string& typeId, const char* slicingCat, const LoggerPtr& logger) +{ + IceUtilInternal::MutexPtrLock lock(slicingMutex); + static set slicingIds; + if(slicingIds.insert(typeId).second) + { + string s("unknown "); + s += kind; + s += " type `" + typeId + "'"; + logger->trace(slicingCat, s); + } +} + +void +IceInternal::traceSend(const OutputStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) +{ + if(tl->protocol >= 1) + { + OutputStream& stream = const_cast(str); + InputStream is(stream.instance(), stream.getEncoding(), stream); + is.i = is.b.begin(); + + ostringstream s; + Byte type = printMessage(s, is); + + logger->trace(tl->protocolCat, "sending " + getMessageTypeAsString(type) + " " + s.str()); + } +} + +void +IceInternal::traceRecv(const InputStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) +{ + if(tl->protocol >= 1) + { + InputStream& stream = const_cast(str); + InputStream::Container::iterator p = stream.i; + stream.i = stream.b.begin(); + + ostringstream s; + Byte type = printMessage(s, stream); + + logger->trace(tl->protocolCat, "received " + getMessageTypeAsString(type) + " " + s.str()); + stream.i = p; + } +} + +void +IceInternal::trace(const char* heading, const OutputStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) +{ + if(tl->protocol >= 1) + { + OutputStream& stream = const_cast(str); + InputStream is(stream.instance(), stream.getEncoding(), stream); + is.i = is.b.begin(); + + ostringstream s; + s << heading; + printMessage(s, is); + + logger->trace(tl->protocolCat, s.str()); + } +} + +void +IceInternal::trace(const char* heading, const InputStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) +{ + if(tl->protocol >= 1) + { + InputStream& stream = const_cast(str); + InputStream::Container::iterator p = stream.i; + stream.i = stream.b.begin(); + + ostringstream s; + s << heading; + printMessage(s, stream); + + logger->trace(tl->protocolCat, s.str()); + stream.i = p; + } +} diff --git a/Sources/IceCpp/Transceiver.cpp b/Sources/IceCpp/Transceiver.cpp new file mode 100644 index 0000000..83de316 --- /dev/null +++ b/Sources/IceCpp/Transceiver.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(Transceiver* p) { return p; } + +EndpointIPtr +IceInternal::Transceiver::bind() +{ + assert(false); + return 0; +} diff --git a/Sources/IceCpp/UUID.cpp b/Sources/IceCpp/UUID.cpp new file mode 100644 index 0000000..e803d77 --- /dev/null +++ b/Sources/IceCpp/UUID.cpp @@ -0,0 +1,165 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +// On Windows, we use Windows's RPC UUID generator. +// On other platforms, we use a high quality random number generator +// (/dev/random) to generate "version 4" UUIDs, as described in +// http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-00.txt + +#include + +#ifdef _WIN32 +# include +#else +# include +# include +#endif + +using namespace std; + +#ifndef _WIN32 + +namespace +{ + +char myPid[2]; + +} + +namespace IceUtilInternal +{ + +// +// Initialize the pid. +// +class PidInitializer +{ +public: + + PidInitializer() + { + pid_t p = getpid(); + myPid[0] = (p >> 8) & 0x7F; + myPid[1] = static_cast(p & 0xFF); + } +}; + +PidInitializer pidInitializer; + +}; +#endif + +namespace +{ + +// Helper char to hex functions +// +inline void halfByteToHex(unsigned char hb, char*& hexBuffer) +{ + if(hb < 10) + { + *hexBuffer++ = '0' + static_cast(hb); + } + else + { + *hexBuffer++ = 'A' + static_cast(hb - 10); + } +} + +inline void bytesToHex(unsigned char* bytes, size_t len, char*& hexBuffer) +{ + for(size_t i = 0; i < len; i++) + { + halfByteToHex((bytes[i] & 0xF0) >> 4, hexBuffer); + halfByteToHex((bytes[i] & 0x0F), hexBuffer); + } +} + +} + +string +IceUtil::generateUUID() +{ +#if defined(_WIN32) + + UUID uuid; + RPC_STATUS ret = UuidCreate(&uuid); + if(ret != RPC_S_OK && ret != RPC_S_UUID_LOCAL_ONLY && ret != RPC_S_UUID_NO_ADDRESS) + { + throw SyscallException(__FILE__, __LINE__, GetLastError()); + } + + unsigned char* str; + + ret = UuidToString(&uuid, &str); + if(ret != RPC_S_OK) + { + throw SyscallException(__FILE__, __LINE__, GetLastError()); + } + string result = reinterpret_cast(str); + + RpcStringFree(&str); + return result; + +#else + struct UUID + { + unsigned char timeLow[4]; + unsigned char timeMid[2]; + unsigned char timeHighAndVersion[2]; + unsigned char clockSeqHiAndReserved; + unsigned char clockSeqLow; + unsigned char node[6]; + }; + UUID uuid; + + assert(sizeof(UUID) == 16); + + // + // Get a random sequence of bytes. Instead of using 122 random + // bits that could be duplicated (because of a bug with some Linux + // kernels and potentially other Unix platforms -- see comment in + // Random.cpp), we replace the last 15 bits of all "random" + // Randoms by the last 15 bits of the process id. + // + char* buffer = reinterpret_cast(&uuid); + IceUtilInternal::generateRandom(buffer, sizeof(UUID)); + + // + // Adjust the bits that say "version 4" UUID + // + uuid.timeHighAndVersion[0] &= 0x0F; + uuid.timeHighAndVersion[0] |= (4 << 4); + uuid.clockSeqHiAndReserved &= 0x3F; + uuid.clockSeqHiAndReserved |= 0x80; + + // + // Replace the end of the node by myPid (15 bits) + // + uuid.node[4] = (uuid.node[4] & 0x80) | static_cast(myPid[0]); + uuid.node[5] = static_cast(myPid[1]); + + // + // Convert to a UUID string + // + char uuidString[16 * 2 + 4 + 1]; // 16 bytes, 4 '-' and a final '\0' + char* uuidIndex = uuidString; + bytesToHex(uuid.timeLow, sizeof(uuid.timeLow), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.timeMid, sizeof(uuid.timeMid), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.timeHighAndVersion, sizeof(uuid.timeHighAndVersion), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(&uuid.clockSeqHiAndReserved, sizeof(uuid.clockSeqHiAndReserved), uuidIndex); + bytesToHex(&uuid.clockSeqLow, sizeof(uuid.clockSeqLow), uuidIndex); + *uuidIndex++ = '-'; + bytesToHex(uuid.node, sizeof(uuid.node), uuidIndex); + *uuidIndex = '\0'; + + return uuidString; + +#endif +} diff --git a/Sources/IceCpp/UdpConnector.cpp b/Sources/IceCpp/UdpConnector.cpp new file mode 100644 index 0000000..02d167d --- /dev/null +++ b/Sources/IceCpp/UdpConnector.cpp @@ -0,0 +1,131 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +TransceiverPtr +IceInternal::UdpConnector::connect() +{ + return new UdpTransceiver(_instance, _addr, _sourceAddr, _mcastInterface, _mcastTtl); +} + +Short +IceInternal::UdpConnector::type() const +{ + return _instance->type(); +} + +string +IceInternal::UdpConnector::toString() const +{ + return addrToString(_addr); +} + +bool +IceInternal::UdpConnector::operator==(const Connector& r) const +{ + const UdpConnector* p = dynamic_cast(&r); + if(!p) + { + return false; + } + if(compareAddress(_addr, p->_addr) != 0) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + if(_mcastTtl != p->_mcastTtl) + { + return false; + } + + if(_mcastInterface != p->_mcastInterface) + { + return false; + } + + if(compareAddress(_sourceAddr, p->_sourceAddr) != 0) + { + return false; + } + + return true; +} + +bool +IceInternal::UdpConnector::operator<(const Connector& r) const +{ + const UdpConnector* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + + if(_mcastTtl < p->_mcastTtl) + { + return true; + } + else if(p->_mcastTtl < _mcastTtl) + { + return false; + } + + if(_mcastInterface < p->_mcastInterface) + { + return true; + } + else if(p->_mcastInterface < _mcastInterface) + { + return false; + } + + int rc = compareAddress(_sourceAddr, p->_sourceAddr); + if(rc < 0) + { + return true; + } + else if(rc > 0) + { + return false; + } + return compareAddress(_addr, p->_addr) == -1; +} + +IceInternal::UdpConnector::UdpConnector(const ProtocolInstancePtr& instance, const Address& addr, + const Address& sourceAddr, const string& mcastInterface, int mcastTtl, + const std::string& connectionId) : + _instance(instance), + _addr(addr), + _sourceAddr(sourceAddr), + _mcastInterface(mcastInterface), + _mcastTtl(mcastTtl), + _connectionId(connectionId) +{ +} + +IceInternal::UdpConnector::~UdpConnector() +{ +} diff --git a/Sources/IceCpp/UdpEndpointI.cpp b/Sources/IceCpp/UdpEndpointI.cpp new file mode 100644 index 0000000..0d96785 --- /dev/null +++ b/Sources/IceCpp/UdpEndpointI.cpp @@ -0,0 +1,515 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(UdpEndpointI* p) { return p; } +#endif + +extern "C" +{ + +Plugin* +createIceUDP(const CommunicatorPtr& c, const string&, const StringSeq&) +{ + return new EndpointFactoryPlugin(c, new UdpEndpointFactory(new ProtocolInstance(c, UDPEndpointType, "udp", false))); +} + +} + +namespace Ice +{ + +ICE_API void +registerIceUDP(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceUDP", createIceUDP, loadOnInitialize); +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_API void +ICEregisterIceUDP(bool loadOnInitialize) +{ + Ice::registerIceUDP(loadOnInitialize); +} + +IceInternal::UdpEndpointI::UdpEndpointI(const ProtocolInstancePtr& instance, const string& host, Int port, + const Address& sourceAddr, const string& mcastInterface, Int mttl, bool conn, + const string& conId, bool co) : + IPEndpointI(instance, host, port, sourceAddr, conId), + _mcastTtl(mttl), + _mcastInterface(mcastInterface), + _connect(conn), + _compress(co) +{ +} + +IceInternal::UdpEndpointI::UdpEndpointI(const ProtocolInstancePtr& instance) : + IPEndpointI(instance), + _mcastTtl(-1), + _connect(false), + _compress(false) +{ +} + +IceInternal::UdpEndpointI::UdpEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : + IPEndpointI(instance, s), + _mcastTtl(-1), + _connect(false), + _compress(false) +{ + if(s->getEncoding() == Ice::Encoding_1_0) + { + Ice::Byte b; + s->read(b); + s->read(b); + s->read(b); + s->read(b); + } + // Not transmitted. + //s->read(const_cast(_connect)); + s->read(const_cast(_compress)); +} + +void +IceInternal::UdpEndpointI::streamWriteImpl(OutputStream* s) const +{ + IPEndpointI::streamWriteImpl(s); + if(s->getEncoding() == Ice::Encoding_1_0) + { + s->write(Ice::Protocol_1_0); + s->write(Ice::Encoding_1_0); + } + // Not transmitted. + //s->write(_connect); + s->write(_compress); +} + +EndpointInfoPtr +IceInternal::UdpEndpointI::getInfo() const ICE_NOEXCEPT +{ + Ice::UDPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, + ICE_DYNAMIC_CAST(UdpEndpointI, ICE_SHARED_FROM_CONST_THIS(UdpEndpointI))); + fillEndpointInfo(info.get()); + return info; +} + +Int +IceInternal::UdpEndpointI::timeout() const +{ + return -1; +} + +EndpointIPtr +IceInternal::UdpEndpointI::timeout(Int) const +{ + return ICE_SHARED_FROM_CONST_THIS(UdpEndpointI); +} + +bool +IceInternal::UdpEndpointI::compress() const +{ + return _compress; +} + +EndpointIPtr +IceInternal::UdpEndpointI::compress(bool compress) const +{ + if(compress == _compress) + { + return ICE_SHARED_FROM_CONST_THIS(UdpEndpointI); + } + else + { + return ICE_MAKE_SHARED(UdpEndpointI, _instance, _host, _port, _sourceAddr, _mcastInterface, _mcastTtl, + _connect, _connectionId, compress); + } +} + +bool +IceInternal::UdpEndpointI::datagram() const +{ + return true; +} + +TransceiverPtr +IceInternal::UdpEndpointI::transceiver() const +{ + return new UdpTransceiver(ICE_DYNAMIC_CAST(UdpEndpointI, ICE_SHARED_FROM_CONST_THIS(UdpEndpointI)), _instance, + _host, _port, _mcastInterface, _connect); +} + +AcceptorPtr +IceInternal::UdpEndpointI::acceptor(const string&) const +{ + return 0; +} + +UdpEndpointIPtr +IceInternal::UdpEndpointI::endpoint(const UdpTransceiverPtr& transceiver) const +{ + int port = transceiver->effectivePort(); + if(port == _port) + { + return ICE_DYNAMIC_CAST(UdpEndpointI, ICE_SHARED_FROM_CONST_THIS(UdpEndpointI)); + } + else + { + return ICE_MAKE_SHARED(UdpEndpointI, _instance, _host, port, _sourceAddr, _mcastInterface,_mcastTtl, _connect, + _connectionId, _compress); + } +} + +void +IceInternal::UdpEndpointI::initWithOptions(vector& args, bool oaEndpoint) +{ + IPEndpointI::initWithOptions(args, oaEndpoint); + + if(_mcastInterface == "*") + { + if(oaEndpoint) + { + const_cast(_mcastInterface) = string(); + } + else + { + throw EndpointParseException(__FILE__, __LINE__, "`--interface *' not valid for proxy endpoint `" + + toString() + "'"); + } + } +} + +string +IceInternal::UdpEndpointI::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + s << IPEndpointI::options(); + + if(_mcastInterface.length() > 0) + { + s << " --interface "; + bool addQuote = _mcastInterface.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _mcastInterface; + if(addQuote) + { + s << "\""; + } + } + + if(_mcastTtl != -1) + { + s << " --ttl " << _mcastTtl; + } + + if(_connect) + { + s << " -c"; + } + + if(_compress) + { + s << " -z"; + } + + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::UdpEndpointI::operator==(const Endpoint& r) const +#else +IceInternal::UdpEndpointI::operator==(const LocalObject& r) const +#endif +{ + if(!IPEndpointI::operator==(r)) + { + return false; + } + + const UdpEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_compress != p->_compress) + { + return false; + } + + if(_connect != p->_connect) + { + return false; + } + + if(_mcastTtl != p->_mcastTtl) + { + return false; + } + + if(_mcastInterface != p->_mcastInterface) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::UdpEndpointI::operator<(const Endpoint& r) const +#else +IceInternal::UdpEndpointI::operator<(const LocalObject& r) const +#endif +{ + const UdpEndpointI* p = dynamic_cast(&r); + if(!p) + { + const EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(!_compress && p->_compress) + { + return true; + } + else if(p->_compress < _compress) + { + return false; + } + + if(!_connect && p->_connect) + { + return true; + } + else if(!p->_connect && _connect) + { + return false; + } + + if(_mcastTtl < p->_mcastTtl) + { + return true; + } + else if(p->_mcastTtl < _mcastTtl) + { + return false; + } + + if(_mcastInterface < p->_mcastInterface) + { + return true; + } + else if(p->_mcastInterface < _mcastInterface) + { + return false; + } + + return IPEndpointI::operator<(r); +} + +void +IceInternal::UdpEndpointI::hashInit(Ice::Int& h) const +{ + IPEndpointI::hashInit(h); + hashAdd(h, _mcastInterface); + hashAdd(h, _mcastTtl); + hashAdd(h, _connect); + hashAdd(h, _compress); +} + +void +IceInternal::UdpEndpointI::fillEndpointInfo(IPEndpointInfo* info) const +{ + IPEndpointI::fillEndpointInfo(info); + UDPEndpointInfo* udpInfo = dynamic_cast(info); + if(udpInfo) + { + udpInfo->timeout = -1; + udpInfo->compress = _compress; + udpInfo->mcastTtl = _mcastTtl; + udpInfo->mcastInterface = _mcastInterface; + } +} + +bool +IceInternal::UdpEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + if(IPEndpointI::checkOption(option, argument, endpoint)) + { + return true; + } + + if(option == "-c") + { + if(!argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -c option in " + endpoint); + } + const_cast(_connect) = true; + } + else if(option == "-z") + { + if(!argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "unexpected argument `" + argument + + "' provided for -z option in " + endpoint); + } + const_cast(_compress) = true; + } + else if(option == "-v" || option == "-e") + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for " + option + + " option in endpoint " + endpoint); + } + try + { + Ice::Byte major, minor; + IceInternal::stringToMajorMinor(argument, major, minor); + if(major != 1 || minor != 0) + { + _instance->logger()->warning("deprecated udp endpoint option: " + option); + } + } + catch(const VersionParseException& ex) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid version `" + argument + "' in endpoint " + + endpoint + ":\n" + ex.str); + } + } + else if(option == "--interface") + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for --interface option in endpoint " + + endpoint); + } + const_cast(_mcastInterface) = argument; + } + else if(option == "--ttl") + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for --ttl option in endpoint " + + endpoint); + } + istringstream p(argument); + if(!(p >> const_cast(_mcastTtl)) || !p.eof()) + { + throw EndpointParseException(__FILE__, __LINE__, "invalid TTL value `" + argument + "' in endpoint " + + endpoint); + } + } + else + { + return false; + } + return true; +} + +ConnectorPtr +IceInternal::UdpEndpointI::createConnector(const Address& address, const NetworkProxyPtr&) const +{ + return new UdpConnector(_instance, address, _sourceAddr, _mcastInterface, _mcastTtl, _connectionId); +} + +IPEndpointIPtr +IceInternal::UdpEndpointI::createEndpoint(const string& host, int port, const string& connectionId) const +{ + return ICE_MAKE_SHARED(UdpEndpointI, _instance, host, port, _sourceAddr, _mcastInterface, _mcastTtl, _connect, + connectionId, _compress); +} + +IceInternal::UdpEndpointFactory::UdpEndpointFactory(const ProtocolInstancePtr& instance) : _instance(instance) +{ +} + +IceInternal::UdpEndpointFactory::~UdpEndpointFactory() +{ +} + +Short +IceInternal::UdpEndpointFactory::type() const +{ + return _instance->type(); +} + +string +IceInternal::UdpEndpointFactory::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceInternal::UdpEndpointFactory::create(vector& args, bool oaEndpoint) const +{ + IPEndpointIPtr endpt = ICE_MAKE_SHARED(UdpEndpointI, _instance); + endpt->initWithOptions(args, oaEndpoint); + return endpt; +} + +EndpointIPtr +IceInternal::UdpEndpointFactory::read(InputStream* s) const +{ + return ICE_MAKE_SHARED(UdpEndpointI, _instance, s); +} + +void +IceInternal::UdpEndpointFactory::destroy() +{ + _instance = 0; +} + +EndpointFactoryPtr +IceInternal::UdpEndpointFactory::clone(const ProtocolInstancePtr& instance) const +{ + return new UdpEndpointFactory(instance); +} diff --git a/Sources/IceCpp/UdpTransceiver.cpp b/Sources/IceCpp/UdpTransceiver.cpp new file mode 100644 index 0000000..966787f --- /dev/null +++ b/Sources/IceCpp/UdpTransceiver.cpp @@ -0,0 +1,806 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(UdpTransceiver* p) { return p; } + +NativeInfoPtr +IceInternal::UdpTransceiver::getNativeInfo() +{ + return this; +} + +#if defined(ICE_USE_IOCP) +AsyncInfo* +IceInternal::UdpTransceiver::getAsyncInfo(SocketOperation status) +{ + switch(status) + { + case SocketOperationRead: + return &_read; + case SocketOperationWrite: + return &_write; + default: + assert(false); + return 0; + } +} +#endif + +SocketOperation +IceInternal::UdpTransceiver::initialize(Buffer& /*readBuffer*/, Buffer& /*writeBuffer*/) +{ + if(_state == StateNeedConnect) + { + _state = StateConnectPending; + return SocketOperationConnect; + } + else if(_state <= StateConnectPending) + { +#if defined(ICE_USE_IOCP) + doFinishConnectAsync(_fd, _write); +#else + doFinishConnect(_fd); +#endif + _state = StateConnected; + } + + assert(_state >= StateConnected); + return SocketOperationNone; +} + +SocketOperation +IceInternal::UdpTransceiver::closing(bool, const Ice::LocalException&) +{ + // Nothing to do. + return SocketOperationNone; +} + +void +IceInternal::UdpTransceiver::close() +{ + assert(_fd != INVALID_SOCKET); + SOCKET fd = _fd; + _fd = INVALID_SOCKET; + closeSocket(fd); +} + +EndpointIPtr +IceInternal::UdpTransceiver::bind() +{ + if(isMulticast(_addr)) + { + setReuseAddress(_fd, true); + _mcastAddr = _addr; + +#ifdef _WIN32 + // + // Windows does not allow binding to the mcast address itself + // so we bind to INADDR_ANY (0.0.0.0) instead. As a result, + // bi-directional connection won't work because the source + // address won't be the multicast address and the client will + // therefore reject the datagram. + // + const_cast(_addr) = getAddressForServer("", _port, getProtocolSupport(_addr), false, false); +#endif + + const_cast(_addr) = doBind(_fd, _addr, _mcastInterface); + if(getPort(_mcastAddr) == 0) + { + setPort(_mcastAddr, getPort(_addr)); + } + setMcastGroup(_fd, _mcastAddr, _mcastInterface); + } + else + { +#ifndef _WIN32 + // + // Enable SO_REUSEADDR on Unix platforms to allow re-using + // the socket even if it's in the TIME_WAIT state. On + // Windows, this doesn't appear to be necessary and + // enabling SO_REUSEADDR would actually not be a good + // thing since it allows a second process to bind to an + // address even it's already bound by another process. + // + // TODO: using SO_EXCLUSIVEADDRUSE on Windows would + // probably be better but it's only supported by recent + // Windows versions (XP SP2, Windows Server 2003). + // + setReuseAddress(_fd, true); +#endif + const_cast(_addr) = doBind(_fd, _addr); + } + + _bound = true; + + _endpoint = _endpoint->endpoint(this); + return _endpoint; +} + +SocketOperation +IceInternal::UdpTransceiver::write(Buffer& buf) +{ + if(buf.i == buf.b.end()) + { + return SocketOperationNone; + } + assert(buf.i == buf.b.begin()); + assert(_fd != INVALID_SOCKET && _state >= StateConnected); + + // The caller is supposed to check the send size before by calling checkSendSize + assert(min(_maxPacketSize, _sndSize - _udpOverhead) >= static_cast(buf.b.size())); + +repeat: + + ssize_t ret; + if(_state == StateConnected) + { +#ifdef _WIN32 + ret = ::send(_fd, reinterpret_cast(&buf.b[0]), static_cast(buf.b.size()), 0); +#else + ret = ::send(_fd, reinterpret_cast(&buf.b[0]), buf.b.size(), 0); +#endif + } + else + { + socklen_t len = static_cast(sizeof(sockaddr_storage)); + if(_peerAddr.saStorage.ss_family == AF_INET) + { + len = static_cast(sizeof(sockaddr_in)); + } + else if(_peerAddr.saStorage.ss_family == AF_INET6) + { + len = static_cast(sizeof(sockaddr_in6)); + } + else + { + // No peer has sent a datagram yet. + throw SocketException(__FILE__, __LINE__, 0); + } + +#ifdef _WIN32 + ret = ::sendto(_fd, reinterpret_cast(&buf.b[0]), static_cast(buf.b.size()), 0, + &_peerAddr.sa, len); +#else + ret = ::sendto(_fd, reinterpret_cast(&buf.b[0]), buf.b.size(), 0, + &_peerAddr.sa, len); +#endif + } + + if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + goto repeat; + } + + if(wouldBlock()) + { + return SocketOperationWrite; + } + + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + + assert(ret == static_cast(buf.b.size())); + buf.i = buf.b.end(); + return SocketOperationNone; +} + +SocketOperation +IceInternal::UdpTransceiver::read(Buffer& buf) +{ + if(buf.i == buf.b.end()) + { + return SocketOperationNone; + } + assert(buf.i == buf.b.begin()); + assert(_fd != INVALID_SOCKET); + +#ifdef _WIN32 + int packetSize = min(_maxPacketSize, _rcvSize - _udpOverhead); +#else + const size_t packetSize = static_cast(min(_maxPacketSize, _rcvSize - _udpOverhead)); +#endif + buf.b.resize(packetSize); + buf.i = buf.b.begin(); + +repeat: + +#ifdef _WIN32 + int ret; +#else + ssize_t ret; +#endif + if(_state == StateConnected) + { + ret = ::recv(_fd, reinterpret_cast(&buf.b[0]), packetSize, 0); + } + else + { + assert(_incoming); + + Address peerAddr; + memset(&peerAddr.saStorage, 0, sizeof(sockaddr_storage)); + socklen_t len = static_cast(sizeof(sockaddr_storage)); + + ret = recvfrom(_fd, reinterpret_cast(&buf.b[0]), packetSize, 0, + &peerAddr.sa, &len); + + if(ret != SOCKET_ERROR) + { + _peerAddr = peerAddr; + } + } + + if(ret == SOCKET_ERROR) + { + if(recvTruncated()) + { + // The message was truncated and the whole buffer is filled. We ignore + // this error here, it will be detected at the connection level when + // the Ice message size is checked against the buffer size. + ret = static_cast(buf.b.size()); + } + else + { + if(interrupted()) + { + goto repeat; + } + + if(wouldBlock()) + { + return SocketOperationRead; + } + + if(connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } + + if(_state == StateNeedConnect) + { + // + // If we must connect, we connect to the first peer that sends us a packet. + // + assert(_incoming); // Client connections should always be connected at this point. + +#ifndef NDEBUG + bool connected = doConnect(_fd, _peerAddr, Address()); + assert(connected); +#else + doConnect(_fd, _peerAddr, Address()); +#endif + _state = StateConnected; + + if(_instance->traceLevel() >= 1) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "connected " << _instance->protocol() << " socket\n" << toString(); + } + } + + buf.b.resize(static_cast(ret)); + buf.i = buf.b.end(); + return SocketOperationNone; +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::UdpTransceiver::startWrite(Buffer& buf) +{ + assert(buf.i == buf.b.begin()); + + // The caller is supposed to check the send size before by calling checkSendSize + assert(min(_maxPacketSize, _sndSize - _udpOverhead) >= static_cast(buf.b.size())); + assert(_fd != INVALID_SOCKET); + + _write.buf.len = static_cast(buf.b.size()); + _write.buf.buf = reinterpret_cast(&*buf.i); + _write.error = ERROR_SUCCESS; + int err; + if(_state == StateConnected) + { + err = WSASend(_fd, &_write.buf, 1, &_write.count, 0, &_write, ICE_NULLPTR); + } + else + { + socklen_t len = static_cast(sizeof(sockaddr_storage)); + if(_peerAddr.saStorage.ss_family == AF_INET) + { + len = sizeof(sockaddr_in); + } + else if(_peerAddr.saStorage.ss_family == AF_INET6) + { + len = sizeof(sockaddr_in6); + } + else + { + // No peer has sent a datagram yet. + throw SocketException(__FILE__, __LINE__, 0); + } + err = WSASendTo(_fd, &_write.buf, 1, &_write.count, 0, &_peerAddr.sa, len, &_write, ICE_NULLPTR); + } + + if(err == SOCKET_ERROR) + { + if(!wouldBlock()) + { + if(connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } + return true; +} + +void +IceInternal::UdpTransceiver::finishWrite(Buffer& buf) +{ + if(_fd == INVALID_SOCKET || _state < StateConnected) + { + return; + } + + if(_write.error != ERROR_SUCCESS) + { + WSASetLastError(_write.error); + if(connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__ ,getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + + assert(static_cast(_write.count) == buf.b.size()); + buf.i = buf.b.end(); +} + +void +IceInternal::UdpTransceiver::startRead(Buffer& buf) +{ + const int packetSize = min(_maxPacketSize, _rcvSize - _udpOverhead); + buf.b.resize(packetSize); + buf.i = buf.b.begin(); + assert(!buf.b.empty() && buf.i != buf.b.end()); + _read.buf.len = packetSize; + _read.buf.buf = reinterpret_cast(&*buf.i); + _read.error = ERROR_SUCCESS; + int err; + if(_state == StateConnected) + { + err = WSARecv(_fd, &_read.buf, 1, &_read.count, &_read.flags, &_read, ICE_NULLPTR); + } + else + { + memset(&_readAddr.saStorage, 0, sizeof(struct sockaddr_storage)); + _readAddrLen = static_cast(sizeof(sockaddr_storage)); + + err = WSARecvFrom(_fd, &_read.buf, 1, &_read.count, &_read.flags, &_readAddr.sa, &_readAddrLen, &_read, + ICE_NULLPTR); + } + + if(err == SOCKET_ERROR) + { + if(recvTruncated()) + { + // Nothing to do. + } + else if(!wouldBlock()) + { + if(connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } +} + +void +IceInternal::UdpTransceiver::finishRead(Buffer& buf) +{ + if(_read.error != ERROR_SUCCESS) + { + WSASetLastError(_read.error); + + if(recvTruncated()) + { + // The message was truncated and the whole buffer is filled. We ignore + // this error here, it will be detected at the connection level when + // the Ice message size is checked against the buffer size. + _read.count = static_cast(buf.b.size()); + } + else + { + if(connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, getSocketErrno()); + } + } + } + + if(_state == StateNotConnected) + { + _peerAddr = _readAddr; + } + + int ret = _read.count; + + buf.b.resize(ret); + buf.i = buf.b.end(); +} +#endif + +string +IceInternal::UdpTransceiver::protocol() const +{ + return _instance->protocol(); +} + +string +IceInternal::UdpTransceiver::toString() const +{ + if(_fd == INVALID_SOCKET) + { + return ""; + } + + ostringstream s; + if(_incoming && !_bound) + { + s << "local address = " << addrToString(_addr); + } + else if(_state == StateNotConnected) + { + Address localAddr; + fdToLocalAddress(_fd, localAddr); + s << "local address = " << addrToString(localAddr); + if(isAddressValid(_peerAddr)) + { + s << "\nremote address = " << addrToString(_peerAddr); + } + } + else + { + s << fdToString(_fd); + } + + if(isAddressValid(_mcastAddr)) + { + s << "\nmulticast address = " + addrToString(_mcastAddr); + } + return s.str(); +} + +string +IceInternal::UdpTransceiver::toDetailedString() const +{ + ostringstream os; + os << toString(); + vector intfs; + if(isAddressValid(_mcastAddr)) + { + intfs = getInterfacesForMulticast(_mcastInterface, getProtocolSupport(_mcastAddr)); + } + else + { + intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true); + } + if(!intfs.empty()) + { + os << "\nlocal interfaces = "; + os << IceUtilInternal::joinString(intfs, ", "); + } + return os.str(); +} + +Ice::ConnectionInfoPtr +IceInternal::UdpTransceiver::getInfo() const +{ + Ice::UDPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::UDPConnectionInfo); + if(_fd == INVALID_SOCKET) + { + return info; + } + + if(_state == StateNotConnected) + { + Address localAddr; + fdToLocalAddress(_fd, localAddr); + addrToAddressAndPort(localAddr, info->localAddress, info->localPort); + if(isAddressValid(_peerAddr)) + { + addrToAddressAndPort(_peerAddr, info->remoteAddress, info->remotePort); + } + else + { + info->remotePort = 0; + } + } + else + { + fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort); + } + + info->rcvSize = _rcvSize; + info->sndSize = _sndSize; + + if(isAddressValid(_mcastAddr)) + { + addrToAddressAndPort(_mcastAddr, info->mcastAddress, info->mcastPort); + } + else + { + info->mcastPort = 0; + } + return info; +} + +void +IceInternal::UdpTransceiver::checkSendSize(const Buffer& buf) +{ + // + // The maximum packetSize is either the maximum allowable UDP packet size, or + // the UDP send buffer size (which ever is smaller). + // + const int packetSize = min(_maxPacketSize, _sndSize - _udpOverhead); + if(packetSize < static_cast(buf.b.size())) + { + throw DatagramLimitException(__FILE__, __LINE__); + } +} + +void +IceInternal::UdpTransceiver::setBufferSize(int rcvSize, int sndSize) +{ + setBufSize(rcvSize, sndSize); +} + +int +IceInternal::UdpTransceiver::effectivePort() const +{ + return getPort(_addr); +} + +IceInternal::UdpTransceiver::UdpTransceiver(const ProtocolInstancePtr& instance, + const Address& addr, + const Address& sourceAddr, + const string& mcastInterface, + int mcastTtl) : + _instance(instance), + _incoming(false), + _bound(false), + _addr(addr), + _state(StateNeedConnect) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), + _write(SocketOperationWrite) +#endif +{ + _fd = createSocket(true, _addr); + setBufSize(-1, -1); + setBlock(_fd, false); + + _mcastAddr.saStorage.ss_family = AF_UNSPEC; + _peerAddr.saStorage.ss_family = AF_UNSPEC; // Not initialized yet. + + // + // NOTE: setting the multicast interface before performing the + // connect is important for some OS such as macOS. + // + if(isMulticast(_addr)) + { + if(mcastInterface.length() > 0) + { + setMcastInterface(_fd, mcastInterface, _addr); + } + if(mcastTtl != -1) + { + setMcastTtl(_fd, mcastTtl, _addr); + } + } + + // + // In general, connecting a datagram socket should be non-blocking as this just setups + // the default destination address for the socket. However, on some OS, connect sometime + // returns EWOULDBLOCK. If that's the case, we keep the state as StateNeedConnect. This + // will make sure the transceiver is notified when the socket is ready for sending (see + // the initialize() implementation). + // + if(doConnect(_fd, _addr, sourceAddr)) + { + _state = StateConnected; + } + +#ifdef ICE_USE_IOCP + // + // On Windows when using IOCP, we must make sure that the socket is connected without + // blocking as there's no way to do a non-blocking datagram socket conection (ConnectEx + // only supports connection oriented sockets). According to Microsoft documentation of + // the connect() call, this should always be the case. + // + assert(_state == StateConnected); +#endif +} + +IceInternal::UdpTransceiver::UdpTransceiver(const UdpEndpointIPtr& endpoint, const ProtocolInstancePtr& instance, + const string& host, int port, const string& mcastInterface, bool connect) : + _endpoint(endpoint), + _instance(instance), + _incoming(true), + _bound(false), + _addr(getAddressForServer(host, port, instance->protocolSupport(), instance->preferIPv6(), true)), + _mcastInterface(mcastInterface), + _port(port), + _state(connect ? StateNeedConnect : StateNotConnected) +#if defined(ICE_USE_IOCP) + , _read(SocketOperationRead), + _write(SocketOperationWrite) +#endif +{ + _fd = createServerSocket(true, _addr, instance->protocolSupport()); + setBufSize(-1, -1); + setBlock(_fd, false); + + memset(&_mcastAddr.saStorage, 0, sizeof(sockaddr_storage)); + memset(&_peerAddr.saStorage, 0, sizeof(sockaddr_storage)); + _peerAddr.saStorage.ss_family = AF_UNSPEC; + _mcastAddr.saStorage.ss_family = AF_UNSPEC; +} + +IceInternal::UdpTransceiver::~UdpTransceiver() +{ + assert(_fd == INVALID_SOCKET); +} + +// +// Set UDP receive and send buffer sizes. +// +void +IceInternal::UdpTransceiver::setBufSize(int rcvSize, int sndSize) +{ + assert(_fd != INVALID_SOCKET); + + for(int i = 0; i < 2; ++i) + { + bool isSnd; + string direction; + string prop; + int* addr; + int dfltSize; + int sizeRequested; + if(i == 0) + { + isSnd = false; + direction = "receive"; + prop = "Ice.UDP.RcvSize"; + addr = &_rcvSize; + dfltSize = getRecvBufferSize(_fd); + sizeRequested = rcvSize; + } + else + { + isSnd = true; + direction = "send"; + prop = "Ice.UDP.SndSize"; + addr = &_sndSize; + dfltSize = getSendBufferSize(_fd); + sizeRequested = sndSize; + } + + if(dfltSize <= 0) + { + dfltSize = _maxPacketSize; + } + *addr = dfltSize; + + // + // Get property for buffer size if size not passed in. + // + if(sizeRequested == -1) + { + sizeRequested = _instance->properties()->getPropertyAsIntWithDefault(prop, dfltSize); + } + // + // Check for sanity. + // + if(sizeRequested < (_udpOverhead + headerSize)) + { + Warning out(_instance->logger()); + out << "Invalid " << prop << " value of " << sizeRequested << " adjusted to " << dfltSize; + sizeRequested = dfltSize; + } + + if(sizeRequested != dfltSize) + { + // + // Try to set the buffer size. The kernel will silently adjust + // the size to an acceptable value. Then read the size back to + // get the size that was actually set. + // + if(i == 0) + { + setRecvBufferSize(_fd, sizeRequested); + *addr = getRecvBufferSize(_fd); + } + else + { + setSendBufferSize(_fd, sizeRequested); + *addr = getSendBufferSize(_fd); + } + + // + // Warn if the size that was set is less than the requested size and + // we have not already warned. + // + if(*addr == 0) // set buffer size not supported. + { + *addr = sizeRequested; + } + else if(*addr < sizeRequested) + { + BufSizeWarnInfo winfo = _instance->getBufSizeWarn(UDPEndpointType); + if((isSnd && (!winfo.sndWarn || winfo.sndSize != sizeRequested)) || + (!isSnd && (!winfo.rcvWarn || winfo.rcvSize != sizeRequested))) + { + Warning out(_instance->logger()); + out << "UDP " << direction << " buffer size: requested size of " + << sizeRequested << " adjusted to " << *addr; + + if(isSnd) + { + _instance->setSndBufSizeWarn(UDPEndpointType, sizeRequested); + } + else + { + _instance->setRcvBufSizeWarn(UDPEndpointType, sizeRequested); + } + } + } + } + } +} + +// +// The maximum IP datagram size is 65535. Subtract 20 bytes for the IP header and 8 bytes for the UDP header +// to get the maximum payload. +// +const int IceInternal::UdpTransceiver::_udpOverhead = 20 + 8; +const int IceInternal::UdpTransceiver::_maxPacketSize = 65535 - _udpOverhead; diff --git a/Sources/IceCpp/Unicode.cpp b/Sources/IceCpp/Unicode.cpp new file mode 100644 index 0000000..2261eb4 --- /dev/null +++ b/Sources/IceCpp/Unicode.cpp @@ -0,0 +1,183 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#ifndef ICE_HAS_CODECVT_UTF8 +// +// It's better to exclude the file from the build, but it's not always +// easy to do. +// + +#include +#include + +#include + +using namespace std; +using namespace IceUtil; +using namespace IceUtilInternal; + +namespace +{ +// +// Helper class, base never defined +// Usage: WstringHelper::toUTF8 and fromUTF8. +// +template struct WstringHelper; + +template<> +struct WstringHelper<2> +{ + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) + { + return ConvertUTF16toUTF8( + reinterpret_cast(&sourceStart), + reinterpret_cast(sourceEnd), + &targetStart, targetEnd, lenientConversion); + } + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd) + { + return ConvertUTF8toUTF16( + &sourceStart, sourceEnd, + reinterpret_cast(&targetStart), + reinterpret_cast(targetEnd), lenientConversion); + } +}; + +template<> +struct WstringHelper<4> +{ + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) + { + return ConvertUTF32toUTF8( + reinterpret_cast(&sourceStart), + reinterpret_cast(sourceEnd), + &targetStart, targetEnd, lenientConversion); + } + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd) + { + return ConvertUTF8toUTF32( + &sourceStart, sourceEnd, + reinterpret_cast(&targetStart), + reinterpret_cast(targetEnd), lenientConversion); + } +}; + +void checkResult(ConversionResult result) +{ + switch (result) + { + case conversionOK: + break; + case sourceExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source exhausted"); + case sourceIllegal: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source illegal"); + case targetExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source illegal"); + default: + { + assert(0); + throw IceUtil::IllegalConversionException(__FILE__, __LINE__); + } + } +} +} + +// +// convertXXX functions +// + +bool +IceUtilInternal::convertUTFWstringToUTF8(const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) +{ + ConversionResult result = WstringHelper::toUTF8( + sourceStart, sourceEnd, targetStart, targetEnd); + + if(result == targetExhausted) + { + return false; + } + else + { + checkResult(result); + return true; + } +} + +void +IceUtilInternal::convertUTF8ToUTFWstring(const Byte*& sourceStart, const Byte* sourceEnd, std::wstring& target) +{ + size_t sourceSize = static_cast(sourceEnd - sourceStart); + + target.resize(sourceSize); + wchar_t* targetStart = const_cast(target.data()); + wchar_t* targetEnd = targetStart + sourceSize; + + ConversionResult result = WstringHelper::fromUTF8(sourceStart, sourceEnd, + targetStart, targetEnd); + + checkResult(result); + target.resize(targetStart - target.data()); +} + +void +IceUtilInternal::convertUTF8ToUTF16(const vector& source, vector& target) +{ + target.resize(source.size()); + const unsigned char* sourceStart = &source[0]; + const unsigned char* sourceEnd = &source[0] + source.size(); + + unsigned short* targetStart = &target[0]; + unsigned short* targetEnd = &target[0] + target.size(); + ConversionResult result = ConvertUTF8toUTF16(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + + checkResult(result); + target.resize(targetStart - &target[0]); +} + +void +IceUtilInternal::convertUTF8ToUTF32(const vector& source, vector& target) +{ + target.resize(source.size()); + const unsigned char* sourceStart = &source[0]; + const unsigned char* sourceEnd = &source[0] + source.size(); + + unsigned int* targetStart = &target[0]; + unsigned int* targetEnd = &target[0] + target.size(); + ConversionResult result = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + + checkResult(result); + target.resize(targetStart - &target[0]); +} + +void +IceUtilInternal::convertUTF32ToUTF8(const vector& source, vector& target) +{ + target.resize(source.size() * 4); + + const unsigned int* sourceStart = &source[0]; + const unsigned int* sourceEnd = &source[0] + source.size(); + + unsigned char* targetStart = &target[0]; + unsigned char* targetEnd = &target[0] + target.size(); + ConversionResult result = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + + checkResult(result); + target.resize(targetStart - &target[0]); +} + +#endif diff --git a/Sources/IceCpp/UtilException.cpp b/Sources/IceCpp/UtilException.cpp new file mode 100644 index 0000000..c8c2ba0 --- /dev/null +++ b/Sources/IceCpp/UtilException.cpp @@ -0,0 +1,839 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#if defined(_MSC_VER) && _MSC_VER >= 1700 +// +// DbgHelp.dll on Windows XP does not contain Unicode functions, so we +// "switch on" Unicode only with VS2012 and up +// +# ifndef UNICODE +# define UNICODE +# endif +# ifndef _UNICODE +# define _UNICODE +# endif +#endif + +// +// For UINTPTR_MAX on Ubuntu Precise +// +#ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +# if defined(ICE_LIBBACKTRACE) +# include +# include +# if BACKTRACE_SUPPORTED && BACKTRACE_SUPPORTS_THREADS +# include +# include +# else + // It's available but we cant' use it - shouldn't happen +# undef ICE_LIBBACKTRACE +# endif +# endif + +# if !defined(_AIX) && !defined(__sun) && !defined(__FreeBSD__) && !defined(__MINGW32__) && !defined(ICE_STATIC_LIBS) +# include +# include +# include +# define ICE_BACKTRACE +# endif +#endif + +// +// The Slice compilers don't retrieve the exception stack traces so we don't need the DbgHelp calls. +// +#if defined(_WIN32) && !defined(__MINGW32__) && !defined(ICE_BUILDING_SLICE_COMPILERS) +# define ICE_DBGHELP +# if defined(_MSC_VER) && (_MSC_VER >= 1700) +# define DBGHELP_TRANSLATE_TCHAR +# include +# if _MSC_VER >= 1900 +# pragma warning(disable:4091) // VS 2015 RC issues this warning for code in DbgHelp.h +# endif +# endif +# include +# include +#endif + +using namespace std; + +namespace IceUtilInternal +{ + +#ifdef NDEBUG +bool ICE_API printStackTraces = false; +#else +bool ICE_API printStackTraces = true; +#endif + +bool ICE_API nullHandleAbort = false; + +StackTraceImpl +stackTraceImpl() +{ +#if defined(ICE_DBGHELP) + return STDbghelp; +#elif defined(ICE_LIBBACKTRACE) +# if defined(ICE_BACKTRACE) + return STLibbacktracePlus; +# else + return STLibbacktrace; +# endif +#elif defined(ICE_BACKTRACE) + return STBacktrace; +#else + return STNone; +#endif +} +} + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; + +#ifdef ICE_DBGHELP +HANDLE process = 0; +#endif + +#ifdef ICE_LIBBACKTRACE +backtrace_state* bstate = 0; + +void +ignoreErrorCallback(void*, const char* /*msg*/, int /*errnum*/) +{ + // cerr << "Error callback: " << msg << ", errnum = " << errnum << endl; +} + +int +ignoreFrame(void*, ICE_MAYBE_UNUSED uintptr_t pc, const char*, int, const char*) +{ + assert(pc == 0); + return 0; +} + +#endif + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; +#ifdef ICE_LIBBACKTRACE + // Leaked, as libbacktrace does not provide an API to free this state. + // + bstate = backtrace_create_state(0, 1, ignoreErrorCallback, 0); + + // The first call to backtrace_pcinfo does not initialize bstate->fileline_fn + // in a thread-safe manner, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81098. + // So we make a "dummy" call to backtrace_pcinfo to initialize it here. + // + backtrace_pcinfo(bstate, 0, ignoreFrame, ignoreErrorCallback, 0); +#endif + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; +#ifdef ICE_DBGHELP + if(process != 0) + { + SymCleanup(process); + process = 0; + } +#endif + } +}; + +Init init; + +#if defined(ICE_LIBBACKTRACE) || defined (ICE_BACKTRACE) + +struct FrameInfo +{ + FrameInfo(int i, uintptr_t p) : + index(i), + pc(p), + fallback(0), + setByErrorCb(false) + { + } + + int index; + uintptr_t pc; + const char* fallback; + bool setByErrorCb; + string output; +}; + +void +decode(const string& line, string& function, string& filename) +{ + string::size_type openParen = line.find_first_of('('); + if(openParen != string::npos) + { + // + // Format: "/opt/Ice/lib/libIceUtil.so.33(_ZN7IceUtil9ExceptionC2EPKci+0x51) [0x73b267]" + // + string::size_type closeParen = line.find_first_of(')', openParen); + if(closeParen != string::npos) + { + string tmp = line.substr(openParen + 1, closeParen - openParen - 1); + string::size_type plus = tmp.find_last_of('+'); + if(plus != string::npos) + { + function = tmp.substr(0 , plus); + filename = line.substr(0, openParen); + } + } + } + else + { + // + // Format: "1 libIce.3.3.1.dylib 0x000933a1 _ZN7IceUtil9ExceptionC2EPKci + 71" + // + string::size_type plus = line.find_last_of('+'); + if(plus != string::npos) + { + string tmp = line.substr(0, plus - 1); + string::size_type space = tmp.find_last_of(" \t"); + if(space != string::npos) + { + tmp = tmp.substr(space + 1, tmp.size() - space); + + string::size_type start = line.find_first_not_of(" \t", 3); + if(start != string::npos) + { + string::size_type finish = line.find_first_of(" \t", start); + if(finish != string::npos) + { + function = tmp; + filename = line.substr(start, finish - start); + } + } + } + } + } +} + +int +printFrame(void* data, uintptr_t pc, const char* filename, int lineno, const char* function) +{ + FrameInfo& frameInfo = *reinterpret_cast(data); + + ostringstream os; + os << setw(3) << frameInfo.index << " "; + + string functionHolder, filenameHolder; + + if(!function && frameInfo.fallback) + { + // Extract function and filename from fallback + decode(frameInfo.fallback, functionHolder, filenameHolder); + if(!functionHolder.empty()) + { + function = functionHolder.c_str(); + } + if(!filename && !filenameHolder.empty()) + { + filename = filenameHolder.c_str(); + } + } + + int ret = 0; + + if(function) + { + char* demangledFunction = abi::__cxa_demangle(function, 0, 0, 0); + if(demangledFunction) + { + os << demangledFunction; + free(demangledFunction); + } + else + { + os << function; + } + + if(filename && lineno > 0) + { + os << " at " << filename << ":" << lineno; + } + else if(filename) + { + os << " in " << filename; + } + } + else if(frameInfo.fallback) + { + // decode was not able to parse this string + os << frameInfo.fallback; + ret = 1; + } + else + { + os << hex << setw(sizeof(uintptr_t) * 2) << setfill('0') << pc; + ret = 2; + } + os << "\n"; + frameInfo.output = os.str(); + return ret; +} +#endif + +#ifdef ICE_LIBBACKTRACE + +void +handlePcInfoError(void* data, const char* /*msg*/, int /*errnum*/) +{ + FrameInfo& frameInfo = *reinterpret_cast(data); + printFrame(&frameInfo, frameInfo.pc, 0, 0, 0); + frameInfo.setByErrorCb = true; +} + +int +addFrame(void* sf, uintptr_t pc) +{ + if(pc != UINTPTR_MAX) + { + vector* stackFrames = reinterpret_cast*>(sf); + stackFrames->push_back(reinterpret_cast(pc)); + return 0; + } + else + { + return 1; + } +} +#endif + +vector +getStackFrames() +{ + vector stackFrames; + + if(!IceUtilInternal::printStackTraces) + { + return stackFrames; + } + +#if defined(ICE_DBGHELP) + + stackFrames.resize(61); + // + // 1: skip the first frame (the call to getStackFrames) + // 1 + stackSize < 63 on Windows XP according to the documentation for CaptureStackBackTrace + // + USHORT frameCount = CaptureStackBackTrace(1, static_cast(stackFrames.size()), &stackFrames.front(), 0); + + stackFrames.resize(frameCount); + +#elif defined(ICE_LIBBACKTRACE) + + backtrace_simple(bstate, 1, addFrame, ignoreErrorCallback, &stackFrames); + +#elif defined(ICE_BACKTRACE) + + stackFrames.resize(100); + int stackDepth = backtrace(&stackFrames.front(), static_cast(stackFrames.size())); + stackFrames.resize(static_cast(stackDepth)); + if(!stackFrames.empty()) + { + stackFrames.erase(stackFrames.begin()); // drop the first frame + } +#endif + + return stackFrames; +} + +string +getStackTrace(const vector& stackFrames) +{ + if(stackFrames.empty()) + { + return ""; + } + + string stackTrace; + +#if defined(ICE_DBGHELP) + + // + // Note: the Sym functions are not thread-safe + // + IceUtilInternal::MutexPtrLock lock(globalMutex); + bool refreshModuleList = process != 0; + if(process == 0) + { + process = GetCurrentProcess(); + + SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS | SYMOPT_UNDNAME); + if(SymInitialize(process, 0, TRUE) == 0) + { + process = 0; + return "No stack trace: SymInitialize failed with " + IceUtilInternal::errorToString(GetLastError()); + } + } + lock.release(); + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# if defined(DBGHELP_TRANSLATE_TCHAR) + static_assert(sizeof(TCHAR) == sizeof(wchar_t), "Bad TCHAR - should be wchar_t"); +# else + static_assert(sizeof(TCHAR) == sizeof(char), "Bad TCHAR - should be char"); +# endif +#endif + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + + SYMBOL_INFO* symbol = reinterpret_cast(buffer); + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + + IMAGEHLP_LINE64 line = {}; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + DWORD displacement = 0; + + lock.acquire(); + + if(refreshModuleList && SymRefreshModuleList(process) == 0) + { + return "No stack trace: SymRefreshModuleList failed with " + IceUtilInternal::errorToString(GetLastError()); + } +#ifdef DBGHELP_TRANSLATE_TCHAR + const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); +#endif + for(size_t i = 0; i < stackFrames.size(); i++) + { + ostringstream s; + s << setw(3) << i << " "; + + DWORD64 address = reinterpret_cast(stackFrames[i]); + + BOOL ok = SymFromAddr(process, address, 0, symbol); + if(ok) + { +#ifdef DBGHELP_TRANSLATE_TCHAR + s << wstringToString(symbol->Name, converter); +#else + s << symbol->Name; +#endif + ok = SymGetLineFromAddr64(process, address, &displacement, &line); + if(ok) + { + s << " at " +#ifdef DBGHELP_TRANSLATE_TCHAR + << wstringToString(line.FileName, converter) +#else + << line.FileName +#endif + << ":" << line.LineNumber; + } + } + else + { + s << hex << setw(sizeof(DWORD64) * 2) << setfill('0') << address; + } + s << "\n"; + stackTrace += s.str(); + } + lock.release(); + +#elif defined(ICE_LIBBACKTRACE) || defined (ICE_BACKTRACE) + + vector::const_iterator p = stackFrames.begin(); + int frameIndex = 0; + int offset = 0; + char** backtraceStrings = 0; + +# if defined(ICE_LIBBACKTRACE) && defined(ICE_BACKTRACE) + bool backtraceStringsInitialized = false; +# endif +# if !defined(ICE_LIBBACKTRACE) + // Initialize backtraceStrings immediately + if(p != stackFrames.end()) + { + backtraceStrings = backtrace_symbols(&*p, static_cast(stackFrames.size())); + } +# endif + + do + { + FrameInfo frameInfo(frameIndex, reinterpret_cast(*p)); + bool retry = false; + + if(backtraceStrings) + { + frameInfo.fallback = backtraceStrings[frameIndex - offset]; + } + +# if defined(ICE_LIBBACKTRACE) + bool ok = backtrace_pcinfo(bstate, frameInfo.pc, printFrame, handlePcInfoError, &frameInfo) == 0; + + // When error callback is called, pcinfo returns 0 + if(!ok || frameInfo.setByErrorCb) + { +# if defined(ICE_BACKTRACE) + if(!backtraceStringsInitialized) + { + offset = frameIndex; + // Initialize backtraceStrings as fallback + backtraceStrings = backtrace_symbols(&*p, stackFrames.size() - offset); + backtraceStringsInitialized = true; + retry = true; + } +# endif + } +# else // not using libbacktrace: + printFrame(&frameInfo, frameInfo.pc, 0, 0, 0); +# endif + if(!retry) + { + stackTrace += frameInfo.output; + ++p; + ++frameIndex; + } + } while(p != stackFrames.end()); + + if(backtraceStrings) + { + free(backtraceStrings); + } + +#endif + return stackTrace; +} +} + +IceUtil::Exception::Exception() : + _file(0), + _line(0), + _stackFrames(getStackFrames()) +{ +} + +IceUtil::Exception::Exception(const char* file, int line) : + _file(file), + _line(line), + _stackFrames(getStackFrames()) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtil::Exception::~Exception() throw() +{ +} +#endif + +void +IceUtil::Exception::ice_print(ostream& out) const +{ + if(_file && _line > 0) + { + out << _file << ':' << _line << ": "; + } + out << ice_id(); +} + +const char* +IceUtil::Exception::what() const ICE_NOEXCEPT +{ + try + { + IceUtilInternal::MutexPtrLock lock(globalMutex); + { + if(_str.empty()) + { + stringstream s; + ice_print(s); + _str = s.str(); // Lazy initialization. + } + } + return _str.c_str(); + } + catch(...) + { + } + return ""; +} + +#ifndef ICE_CPP11_MAPPING +string +IceUtil::Exception::ice_name() const +{ + return ice_id().substr(2); +} +#endif + +const char* +IceUtil::Exception::ice_file() const +{ + return _file; +} + +int +IceUtil::Exception::ice_line() const +{ + return _line; +} + +string +IceUtil::Exception::ice_stackTrace() const +{ + return getStackTrace(_stackFrames); +} + +#ifdef ICE_CPP11_MAPPING +unique_ptr +IceUtil::Exception::ice_clone() const +{ + return unique_ptr(ice_cloneImpl()); +} +#endif + +ostream& +IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex) +{ + ex.ice_print(out); + return out; +} + +IceUtil::NullHandleException::NullHandleException(const char* file, int line) : + ExceptionHelper(file, line) +{ + if(IceUtilInternal::nullHandleAbort) + { + abort(); + } +} + +string +IceUtil::NullHandleException::ice_id() const +{ + return "::IceUtil::NullHandleException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::NullHandleException* +IceUtil::NullHandleException::ice_clone() const +{ + return new NullHandleException(*this); +} +#endif + +IceUtil::IllegalArgumentException::IllegalArgumentException(const char* file, int line) : + ExceptionHelper(file, line) +{ +} + +IceUtil::IllegalArgumentException::IllegalArgumentException(const char* file, int line, const string& r) : + ExceptionHelper(file, line), + _reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtil::IllegalArgumentException::~IllegalArgumentException() throw() +{ +} +#endif + +void +IceUtil::IllegalArgumentException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ": " << _reason; +} + +string +IceUtil::IllegalArgumentException::ice_id() const +{ + return "::IceUtil::IllegalArgumentException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::IllegalArgumentException* +IceUtil::IllegalArgumentException::ice_clone() const +{ + return new IllegalArgumentException(*this); +} +#endif + +string +IceUtil::IllegalArgumentException::reason() const +{ + return _reason; +} + +// +// IllegalConversionException +// +IceUtil::IllegalConversionException::IllegalConversionException(const char* file, int line): + ExceptionHelper(file, line) +{ +} + +IceUtil::IllegalConversionException::IllegalConversionException(const char* file, int line, + const string& reason): + ExceptionHelper(file, line), + _reason(reason) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtil::IllegalConversionException::~IllegalConversionException() throw() +{ +} +#endif + +void +IceUtil::IllegalConversionException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ": " << _reason; + +} + +string +IceUtil::IllegalConversionException::ice_id() const +{ + return "::IceUtil::IllegalConversionException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::IllegalConversionException* +IceUtil::IllegalConversionException::ice_clone() const +{ + return new IllegalConversionException(*this); +} +#endif + +string +IceUtil::IllegalConversionException::reason() const +{ + return _reason; +} + +IceUtil::SyscallException::SyscallException(const char* file, int line, int err ): + ExceptionHelper(file, line), + _error(err) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtil::SyscallException::~SyscallException() throw() +{ +} +#endif + +void +IceUtil::SyscallException::ice_print(ostream& os) const +{ + Exception::ice_print(os); + if(_error != 0) + { + os << ":\nsyscall exception: " << IceUtilInternal::errorToString(_error); + } +} + +string +IceUtil::SyscallException::ice_id() const +{ + return "::IceUtil::SyscallException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::SyscallException* +IceUtil::SyscallException::ice_clone() const +{ + return new SyscallException(*this); +} +#endif + +int +IceUtil::SyscallException::error() const +{ + return _error; +} + +IceUtil::FileLockException::FileLockException(const char* file, int line, int err, const string& path): + ExceptionHelper(file, line), + _error(err), + _path(path) +{ +} + +#ifndef ICE_CPP11_COMPILER +IceUtil::FileLockException::~FileLockException() throw() +{ +} +#endif + +void +IceUtil::FileLockException::ice_print(ostream& os) const +{ + Exception::ice_print(os); + os << ":\ncould not lock file: `" << _path << "'"; + if(_error != 0) + { + os << "\nsyscall exception: " << IceUtilInternal::errorToString(_error); + } +} + +string +IceUtil::FileLockException::ice_id() const +{ + return "::IceUtil::FileLockException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::FileLockException* +IceUtil::FileLockException::ice_clone() const +{ + return new FileLockException(*this); +} +#endif + +int +IceUtil::FileLockException::error() const +{ + return _error; +} + +IceUtil::OptionalNotSetException::OptionalNotSetException(const char* file, int line) : + ExceptionHelper(file, line) +{ + if(IceUtilInternal::nullHandleAbort) + { + abort(); + } +} + +string +IceUtil::OptionalNotSetException::ice_id() const +{ + return "::IceUtil::OptionalNotSetException"; +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::OptionalNotSetException* +IceUtil::OptionalNotSetException::ice_clone() const +{ + return new OptionalNotSetException(*this); +} +#endif diff --git a/Sources/IceCpp/Value.cpp b/Sources/IceCpp/Value.cpp new file mode 100644 index 0000000..28c9be9 --- /dev/null +++ b/Sources/IceCpp/Value.cpp @@ -0,0 +1,76 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +void +Ice::Value::ice_preMarshal() +{ +} + +void +Ice::Value::ice_postUnmarshal() +{ +} + +void +Ice::Value::_iceWrite(Ice::OutputStream* os) const +{ + os->startValue(0); + _iceWriteImpl(os); + os->endValue(); +} + +void +Ice::Value::_iceRead(Ice::InputStream* is) +{ + is->startValue(); + _iceReadImpl(is); + is->endValue(false); +} + +namespace +{ + +const string object_ids[] = +{ + "::Ice::Object" +}; + +} + +string +Ice::Value::ice_id() const +{ + return object_ids[0]; +} + +const string& +Ice::Value::ice_staticId() +{ + return object_ids[0]; +} + +shared_ptr +Ice::Value::ice_clone() const +{ + return _iceCloneImpl(); +} + +shared_ptr +Ice::Value::ice_getSlicedData() const +{ + return nullptr; +} + +#endif diff --git a/Sources/IceCpp/ValueFactory.cpp b/Sources/IceCpp/ValueFactory.cpp new file mode 100644 index 0000000..da6d351 --- /dev/null +++ b/Sources/IceCpp/ValueFactory.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ValueFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +Ice::ValueFactoryManager::~ValueFactoryManager() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +Ice::ValueFactory::~ValueFactory() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ValueFactory* p) { return p; } +/// \endcond + +Ice::ValueFactoryManager::~ValueFactoryManager() +{ +} + +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* Ice::upCast(ValueFactoryManager* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/ValueFactoryManagerI.cpp b/Sources/IceCpp/ValueFactoryManagerI.cpp new file mode 100644 index 0000000..94e3036 --- /dev/null +++ b/Sources/IceCpp/ValueFactoryManagerI.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +void +IceInternal::ValueFactoryManagerI::add(ICE_IN(ICE_DELEGATE(ValueFactory)) factory, const string& id) +{ + IceUtil::Mutex::Lock sync(*this); + + if((_factoryMapHint != _factoryMap.end() && _factoryMapHint->first == id) + || _factoryMap.find(id) != _factoryMap.end()) + { + throw AlreadyRegisteredException(__FILE__, __LINE__, "value factory", id); + } + + _factoryMapHint = _factoryMap.insert(_factoryMapHint, pair(id, factory)); +} + +ICE_DELEGATE(ValueFactory) +IceInternal::ValueFactoryManagerI::find(const string& id) const ICE_NOEXCEPT +{ + IceUtil::Mutex::Lock sync(*this); + + FactoryMap& factoryMap = const_cast(_factoryMap); + + FactoryMap::iterator p = factoryMap.end(); + if(_factoryMapHint != factoryMap.end()) + { + if(_factoryMapHint->first == id) + { + p = _factoryMapHint; + } + } + + if(p == factoryMap.end()) + { + p = factoryMap.find(id); + } + + if(p != factoryMap.end()) + { + _factoryMapHint = p; + return p->second; + } + else + { + return ICE_NULLPTR; + } +} + +IceInternal::ValueFactoryManagerI::ValueFactoryManagerI() : + _factoryMapHint(_factoryMap.end()) +{ +} diff --git a/Sources/IceCpp/Version.cpp b/Sources/IceCpp/Version.cpp new file mode 100644 index 0000000..58a4366 --- /dev/null +++ b/Sources/IceCpp/Version.cpp @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Version.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICE_API_EXPORTS +# define ICE_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ +} + +#else // C++98 mapping + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceCpp/WSAcceptor.cpp b/Sources/IceCpp/WSAcceptor.cpp new file mode 100644 index 0000000..ce017d2 --- /dev/null +++ b/Sources/IceCpp/WSAcceptor.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceInternal::NativeInfoPtr +IceInternal::WSAcceptor::getNativeInfo() +{ + return _delegate->getNativeInfo(); +} + +#if defined(ICE_USE_IOCP) +IceInternal::AsyncInfo* +IceInternal::WSAcceptor::getAsyncInfo(IceInternal::SocketOperation status) +{ + return _delegate->getNativeInfo()->getAsyncInfo(status); +} +#endif + +void +IceInternal::WSAcceptor::close() +{ + _delegate->close(); +} + +EndpointIPtr +IceInternal::WSAcceptor::listen() +{ + _endpoint = _endpoint->endpoint(_delegate->listen()); + return _endpoint; +} + +#if defined(ICE_USE_IOCP) +void +IceInternal::WSAcceptor::startAccept() +{ + _delegate->startAccept(); +} + +void +IceInternal::WSAcceptor::finishAccept() +{ + _delegate->finishAccept(); +} +#endif + +IceInternal::TransceiverPtr +IceInternal::WSAcceptor::accept() +{ + // + // WebSocket handshaking is performed in TransceiverI::initialize, since + // accept must not block. + // + return new WSTransceiver(_instance, _delegate->accept()); +} + +string +IceInternal::WSAcceptor::protocol() const +{ + return _delegate->protocol(); +} + +string +IceInternal::WSAcceptor::toString() const +{ + return _delegate->toString(); +} + +string +IceInternal::WSAcceptor::toDetailedString() const +{ + return _delegate->toDetailedString(); +} + +IceInternal::WSAcceptor::WSAcceptor(const WSEndpointPtr& endpoint, const ProtocolInstancePtr& instance, + const AcceptorPtr& del) : + _endpoint(endpoint), + _instance(instance), + _delegate(del) +{ +} + +IceInternal::WSAcceptor::~WSAcceptor() +{ +} diff --git a/Sources/IceCpp/WSConnector.cpp b/Sources/IceCpp/WSConnector.cpp new file mode 100644 index 0000000..f193583 --- /dev/null +++ b/Sources/IceCpp/WSConnector.cpp @@ -0,0 +1,102 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +TransceiverPtr +IceInternal::WSConnector::connect() +{ + return new WSTransceiver(_instance, _delegate->connect(), _host, _resource); +} + +Short +IceInternal::WSConnector::type() const +{ + return _delegate->type(); +} + +string +IceInternal::WSConnector::toString() const +{ + return _delegate->toString(); +} + +bool +IceInternal::WSConnector::operator==(const Connector& r) const +{ + const WSConnector* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_delegate != p->_delegate) + { + return false; + } + + if(_resource != p->_resource) + { + return false; + } + + return true; +} + +bool +IceInternal::WSConnector::operator<(const Connector& r) const +{ + const WSConnector* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(this == p) + { + return false; + } + + if(_delegate < p->_delegate) + { + return true; + } + else if(p->_delegate < _delegate) + { + return false; + } + + if(_resource < p->_resource) + { + return true; + } + else if(p->_resource < _resource) + { + return false; + } + + return false; +} + +IceInternal::WSConnector::WSConnector(const ProtocolInstancePtr& instance, const ConnectorPtr& del, const string& host, + const string& resource) : + _instance(instance), _delegate(del), _host(host), _resource(resource) +{ +} + +IceInternal::WSConnector::~WSConnector() +{ +} diff --git a/Sources/IceCpp/WSEndpoint.cpp b/Sources/IceCpp/WSEndpoint.cpp new file mode 100644 index 0000000..ac6742b --- /dev/null +++ b/Sources/IceCpp/WSEndpoint.cpp @@ -0,0 +1,508 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +class WSEndpointFactoryPlugin : public Plugin +{ +public: + + WSEndpointFactoryPlugin(const CommunicatorPtr&); + virtual void initialize(); + virtual void destroy(); +}; + +IPEndpointInfoPtr +getIPEndpointInfo(const EndpointInfoPtr& info) +{ + for(EndpointInfoPtr p = info; p; p = p->underlying) + { + IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(IPEndpointInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +} + +extern "C" +{ + +Plugin* +createIceWS(const CommunicatorPtr& c, const string&, const StringSeq&) +{ + return new WSEndpointFactoryPlugin(c); +} + +} + +namespace Ice +{ + +ICE_API void +registerIceWS(bool loadOnInitialize) +{ + registerPluginFactory("IceWS", createIceWS, loadOnInitialize); +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_API void +ICEregisterIceWS(bool loadOnInitialize) +{ + Ice::registerIceWS(loadOnInitialize); +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceInternal::upCast(WSEndpoint* p) { return p; } +#endif + +WSEndpointFactoryPlugin::WSEndpointFactoryPlugin(const CommunicatorPtr& communicator) +{ + assert(communicator); + + const EndpointFactoryManagerPtr efm = getInstance(communicator)->endpointFactoryManager(); + efm->add(new WSEndpointFactory(new ProtocolInstance(communicator, WSEndpointType, "ws", false), TCPEndpointType)); + efm->add(new WSEndpointFactory(new ProtocolInstance(communicator, WSSEndpointType, "wss", true), SSLEndpointType)); +} + +void +WSEndpointFactoryPlugin::initialize() +{ +} + +void +WSEndpointFactoryPlugin::destroy() +{ +} + +IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, const string& res) : + _instance(instance), _delegate(del), _resource(res) +{ +} + +IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& inst, const EndpointIPtr& del, vector& args) : + _instance(inst), _delegate(del) +{ + initWithOptions(args); + + if(_resource.empty()) + { + const_cast(_resource) = "/"; + } +} + +IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, InputStream* s) : + _instance(instance), _delegate(del) +{ + s->read(const_cast(_resource), false); +} + +EndpointInfoPtr +IceInternal::WSEndpoint::getInfo() const ICE_NOEXCEPT +{ + WSEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, ICE_SHARED_FROM_CONST_THIS(WSEndpoint)); + info->underlying = _delegate->getInfo(); + info->compress = info->underlying->compress; + info->timeout = info->underlying->timeout; + info->resource = _resource; + return info; +} + +Short +IceInternal::WSEndpoint::type() const +{ + return _delegate->type(); +} + +const string& +IceInternal::WSEndpoint::protocol() const +{ + return _delegate->protocol(); +} + +void +IceInternal::WSEndpoint::streamWriteImpl(OutputStream* s) const +{ + _delegate->streamWriteImpl(s); + s->write(_resource, false); +} + +Int +IceInternal::WSEndpoint::timeout() const +{ + return _delegate->timeout(); +} + +EndpointIPtr +IceInternal::WSEndpoint::timeout(Int timeout) const +{ + if(timeout == _delegate->timeout()) + { + return ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + return ICE_MAKE_SHARED(WSEndpoint, _instance, _delegate->timeout(timeout), _resource); + } +} + +const string& +IceInternal::WSEndpoint::connectionId() const +{ + return _delegate->connectionId(); +} + +EndpointIPtr +IceInternal::WSEndpoint::connectionId(const string& connectionId) const +{ + if(connectionId == _delegate->connectionId()) + { + return ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + return ICE_MAKE_SHARED(WSEndpoint, _instance, _delegate->connectionId(connectionId), _resource); + } +} + +bool +IceInternal::WSEndpoint::compress() const +{ + return _delegate->compress(); +} + +EndpointIPtr +IceInternal::WSEndpoint::compress(bool compress) const +{ + if(compress == _delegate->compress()) + { + return ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + return ICE_MAKE_SHARED(WSEndpoint, _instance, _delegate->compress(compress), _resource); + } +} + +bool +IceInternal::WSEndpoint::datagram() const +{ + return _delegate->datagram(); +} + +bool +IceInternal::WSEndpoint::secure() const +{ + return _delegate->secure(); +} + +TransceiverPtr +IceInternal::WSEndpoint::transceiver() const +{ + return 0; +} + +void +IceInternal::WSEndpoint::connectors_async(EndpointSelectionType selType, + const EndpointI_connectorsPtr& callback) const +{ + class CallbackI : public EndpointI_connectors + { + public: + + CallbackI(const EndpointI_connectorsPtr& callback, const ProtocolInstancePtr& instance, + const string& host, const string& resource) : + _callback(callback), _instance(instance), _host(host), _resource(resource) + { + } + + virtual void connectors(const vector& c) + { + vector connectors = c; + for(vector::iterator p = connectors.begin(); p != connectors.end(); ++p) + { + *p = new WSConnector(_instance, *p, _host, _resource); + } + _callback->connectors(connectors); + } + + virtual void exception(const LocalException& ex) + { + _callback->exception(ex); + } + + private: + + const EndpointI_connectorsPtr _callback; + const ProtocolInstancePtr _instance; + const string _host; + const string _resource; + }; + + ostringstream host; + IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo()); + if(info) + { + host << info->host << ":" << info->port; + } + _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, host.str(), _resource)); +} + +AcceptorPtr +IceInternal::WSEndpoint::acceptor(const string& adapterName) const +{ + AcceptorPtr delAcc = _delegate->acceptor(adapterName); + return new WSAcceptor(ICE_SHARED_FROM_CONST_THIS(WSEndpoint), _instance, delAcc); +} + +WSEndpointPtr +IceInternal::WSEndpoint::endpoint(const EndpointIPtr& delEndp) const +{ + if(delEndp.get() == _delegate.get()) + { + return ICE_DYNAMIC_CAST(WSEndpoint, ICE_SHARED_FROM_CONST_THIS(WSEndpoint)); + } + else + { + return ICE_MAKE_SHARED(WSEndpoint, _instance, delEndp, _resource); + } +} + +vector +IceInternal::WSEndpoint::expandIfWildcard() const +{ + vector endps = _delegate->expandIfWildcard(); + for(vector::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + *p = ICE_MAKE_SHARED(WSEndpoint, _instance, *p, _resource); + } + } + return endps; +} + +vector +IceInternal::WSEndpoint::expandHost(EndpointIPtr& publish) const +{ + vector endps = _delegate->expandHost(publish); + if(publish.get() == _delegate.get()) + { + publish = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else if(publish.get()) + { + publish = ICE_MAKE_SHARED(WSEndpoint, _instance, publish, _resource); + } + for(vector::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + *p = ICE_MAKE_SHARED(WSEndpoint, _instance, *p, _resource); + } + } + return endps; +} + +bool +IceInternal::WSEndpoint::equivalent(const EndpointIPtr& endpoint) const +{ + const WSEndpoint* wsEndpointI = dynamic_cast(endpoint.get()); + if(!wsEndpointI) + { + return false; + } + return _delegate->equivalent(wsEndpointI->_delegate); +} + +Int +IceInternal::WSEndpoint::hash() const +{ + int h = _delegate->hash(); + hashAdd(h, _resource); + return h; +} + +string +IceInternal::WSEndpoint::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + s << _delegate->options(); + + if(!_resource.empty()) + { + s << " -r "; + bool addQuote = _resource.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _resource; + if(addQuote) + { + s << "\""; + } + } + + return s.str(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::WSEndpoint::operator==(const Endpoint& r) const +#else +IceInternal::WSEndpoint::operator==(const LocalObject& r) const +#endif +{ + const WSEndpoint* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(!targetEqualTo(_delegate, p->_delegate)) + { + return false; + } + + if(_resource != p->_resource) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceInternal::WSEndpoint::operator<(const Endpoint& r) const +#else +IceInternal::WSEndpoint::operator<(const LocalObject& r) const +#endif +{ + const WSEndpoint* p = dynamic_cast(&r); + if(!p) + { + const EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(targetLess(_delegate, p->_delegate)) + { + return true; + } + else if (targetLess(p->_delegate, _delegate)) + { + return false; + } + + if(_resource < p->_resource) + { + return true; + } + else if (p->_resource < _resource) + { + return false; + } + + return false; +} + +bool +IceInternal::WSEndpoint::checkOption(const string& option, const string& argument, const string& endpoint) +{ + switch(option[1]) + { + case 'r': + { + if(argument.empty()) + { + throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -r option in endpoint " + + endpoint + _delegate->options()); + } + const_cast(_resource) = argument; + return true; + } + + default: + { + return false; + } + } +} + +IceInternal::WSEndpointFactory::WSEndpointFactory(const ProtocolInstancePtr& instance, Short type) : + EndpointFactoryWithUnderlying(instance, type) +{ +} + +EndpointFactoryPtr +IceInternal::WSEndpointFactory::cloneWithUnderlying(const ProtocolInstancePtr& instance, Short underlying) const +{ + return new WSEndpointFactory(instance, underlying); +} + +EndpointIPtr +IceInternal::WSEndpointFactory::createWithUnderlying(const EndpointIPtr& underlying, vector& args, bool) const +{ + return ICE_MAKE_SHARED(WSEndpoint, _instance, underlying, args); +} + +EndpointIPtr +IceInternal::WSEndpointFactory::readWithUnderlying(const EndpointIPtr& underlying, InputStream* s) const +{ + return ICE_MAKE_SHARED(WSEndpoint, _instance, underlying, s); +} diff --git a/Sources/IceCpp/WSTransceiver.cpp b/Sources/IceCpp/WSTransceiver.cpp new file mode 100644 index 0000000..2f239af --- /dev/null +++ b/Sources/IceCpp/WSTransceiver.cpp @@ -0,0 +1,1704 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Python 2.7 under Windows. +#if _MSC_VER == 1500 +typedef unsigned short uint16_t; +#else +#include +#endif + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +// +// WebSocket opcodes +// +#define OP_CONT 0x0 // Continuation frame +#define OP_TEXT 0x1 // Text frame +#define OP_DATA 0x2 // Data frame +#define OP_RES_0x3 0x3 // Reserved +#define OP_RES_0x4 0x4 // Reserved +#define OP_RES_0x5 0x5 // Reserved +#define OP_RES_0x6 0x6 // Reserved +#define OP_RES_0x7 0x7 // Reserved +#define OP_CLOSE 0x8 // Connection close +#define OP_PING 0x9 // Ping +#define OP_PONG 0xA // Pong +#define OP_RES_0xB 0xB // Reserved +#define OP_RES_0xC 0xC // Reserved +#define OP_RES_0xD 0xD // Reserved +#define OP_RES_0xE 0xE // Reserved +#define OP_RES_0xF 0xF // Reserved +#define FLAG_FINAL 0x80 // Last frame +#define FLAG_MASKED 0x80 // Payload is masked + +#define CLOSURE_NORMAL 1000 +#define CLOSURE_SHUTDOWN 1001 +#define CLOSURE_PROTOCOL_ERROR 1002 +#define CLOSURE_TOO_BIG 1009 + +namespace +{ + +const string _iceProtocol = "ice.zeroc.com"; +const string _wsUUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + +// +// Rename to avoid conflict with OS 10.10 htonll +// +void ice_htonll(Long v, Byte* dest) +{ + // + // Transfer a 64-bit integer in network (big-endian) order. + // +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v) + sizeof(Long) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#endif +} + +// +// Rename to avoid conflict with OS 10.10 nlltoh +// +Long ice_nlltoh(const Byte* src) +{ + Long v; + + // + // Extract a 64-bit integer in network (big-endian) order. + // +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v) + sizeof(Long) - 1; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest = *src; +#endif + + return v; +} + +} + +NativeInfoPtr +IceInternal::WSTransceiver::getNativeInfo() +{ + return _delegate->getNativeInfo(); +} + +#if defined(ICE_USE_IOCP) +AsyncInfo* +IceInternal::WSTransceiver::getAsyncInfo(SocketOperation status) +{ + return _delegate->getNativeInfo()->getAsyncInfo(status); +} +#endif + +SocketOperation +IceInternal::WSTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) +{ + // + // Delegate logs exceptions that occur during initialize(), so there's no need to trap them here. + // + if(_state == StateInitializeDelegate) + { + SocketOperation op = _delegate->initialize(readBuffer, writeBuffer); + if(op != SocketOperationNone) + { + return op; + } + _state = StateConnected; + } + + try + { + if(_state == StateConnected) + { + // + // We don't know how much we'll need to read. + // + _readBuffer.b.resize(_readBufferSize); + _readI = _readBuffer.i = _readBuffer.b.begin(); + + // + // The server waits for the client's upgrade request, the + // client sends the upgrade request. + // + _state = StateUpgradeRequestPending; + if(!_incoming) + { + // + // Compose the upgrade request. + // + ostringstream out; + out << "GET " << _resource << " HTTP/1.1\r\n" + << "Host: " << _host << "\r\n" + << "Upgrade: websocket\r\n" + << "Connection: Upgrade\r\n" + << "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n" + << "Sec-WebSocket-Version: 13\r\n" + << "Sec-WebSocket-Key: "; + + // + // The value for Sec-WebSocket-Key is a 16-byte random number, + // encoded with Base64. + // + vector key(16); + IceUtilInternal::generateRandom(reinterpret_cast(&key[0]), key.size()); + _key = IceInternal::Base64::encode(key); + out << _key << "\r\n\r\n"; // EOM + + string str = out.str(); + _writeBuffer.b.resize(str.size()); + memcpy(&_writeBuffer.b[0], str.c_str(), str.size()); + _writeBuffer.i = _writeBuffer.b.begin(); + } + } + + // + // Try to write the client's upgrade request. + // + if(_state == StateUpgradeRequestPending && !_incoming) + { + if(_writeBuffer.i < _writeBuffer.b.end()) + { + SocketOperation s = _delegate->write(_writeBuffer); + if(s) + { + return s; + } + } + assert(_writeBuffer.i == _writeBuffer.b.end()); + _state = StateUpgradeResponsePending; + } + + while(true) + { + if(_readBuffer.i < _readBuffer.b.end()) + { + SocketOperation s = _delegate->read(_readBuffer); + if(s == SocketOperationWrite || _readBuffer.i == _readBuffer.b.begin()) + { + return s; + } + } + + // + // Try to read the client's upgrade request or the server's response. + // + if((_state == StateUpgradeRequestPending && _incoming) || + (_state == StateUpgradeResponsePending && !_incoming)) + { + // + // Check if we have enough data for a complete message. + // + const Ice::Byte* p = _parser->isCompleteMessage(&_readBuffer.b[0], _readBuffer.i); + if(!p) + { + if(_readBuffer.i < _readBuffer.b.end()) + { + return SocketOperationRead; + } + + // + // Enlarge the buffer and try to read more. + // + const size_t oldSize = static_cast(_readBuffer.i - _readBuffer.b.begin()); + if(oldSize + 1024 > _instance->messageSizeMax()) + { + throw MemoryLimitException(__FILE__, __LINE__); + } + _readBuffer.b.resize(oldSize + 1024); + _readBuffer.i = _readBuffer.b.begin() + oldSize; + continue; // Try again to read the response/request + } + + // + // Set _readI at the end of the response/request message. + // + _readI = _readBuffer.b.begin() + (p - &_readBuffer.b[0]); + } + + // + // We're done, the client's upgrade request or server's response is read. + // + break; + } + + try + { + // + // Parse the client's upgrade request. + // + if(_state == StateUpgradeRequestPending && _incoming) + { + if(_parser->parse(&_readBuffer.b[0], _readI)) + { + handleRequest(_writeBuffer); + _state = StateUpgradeResponsePending; + } + else + { + throw ProtocolException(__FILE__, __LINE__, "incomplete request message"); + } + } + + if(_state == StateUpgradeResponsePending) + { + if(_incoming) + { + if(_writeBuffer.i < _writeBuffer.b.end()) + { + SocketOperation s = _delegate->write(_writeBuffer); + if(s) + { + return s; + } + } + } + else + { + // + // Parse the server's response + // + if(_parser->parse(&_readBuffer.b[0], _readI)) + { + handleResponse(); + } + else + { + throw ProtocolException(__FILE__, __LINE__, "incomplete response message"); + } + } + } + } + catch(const WebSocketException& ex) + { + throw ProtocolException(__FILE__, __LINE__, ex.reason); + } + + _state = StateOpened; + _nextState = StateOpened; + + if(_readI < _readBuffer.i) + { + _delegate->getNativeInfo()->ready(SocketOperationRead, true); + } + } + catch(const Ice::LocalException& ex) + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << protocol() << " connection HTTP upgrade request failed\n" << toString() << "\n" << ex; + } + throw; + } + + if(_instance->traceLevel() >= 1) + { + Trace out(_instance->logger(), _instance->traceCategory()); + if(_incoming) + { + out << "accepted " << protocol() << " connection HTTP upgrade request\n" << toString(); + } + else + { + out << protocol() << " connection HTTP upgrade request accepted\n" << toString(); + } + } + + return SocketOperationNone; +} + +SocketOperation +IceInternal::WSTransceiver::closing(bool initiator, const Ice::LocalException& reason) +{ + if(_instance->traceLevel() >= 1) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "gracefully closing " << protocol() << " connection\n" << toString(); + } + + State s = _nextState == StateOpened ? _state : _nextState; + + if(s == StateClosingRequestPending && _closingInitiator) + { + // + // If we initiated a close connection but also received a + // close connection, we assume we didn't initiated the + // connection and we send the close frame now. This is to + // ensure that if both peers close the connection at the same + // time we don't hang having both peer waiting for the close + // frame of the other. + // + assert(!initiator); + _closingInitiator = false; + return SocketOperationWrite; + } + else if(s >= StateClosingRequestPending) + { + return SocketOperationNone; + } + + _closingInitiator = initiator; + + if(dynamic_cast(&reason)) + { + _closingReason = CLOSURE_NORMAL; + } + else if(dynamic_cast(&reason) || + dynamic_cast(&reason)) + { + _closingReason = CLOSURE_SHUTDOWN; + } + else if(dynamic_cast(&reason)) + { + _closingReason = CLOSURE_PROTOCOL_ERROR; + } + else if(dynamic_cast(&reason)) + { + _closingReason = CLOSURE_TOO_BIG; + } + + if(_state == StateOpened) + { + _state = StateClosingRequestPending; + return initiator ? SocketOperationRead : SocketOperationWrite; + } + else + { + _nextState = StateClosingRequestPending; + return SocketOperationNone; + } +} + +void +IceInternal::WSTransceiver::close() +{ + _delegate->close(); + _state = StateClosed; + + // + // Clear the buffers now instead of waiting for destruction. + // + if(!_writePending) + { + _writeBuffer.b.clear(); + } + if(!_readPending) + { + _readBuffer.b.clear(); + } +} + +SocketOperation +IceInternal::WSTransceiver::write(Buffer& buf) +{ + if(_writePending) + { + return SocketOperationWrite; + } + + if(_state < StateOpened) + { + if(_state < StateConnected) + { + return _delegate->write(buf); + } + else + { + return _delegate->write(_writeBuffer); + } + } + + do + { + if(preWrite(buf)) + { + if(_writeBuffer.i < _writeBuffer.b.end()) + { + SocketOperation s = _delegate->write(_writeBuffer); + if(s) + { + return s; + } + } + else if(_incoming && !buf.b.empty() && _writeState == WriteStatePayload) + { + SocketOperation s = _delegate->write(buf); + if(s) + { + return s; + } + } + } + } + while(postWrite(buf)); + + if(_state == StateClosingResponsePending && !_closingInitiator) + { + return SocketOperationRead; + } + return SocketOperationNone; +} + +SocketOperation +IceInternal::WSTransceiver::read(Buffer& buf) +{ + if(_readPending) + { + return SocketOperationRead; + } + + if(_state < StateOpened) + { + if(_state < StateConnected) + { + return _delegate->read(buf); + } + else + { + if(_delegate->read(_readBuffer) == SocketOperationWrite) + { + return SocketOperationWrite; + } + else + { + return SocketOperationNone; + } + } + } + + // + // If we read the full Ice message, handle it before trying + // reading anymore data from the WS connection. + // + if(buf.i == buf.b.end()) + { + if(_readI < _readBuffer.i) + { + _delegate->getNativeInfo()->ready(SocketOperationRead, true); + } + return SocketOperationNone; + } + + SocketOperation s = SocketOperationNone; + do + { + if(preRead(buf)) + { + if(_readState == ReadStatePayload) + { + // + // If the payload length is smaller than what remains to be read, we read + // no more than the payload length. The remaining of the buffer will be + // sent over in another frame. + // + size_t readSz = _readPayloadLength - static_cast(buf.i - _readStart); // Already read + if(static_cast(buf.b.end() - buf.i) > readSz) + { + size_t size = buf.b.size(); + buf.b.resize(static_cast(buf.i - buf.b.begin()) + readSz); + s = _delegate->read(buf); + buf.b.resize(size); + } + else + { + s = _delegate->read(buf); + } + } + else + { + s = _delegate->read(_readBuffer); + } + + if(s == SocketOperationWrite) + { + postRead(buf); + return s; + } + } + } + while(postRead(buf)); + + if(buf.i == buf.b.end()) + { + if(_readI < _readBuffer.i) + { + _delegate->getNativeInfo()->ready(SocketOperationRead, true); + } + s = SocketOperationNone; + } + else + { + _delegate->getNativeInfo()->ready(SocketOperationRead, false); + s = SocketOperationRead; + } + + if(((_state == StateClosingRequestPending && !_closingInitiator) || + (_state == StateClosingResponsePending && _closingInitiator) || + _state == StatePingPending || + _state == StatePongPending) && + _writeState == WriteStateHeader) + { + // We have things to write, ask to be notified when writes are ready. + s = static_cast(s | SocketOperationWrite); + } + return s; +} + +#if defined(ICE_USE_IOCP) +bool +IceInternal::WSTransceiver::startWrite(Buffer& buf) +{ + _writePending = true; + if(_state < StateOpened) + { + if(_state < StateConnected) + { + return _delegate->startWrite(buf); + } + else + { + return _delegate->startWrite(_writeBuffer); + } + } + + if(preWrite(buf)) + { + if(_writeBuffer.i < _writeBuffer.b.end()) + { + if(_delegate->startWrite(_writeBuffer)) + { + return buf.b.size() == _writePayloadLength; // Return true only if we've written the whole buffer. + } + return false; + } + else + { + assert(_incoming); + return _delegate->startWrite(buf); + } + } + else + { + _delegate->getNativeInfo()->completed(IceInternal::SocketOperationWrite); + return false; + } +} + +void +IceInternal::WSTransceiver::finishWrite(Buffer& buf) +{ + _writePending = false; + + if(_state < StateOpened) + { + if(_state < StateConnected) + { + _delegate->finishWrite(buf); + } + else + { + _delegate->finishWrite(_writeBuffer); + } + return; + } + + if(_writeBuffer.i < _writeBuffer.b.end()) + { + _delegate->finishWrite(_writeBuffer); + } + else if(!buf.b.empty() && buf.i != buf.b.end()) + { + assert(_incoming); + _delegate->finishWrite(buf); + } + + if(_state == StateClosed) + { + _writeBuffer.b.clear(); + return; + } + + postWrite(buf); +} + +void +IceInternal::WSTransceiver::startRead(Buffer& buf) +{ + _readPending = true; + if(_state < StateOpened) + { + if(_state < StateConnected) + { + _delegate->startRead(buf); + } + else + { + _delegate->startRead(_readBuffer); + } + return; + } + + if(preRead(buf)) + { + if(_readState == ReadStatePayload) + { + // + // If the payload length is smaller than what remains to be read, we read + // no more than the payload length. The remaining of the buffer will be + // sent over in another frame. + // + size_t readSz = _readPayloadLength - (buf.i - _readStart); + if(static_cast(buf.b.end() - buf.i) > readSz) + { + size_t size = buf.b.size(); + buf.b.resize(buf.i - buf.b.begin() + readSz); + _delegate->startRead(buf); + buf.b.resize(size); + } + else + { + _delegate->startRead(buf); + } + } + else + { + _delegate->startRead(_readBuffer); + } + } + else + { + _delegate->getNativeInfo()->completed(IceInternal::SocketOperationRead); + } +} + +void +IceInternal::WSTransceiver::finishRead(Buffer& buf) +{ + _readPending = false; + if(_state < StateOpened) + { + if(_state < StateConnected) + { + _delegate->finishRead(buf); + } + else + { + _delegate->finishRead(_readBuffer); + } + return; + } + + if(buf.b.empty() || buf.i == buf.b.end()) + { + // Nothing to do. + } + else if(_readState == ReadStatePayload) + { + _delegate->finishRead(buf); + } + else + { + _delegate->finishRead(_readBuffer); + } + + if(_state == StateClosed) + { + _readBuffer.b.clear(); + return; + } + + postRead(buf); +} +#endif + +string +IceInternal::WSTransceiver::protocol() const +{ + return _instance->protocol(); +} + +string +IceInternal::WSTransceiver::toString() const +{ + return _delegate->toString(); +} + +string +IceInternal::WSTransceiver::toDetailedString() const +{ + return _delegate->toDetailedString(); +} + +Ice::ConnectionInfoPtr +IceInternal::WSTransceiver::getInfo() const +{ + WSConnectionInfoPtr info = ICE_MAKE_SHARED(WSConnectionInfo); + info->underlying = _delegate->getInfo(); + info->headers = _parser->getHeaders(); + return info; +} + +void +IceInternal::WSTransceiver::checkSendSize(const Buffer& buf) +{ + _delegate->checkSendSize(buf); +} + +void +IceInternal::WSTransceiver::setBufferSize(int rcvSize, int sndSize) +{ + _delegate->setBufferSize(rcvSize, sndSize); +} + +IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del, + const string& host, const string& resource) : + _instance(instance), + _delegate(del), + _host(host), + _resource(resource), + _incoming(false), + _state(StateInitializeDelegate), + _parser(new HttpParser), + _readState(ReadStateOpcode), + _readBufferSize(1024), + _readLastFrame(true), + _readOpCode(0), + _readHeaderLength(0), + _readPayloadLength(0), + _writeState(WriteStateHeader), + _writeBufferSize(16 * 1024), + _readPending(false), + _writePending(false), + _closingInitiator(false), + _closingReason(CLOSURE_NORMAL) +{ + // + // Use 1KB read and 16KB write buffer sizes. We use 16KB for the + // write buffer size because all the data needs to be copied to + // the write buffer for the purpose of masking. A 16KB buffer + // appears to be a good compromise to reduce the number of socket + // write calls and not consume too much memory. + // +} + +IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del) : + _instance(instance), + _delegate(del), + _incoming(true), + _state(StateInitializeDelegate), + _parser(new HttpParser), + _readState(ReadStateOpcode), + _readBufferSize(1024), + _readLastFrame(true), + _readOpCode(0), + _readHeaderLength(0), + _readPayloadLength(0), + _writeState(WriteStateHeader), + _writeBufferSize(1024), + _readPending(false), + _writePending(false), + _closingInitiator(false), + _closingReason(CLOSURE_NORMAL) +{ + // + // Use 1KB read and write buffer sizes. + // +} + +IceInternal::WSTransceiver::~WSTransceiver() +{ +} + +void +IceInternal::WSTransceiver::handleRequest(Buffer& responseBuffer) +{ + string val; + + // + // HTTP/1.1 + // + if(_parser->versionMajor() != 1 || _parser->versionMinor() != 1) + { + throw WebSocketException("unsupported HTTP version"); + } + + // + // "An |Upgrade| header field containing the value 'websocket', + // treated as an ASCII case-insensitive value." + // + if(!_parser->getHeader("Upgrade", val, true)) + { + throw WebSocketException("missing value for Upgrade field"); + } + else if(val != "websocket") + { + throw WebSocketException("invalid value `" + val + "' for Upgrade field"); + } + + // + // "A |Connection| header field that includes the token 'Upgrade', + // treated as an ASCII case-insensitive value. + // + if(!_parser->getHeader("Connection", val, true)) + { + throw WebSocketException("missing value for Connection field"); + } + else if(val.find("upgrade") == string::npos) + { + throw WebSocketException("invalid value `" + val + "' for Connection field"); + } + + // + // "A |Sec-WebSocket-Version| header field, with a value of 13." + // + if(!_parser->getHeader("Sec-WebSocket-Version", val, false)) + { + throw WebSocketException("missing value for WebSocket version"); + } + else if(val != "13") + { + throw WebSocketException("unsupported WebSocket version `" + val + "'"); + } + + // + // "Optionally, a |Sec-WebSocket-Protocol| header field, with a list + // of values indicating which protocols the client would like to + // speak, ordered by preference." + // + bool addProtocol = false; + if(_parser->getHeader("Sec-WebSocket-Protocol", val, true)) + { + vector protocols; + if(!IceUtilInternal::splitString(val, ",", protocols)) + { + throw WebSocketException("invalid value `" + val + "' for WebSocket protocol"); + } + for(vector::iterator p = protocols.begin(); p != protocols.end(); ++p) + { + if(IceUtilInternal::trim(*p) != _iceProtocol) + { + throw WebSocketException("unknown value `" + *p + "' for WebSocket protocol"); + } + addProtocol = true; + } + } + + // + // "A |Sec-WebSocket-Key| header field with a base64-encoded + // value that, when decoded, is 16 bytes in length." + // + string key; + if(!_parser->getHeader("Sec-WebSocket-Key", key, false)) + { + throw WebSocketException("missing value for WebSocket key"); + } + + vector decodedKey = Base64::decode(key); + if(decodedKey.size() != 16) + { + throw WebSocketException("invalid value `" + key + "' for WebSocket key"); + } + + // + // Retain the target resource. + // + const_cast(_resource) = _parser->uri(); + + // + // Compose the response. + // + ostringstream out; + out << "HTTP/1.1 101 Switching Protocols\r\n" + << "Upgrade: websocket\r\n" + << "Connection: Upgrade\r\n"; + if(addProtocol) + { + out << "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n"; + } + + // + // The response includes: + // + // "A |Sec-WebSocket-Accept| header field. The value of this + // header field is constructed by concatenating /key/, defined + // above in step 4 in Section 4.2.2, with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of this + // concatenated value to obtain a 20-byte value and base64- + // encoding (see Section 4 of [RFC4648]) this 20-byte hash. + // + out << "Sec-WebSocket-Accept: "; + string input = key + _wsUUID; + vector hash; + sha1(reinterpret_cast(&input[0]), input.size(), hash); + out << IceInternal::Base64::encode(hash) << "\r\n" << "\r\n"; // EOM + + string str = out.str(); + responseBuffer.b.resize(str.size()); + memcpy(&responseBuffer.b[0], str.c_str(), str.size()); + responseBuffer.i = responseBuffer.b.begin(); +} + +void +IceInternal::WSTransceiver::handleResponse() +{ + string val; + + // + // HTTP/1.1 + // + if(_parser->versionMajor() != 1 || _parser->versionMinor() != 1) + { + throw WebSocketException("unsupported HTTP version"); + } + + // + // "If the status code received from the server is not 101, the + // client handles the response per HTTP [RFC2616] procedures. In + // particular, the client might perform authentication if it + // receives a 401 status code; the server might redirect the client + // using a 3xx status code (but clients are not required to follow + // them), etc." + // + if(_parser->status() != 101) + { + ostringstream out; + out << "unexpected status value " << _parser->status(); + if(!_parser->reason().empty()) + { + out << ":" << endl << _parser->reason(); + } + throw WebSocketException(out.str()); + } + + // + // "If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_." + // + if(!_parser->getHeader("Upgrade", val, true)) + { + throw WebSocketException("missing value for Upgrade field"); + } + else if(val != "websocket") + { + throw WebSocketException("invalid value `" + val + "' for Upgrade field"); + } + + // + // "If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_." + // + if(!_parser->getHeader("Connection", val, true)) + { + throw WebSocketException("missing value for Connection field"); + } + else if(val.find("upgrade") == string::npos) + { + throw WebSocketException("invalid value `" + val + "' for Connection field"); + } + + // + // "If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_." + // + if(_parser->getHeader("Sec-WebSocket-Protocol", val, true) && val != _iceProtocol) + { + throw WebSocketException("invalid value `" + val + "' for WebSocket protocol"); + } + + // + // "If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_." + // + if(!_parser->getHeader("Sec-WebSocket-Accept", val, false)) + { + throw WebSocketException("missing value for Sec-WebSocket-Accept"); + } + string input = _key + _wsUUID; + vector hash; + sha1(reinterpret_cast(&input[0]), input.size(), hash); + if(val != IceInternal::Base64::encode(hash)) + { + throw WebSocketException("invalid value `" + val + "' for Sec-WebSocket-Accept"); + } +} + +bool +IceInternal::WSTransceiver::preRead(Buffer& buf) +{ + while(true) + { + if(_readState == ReadStateOpcode) + { + // + // Is there enough data available to read the opcode? + // + if(!readBuffered(2)) + { + return true; + } + + // + // Most-significant bit indicates whether this is the + // last frame. Least-significant four bits hold the + // opcode. + // + unsigned char ch = static_cast(*_readI++); + _readOpCode = ch & 0xf; + + // + // Remember if last frame if we're going to read a data or + // continuation frame, this is only for protocol + // correctness checking purpose. + // + if(_readOpCode == OP_DATA) + { + if(!_readLastFrame) + { + throw ProtocolException(__FILE__, __LINE__, "invalid data frame, no FIN on previous frame"); + } + _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL; + } + else if(_readOpCode == OP_CONT) + { + if(_readLastFrame) + { + throw ProtocolException(__FILE__, __LINE__, "invalid continuation frame, previous frame FIN set"); + } + _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL; + } + + ch = static_cast(*_readI++); + + // + // Check the MASK bit. Messages sent by a client must be masked; + // messages sent by a server must not be masked. + // + const bool masked = (ch & FLAG_MASKED) == FLAG_MASKED; + if(masked != _incoming) + { + throw ProtocolException(__FILE__, __LINE__, "invalid masking"); + } + + // + // Extract the payload length, which can have the following values: + // + // 0-125: The payload length + // 126: The subsequent two bytes contain the payload length + // 127: The subsequent eight bytes contain the payload length + // + _readPayloadLength = (ch & 0x7f); + if(_readPayloadLength < 126) + { + _readHeaderLength = 0; + } + else if(_readPayloadLength == 126) + { + _readHeaderLength = 2; // Need to read a 16-bit payload length. + } + else + { + _readHeaderLength = 8; // Need to read a 64-bit payload length. + } + if(masked) + { + _readHeaderLength += 4; // Need to read a 32-bit mask. + } + + _readState = ReadStateHeader; + } + + if(_readState == ReadStateHeader) + { + // + // Is there enough data available to read the header? + // + if(_readHeaderLength > 0 && !readBuffered(_readHeaderLength)) + { + return true; + } + + if(_readPayloadLength == 126) + { + _readPayloadLength = static_cast(ntohs(*reinterpret_cast(_readI))); + _readI += 2; + } + else if(_readPayloadLength == 127) + { + assert(_readPayloadLength == 127); + Long l = ice_nlltoh(_readI); + _readI += 8; + if(l < 0 || l > INT_MAX) + { + ostringstream ostr; + ostr << "invalid WebSocket payload length: " << l; + throw ProtocolException(__FILE__, __LINE__, ostr.str()); + } + _readPayloadLength = static_cast(l); + } + + // + // Read the mask if this is an incoming connection. + // + if(_incoming) + { + assert(_readBuffer.i - _readI >= 4); // We must have needed to read the mask. + memcpy(_readMask, _readI, 4); // Copy the mask. + _readI += 4; + } + + switch(_readOpCode) + { + case OP_TEXT: // Text frame + { + throw ProtocolException(__FILE__, __LINE__, "text frames not supported"); + } + case OP_DATA: // Data frame + case OP_CONT: // Continuation frame + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "received " << protocol() << (_readOpCode == OP_DATA ? " data" : " continuation"); + out << " frame with payload length of " << _readPayloadLength; + out << " bytes\n" << toString(); + } + + if(_readPayloadLength <= 0) + { + throw ProtocolException(__FILE__, __LINE__, "payload length is 0"); + } + _readState = ReadStatePayload; + assert(buf.i != buf.b.end()); + _readFrameStart = buf.i; + break; + } + case OP_CLOSE: // Connection close + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "received " << protocol() << " connection close frame\n" << toString(); + } + + State s = _nextState == StateOpened ? _state : _nextState; + if(s == StateClosingRequestPending) + { + // + // If we receive a close frame while we were actually + // waiting to send one, change the role and send a + // close frame response. + // + if(!_closingInitiator) + { + _closingInitiator = true; + } + if(_state == StateClosingRequestPending) + { + _state = StateClosingResponsePending; + } + else + { + _nextState = StateClosingResponsePending; + } + return false; // No longer interested in reading + } + else + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + } + case OP_PING: + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "received " << protocol() << " connection ping frame\n" << toString(); + } + _readState = ReadStateControlFrame; + break; + } + case OP_PONG: // Pong + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "received " << protocol() << " connection pong frame\n" << toString(); + } + _readState = ReadStateControlFrame; + break; + } + default: + { + ostringstream ostr; + ostr << "unsupported opcode: " << _readOpCode; + throw ProtocolException(__FILE__, __LINE__, ostr.str()); + } + } + } + + if(_readState == ReadStateControlFrame) + { + if(_readPayloadLength > 0 && !readBuffered(_readPayloadLength)) + { + return true; + } + + if(_readPayloadLength > 0 && _readOpCode == OP_PING) + { + _pingPayload.clear(); + _pingPayload.resize(_readPayloadLength); + memcpy(&_pingPayload[0], _readI, _pingPayload.size()); + } + + _readI += _readPayloadLength; + _readPayloadLength = 0; + + if(_readOpCode == OP_PING) + { + if(_state == StateOpened) + { + _state = StatePongPending; // Send pong frame now + } + else if(_nextState < StatePongPending) + { + _nextState = StatePongPending; // Send pong frame next + } + } + + // + // We've read the payload of the PING/PONG frame, we're ready + // to read a new frame. + // + _readState = ReadStateOpcode; + } + + if(_readState == ReadStatePayload) + { + // + // This must be assigned before the check for the buffer. If the buffer is empty + // or already read, postRead will return false. + // + _readStart = buf.i; + + if(buf.b.empty() || buf.i == buf.b.end()) + { + return false; + } + + size_t n = min(static_cast(_readBuffer.i - _readI), static_cast(buf.b.end() - buf.i)); + + if(n > _readPayloadLength) + { + n = _readPayloadLength; + } + if(n > 0) + { + memcpy(buf.i, _readI, n); + buf.i += n; + _readI += n; + } + // + // Continue reading if we didn't read the full message, otherwise give back + // the control to the connection + // + return buf.i < buf.b.end() && n < _readPayloadLength; + } + } +} + +bool +IceInternal::WSTransceiver::postRead(Buffer& buf) +{ + if(_readState != ReadStatePayload) + { + return _readStart < _readBuffer.i; // Returns true if data was read. + } + + if(_readStart == buf.i) + { + return false; // Nothing was read or nothing to read. + } + assert(_readStart < buf.i); + + if(_incoming) + { + // + // Unmask the data we just read. + // + IceInternal::Buffer::Container::iterator p = _readStart; + for(size_t n = static_cast(_readStart - _readFrameStart); p < buf.i; ++p, ++n) + { + *p ^= _readMask[n % 4]; + } + } + + _readPayloadLength -= static_cast(buf.i - _readStart); + _readStart = buf.i; + if(_readPayloadLength == 0) + { + // + // We've read the complete payload, we're ready to read a new frame. + // + _readState = ReadStateOpcode; + } + return buf.i != buf.b.end(); +} + +bool +IceInternal::WSTransceiver::preWrite(Buffer& buf) +{ + if(_writeState == WriteStateHeader) + { + if(_state == StateOpened) + { + if(buf.b.empty() || buf.i == buf.b.end()) + { + return false; + } + + assert(buf.i == buf.b.begin()); + prepareWriteHeader(OP_DATA, buf.b.size()); + + _writeState = WriteStatePayload; + } + else if(_state == StatePingPending) + { + prepareWriteHeader(OP_PING, 0); // Don't send any payload + + _writeBuffer.b.resize(static_cast(_writeBuffer.i - _writeBuffer.b.begin())); + _writeState = WriteStateControlFrame; + _writeBuffer.i = _writeBuffer.b.begin(); + } + else if(_state == StatePongPending) + { + prepareWriteHeader(OP_PONG, _pingPayload.size()); + if(_pingPayload.size() > static_cast(_writeBuffer.b.end() - _writeBuffer.i)) + { + size_t pos = static_cast(_writeBuffer.i - _writeBuffer.b.begin()); + _writeBuffer.b.resize(pos + _pingPayload.size()); + _writeBuffer.i = _writeBuffer.b.begin() + pos; + } + memcpy(_writeBuffer.i, &_pingPayload[0], _pingPayload.size()); + _writeBuffer.i += _pingPayload.size(); + _pingPayload.clear(); + + _writeBuffer.b.resize(static_cast(_writeBuffer.i - _writeBuffer.b.begin())); + _writeState = WriteStateControlFrame; + _writeBuffer.i = _writeBuffer.b.begin(); + } + else if((_state == StateClosingRequestPending && !_closingInitiator) || + (_state == StateClosingResponsePending && _closingInitiator)) + { + prepareWriteHeader(OP_CLOSE, 2); + + // Write closing reason + *reinterpret_cast(_writeBuffer.i) = htons(static_cast(_closingReason)); + if(!_incoming) + { + *_writeBuffer.i++ ^= _writeMask[0]; + *_writeBuffer.i++ ^= _writeMask[1]; + } + else + { + _writeBuffer.i += 2; + } + + _writeState = WriteStateControlFrame; + _writeBuffer.b.resize(static_cast(_writeBuffer.i - _writeBuffer.b.begin())); + _writeBuffer.i = _writeBuffer.b.begin(); + } + else + { + assert(_state != StateClosed); + return false; // Nothing to write in this state + } + + _writePayloadLength = 0; + } + + if(_writeState == WriteStatePayload) + { + // + // For an outgoing connection, each message must be masked with a random + // 32-bit value, so we copy the entire message into the internal buffer + // for writing. For incoming connections, we just copy the start of the + // message in the internal buffer after the header. If the message is + // larger, the reminder is sent directly from the message buffer to avoid + // copying. + // + + if(!_incoming && (_writePayloadLength == 0 || _writeBuffer.i == _writeBuffer.b.end())) + { + if(_writeBuffer.i == _writeBuffer.b.end()) + { + _writeBuffer.i = _writeBuffer.b.begin(); + } + + size_t n = static_cast(buf.i - buf.b.begin()); + for(; n < buf.b.size() && _writeBuffer.i < _writeBuffer.b.end(); ++_writeBuffer.i, ++n) + { + *_writeBuffer.i = buf.b[n] ^ _writeMask[n % 4]; + } + _writePayloadLength = n; + if(_writeBuffer.i < _writeBuffer.b.end()) + { + _writeBuffer.b.resize(static_cast(_writeBuffer.i - _writeBuffer.b.begin())); + } + _writeBuffer.i = _writeBuffer.b.begin(); + } + else if(_writePayloadLength == 0) + { + size_t n = min(static_cast(_writeBuffer.b.end() - _writeBuffer.i), + static_cast(buf.b.end() - buf.i)); + memcpy(_writeBuffer.i, buf.i, n); + _writeBuffer.i += n; + buf.i += n; + _writePayloadLength = n; + if(_writeBuffer.i < _writeBuffer.b.end()) + { + _writeBuffer.b.resize(static_cast(_writeBuffer.i - _writeBuffer.b.begin())); + } + _writeBuffer.i = _writeBuffer.b.begin(); + } + return true; + } + else + { + return _writeBuffer.i < _writeBuffer.b.end(); + } +} + +bool +IceInternal::WSTransceiver::postWrite(Buffer& buf) +{ + if(_state > StateOpened && _writeState == WriteStateControlFrame) + { + if(_writeBuffer.i == _writeBuffer.b.end()) + { + if(_state == StatePingPending) + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "sent " << protocol() << " connection ping frame\n" << toString(); + } + } + else if(_state == StatePongPending) + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "sent " << protocol() << " connection pong frame\n" << toString(); + } + } + else if((_state == StateClosingRequestPending && !_closingInitiator) || + (_state == StateClosingResponsePending && _closingInitiator)) + { + if(_instance->traceLevel() >= 2) + { + Trace out(_instance->logger(), _instance->traceCategory()); + out << "sent " << protocol() << " connection close frame\n" << toString(); + } + + if(_state == StateClosingRequestPending && !_closingInitiator) + { + _writeState = WriteStateHeader; + _state = StateClosingResponsePending; + return false; + } + else + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + } + else if(_state == StateClosed) + { + return false; + } + + _state = _nextState; + _nextState = StateOpened; + _writeState = WriteStateHeader; + } + else + { + return true; + } + } + + if((!_incoming || buf.i == buf.b.begin()) && _writePayloadLength > 0) + { + if(_writeBuffer.i == _writeBuffer.b.end()) + { + buf.i = buf.b.begin() + _writePayloadLength; + } + } + + if(buf.b.empty() || buf.i == buf.b.end()) + { + _writeState = WriteStateHeader; + if(_state == StatePingPending || + _state == StatePongPending || + (_state == StateClosingRequestPending && !_closingInitiator) || + (_state == StateClosingResponsePending && _closingInitiator)) + { + return true; + } + } + else if(_state == StateOpened) + { + return true; + } + return false; +} + +bool +IceInternal::WSTransceiver::readBuffered(IceInternal::Buffer::Container::size_type sz) +{ + if(_readI == _readBuffer.i) + { + _readBuffer.b.resize(_readBufferSize); + _readI = _readBuffer.i = _readBuffer.b.begin(); + } + else + { + size_t available = static_cast(_readBuffer.i - _readI); + if(available < sz) + { + if(_readI != &_readBuffer.b[0]) + { + memmove(&_readBuffer.b[0], _readI, available); + } + _readBuffer.b.resize(max(_readBufferSize, sz)); + _readI = _readBuffer.b.begin(); + _readBuffer.i = _readI + available; + } + } + + _readStart = _readBuffer.i; + if(_readI + sz > _readBuffer.i) + { + return false; // Not enough read. + } + assert(_readBuffer.i > _readI); + return true; +} + +void +IceInternal::WSTransceiver::prepareWriteHeader(Byte opCode, IceInternal::Buffer::Container::size_type payloadLength) +{ + // + // We need to prepare the frame header. + // + _writeBuffer.b.resize(_writeBufferSize); + _writeBuffer.i = _writeBuffer.b.begin(); + + // + // Set the opcode - this is the one and only data frame. + // + *_writeBuffer.i++ = static_cast(opCode | FLAG_FINAL); + + // + // Set the payload length. + // + if(payloadLength <= 125) + { + *_writeBuffer.i++ = static_cast(payloadLength); + } + else if(payloadLength > 125 && payloadLength <= USHRT_MAX) + { + // + // Use an extra 16 bits to encode the payload length. + // + *_writeBuffer.i++ = static_cast(126); + *reinterpret_cast(_writeBuffer.i) = htons(static_cast(payloadLength)); + _writeBuffer.i += 2; + } + else if(payloadLength > USHRT_MAX) + { + // + // Use an extra 64 bits to encode the payload length. + // + *_writeBuffer.i++ = static_cast(127); + ice_htonll(static_cast(payloadLength), _writeBuffer.i); + _writeBuffer.i += 8; + } + + if(!_incoming) + { + // + // Add a random 32-bit mask to every outgoing frame, copy the payload data, + // and apply the mask. + // + _writeBuffer.b[1] |= FLAG_MASKED; + IceUtilInternal::generateRandom(reinterpret_cast(_writeMask), sizeof(_writeMask)); + memcpy(_writeBuffer.i, _writeMask, sizeof(_writeMask)); + _writeBuffer.i += sizeof(_writeMask); + } +} diff --git a/Sources/IceCpp/include/Ice/ACM.h b/Sources/IceCpp/include/Ice/ACM.h new file mode 100644 index 0000000..107803a --- /dev/null +++ b/Sources/IceCpp/include/Ice/ACM.h @@ -0,0 +1,119 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ACM_H +#define ICE_ACM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class ACMConfig +{ +public: + + ACMConfig(bool = false); + ACMConfig(const Ice::PropertiesPtr&, const Ice::LoggerPtr&, const std::string&, const ACMConfig&); + + IceUtil::Time timeout; + Ice::ACMHeartbeat heartbeat; + Ice::ACMClose close; +}; + +class ACMMonitor : public IceUtil::TimerTask +{ +public: + + virtual void add(const Ice::ConnectionIPtr&) = 0; + virtual void remove(const Ice::ConnectionIPtr&) = 0; + virtual void reap(const Ice::ConnectionIPtr&) = 0; + + virtual ACMMonitorPtr acm(const IceUtil::Optional&, + const IceUtil::Optional&, + const IceUtil::Optional&) = 0; + virtual Ice::ACM getACM() = 0; +}; + +class FactoryACMMonitor : public ACMMonitor, public IceUtil::Monitor +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + FactoryACMMonitor(const InstancePtr&, const ACMConfig&); + virtual ~FactoryACMMonitor(); + + virtual void add(const Ice::ConnectionIPtr&); + virtual void remove(const Ice::ConnectionIPtr&); + virtual void reap(const Ice::ConnectionIPtr&); + + virtual ACMMonitorPtr acm(const IceUtil::Optional&, + const IceUtil::Optional&, + const IceUtil::Optional&); + virtual Ice::ACM getACM(); + + void destroy(); + void swapReapedConnections(std::vector&); + +private: + + friend class ConnectionACMMonitor; + void handleException(const std::exception&); + void handleException(); + + virtual void runTimerTask(); + + InstancePtr _instance; + const ACMConfig _config; + + std::vector > _changes; + std::set _connections; + std::vector _reapedConnections; +}; + +class ConnectionACMMonitor : public ACMMonitor, + public IceUtil::Mutex +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + ConnectionACMMonitor(const FactoryACMMonitorPtr&, const IceUtil::TimerPtr&, const ACMConfig&); + virtual ~ConnectionACMMonitor(); + + virtual void add(const Ice::ConnectionIPtr&); + virtual void remove(const Ice::ConnectionIPtr&); + virtual void reap(const Ice::ConnectionIPtr&); + + virtual ACMMonitorPtr acm(const IceUtil::Optional&, + const IceUtil::Optional&, + const IceUtil::Optional&); + virtual Ice::ACM getACM(); + +private: + + virtual void runTimerTask(); + + const FactoryACMMonitorPtr _parent; + const IceUtil::TimerPtr _timer; + const ACMConfig _config; + + Ice::ConnectionIPtr _connection; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ACMF.h b/Sources/IceCpp/include/Ice/ACMF.h new file mode 100644 index 0000000..afaa1b7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ACMF.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ACM_F_H +#define ICE_ACM_F_H + +#include +#include + +namespace IceInternal +{ + +class ACMMonitor; +class FactoryACMMonitor; + +#ifdef ICE_CPP11_MAPPING +using ACMMonitorPtr = ::std::shared_ptr; +using FactoryACMMonitorPtr = ::std::shared_ptr; +#else +IceUtil::Shared* upCast(ACMMonitor*); +typedef IceInternal::Handle ACMMonitorPtr; + +IceUtil::Shared* upCast(FactoryACMMonitor*); +typedef IceInternal::Handle FactoryACMMonitorPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Acceptor.h b/Sources/IceCpp/include/Ice/Acceptor.h new file mode 100644 index 0000000..ca94aef --- /dev/null +++ b/Sources/IceCpp/include/Ice/Acceptor.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ACCEPTOR_H +#define ICE_ACCEPTOR_H + +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API Acceptor : public virtual ::IceUtil::Shared +{ +public: + virtual ~Acceptor(); + + virtual NativeInfoPtr getNativeInfo() = 0; + virtual void close() = 0; + virtual EndpointIPtr listen() = 0; +#if defined(ICE_USE_IOCP) + virtual void startAccept() = 0; + virtual void finishAccept() = 0; +#endif + virtual TransceiverPtr accept() = 0; + virtual std::string protocol() const = 0; + virtual std::string toString() const = 0; + virtual std::string toDetailedString() const = 0; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/AcceptorF.h b/Sources/IceCpp/include/Ice/AcceptorF.h new file mode 100644 index 0000000..4e6b97b --- /dev/null +++ b/Sources/IceCpp/include/Ice/AcceptorF.h @@ -0,0 +1,25 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ACCEPTOR_F_H +#define ICE_ACCEPTOR_F_H + +#include + +#include + +namespace IceInternal +{ + +class Acceptor; +ICE_API IceUtil::Shared* upCast(Acceptor*); +typedef Handle AcceptorPtr; + +class TcpAcceptor; +ICE_API IceUtil::Shared* upCast(TcpAcceptor*); +typedef Handle TcpAcceptorPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Application.h b/Sources/IceCpp/include/Ice/Application.h new file mode 100644 index 0000000..973b872 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Application.h @@ -0,0 +1,326 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_APPLICATION_H +#define ICE_APPLICATION_H + +#include +#include +#include +#include + +namespace Ice +{ + +using IceUtil::CtrlCHandler; +using IceUtil::CtrlCHandlerCallback; + +#ifdef ICE_CPP11_MAPPING +/** + * Determines how the Application class handles signals. + */ +enum class SignalPolicy : unsigned char +#else +enum SignalPolicy +#endif +{ + /** Enables signal handling. */ + HandleSignals, + /** Disables signal handling, meaning signals retain their default behavior. */ + NoSignalHandling +}; + +/** + * Singleton helper class that simplifies Ice initialization, finalization and signal handling. + * An application uses this class by writing a subclass and implementing the run method. + * \headerfile Ice/Ice.h + */ +class ICE_API Application +{ +public: + + /** + * The constructor configures the signal handling behavior. + * @param policy Specifies whether to handle signals. If not specified, the default behavior + * is to handle signals. + */ + Application(SignalPolicy policy = ICE_ENUM(SignalPolicy, HandleSignals)); + +#ifdef ICE_CPP11_MAPPING + /// \cond IGNORE + Application(const Application&) = delete; + Application& operator=(const Application&) = delete; + /// \endcond +#endif + + virtual ~Application(); + + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(int argc, const char* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(int argc, const char* const argv[], ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); + +#ifdef _WIN32 + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(int argc, const wchar_t* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(int argc, const wchar_t* const argv[], ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); +#endif + + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param args The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(const StringSeq& args, const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Call this main() from the global main(). main() + * initializes the Communicator, calls run() and destroys the + * the Communicator upon return from run(). It handles all + * exceptions properly, i.e., error message are printed if + * exceptions propagate to main(), and the Communicator is always + * destroyed, regardless of exceptions. + * @param args The command-line arguments. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status. + */ + int main(const StringSeq& args, ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); + + /** + * run is given a copy of the remaining argc/argv arguments, + * after the communicator initialization in the caller (main) + * has removed all Ice-related arguments. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @return The application's exit status. + */ + virtual int run(int argc, char* argv[]) = 0; + + /** + * Override this method to provide a custom application interrupt + * hook. You must call callbackOnInterrupt for this method to + * be called. Note that the interruptCallback can be called + * concurrently with any other thread (including main) in your + * application and thus must take appropriate concurrency + * precautions. + * @param signal The signal identifier. + */ + virtual void interruptCallback(int signal); + + /** + * Obtains the application name, i.e., argv[0]. + * @return The application's name. + */ + static const char* appName(); + + /** + * Obtains the application's Communicator instance. + * One limitation of this class is that there can only be one + * Application instance, with one global Communicator, accessible + * with this communicator() operation. This limitation is due to + * how the signal handling functions below operate. If you require + * multiple Communicators, then you cannot use this Application + * framework class. + * @return The application's communicator. + */ + static CommunicatorPtr communicator(); + + /** + * Configures the application to destroy the communicator when one of the + * monitored signals is raised. This is the default behavior. + */ + static void destroyOnInterrupt(); + + /** + * Configures the application to shut down the communicator when one of the + * monitored signals is raised. + */ + static void shutdownOnInterrupt(); + + /** + * Configures the application to ignore signals. + */ + static void ignoreInterrupt(); + + /** + * Configures the application to invoke interruptCallback when a signal occurs, + * thereby giving the subclass responsibility for handling the signal. + */ + static void callbackOnInterrupt(); + + /** + * Configures the application to ignore (but remember) a signal. + * A stored signal (if any) can be handled later by calling releaseInterrupt. + */ + static void holdInterrupt(); + + /** + * Processes a stored signal (if any) using the current signal handling configuration. + */ + static void releaseInterrupt(); + + /** + * Indicates whether a signal handler was triggered. + * This can be used once Communicator::waitForShutdown() returns to + * test whether the shutdown was due to an interrupt (returns true) + * or because Communicator::shutdown() was called (returns false). + * @return True if a signal handler was triggered, false otherwise. + */ + static bool interrupted(); + +protected: + + /** + * Helper function that implements the application logic. + */ + virtual int doMain(int, char*[], const InitializationData&, Int); + + /** + * Used to synchronize the main thread and the CtrlCHandler thread. + */ + static IceUtil::Mutex _mutex; + + /** + * Used to synchronize the main thread and the CtrlCHandler thread. + */ + static IceUtil::Cond _condVar; + + /** + * True if a signal handling callback is currently executing. + * Can change while run() and communicator->destroy() are running! + */ + static bool _callbackInProgress; + + /** + * True if the communicator has been destroyed. + * Can change while run() and communicator->destroy() are running! + */ + static bool _destroyed; + + /** + * True if an interrupt signal was received. + * Can change while run() and communicator->destroy() are running! + */ + static bool _interrupted; + + /** + * The application's name. + * Immutable during run() and until communicator->destroy() has returned. + * Before and after run(), and once communicator->destroy() has returned, + * we assume that only the main thread and CtrlCHandler threads are running. + */ + static std::string _appName; + + /** + * The application's communicator. + * Immutable during run() and until communicator->destroy() has returned. + * Before and after run(), and once communicator->destroy() has returned, + * we assume that only the main thread and CtrlCHandler threads are running. + */ + static CommunicatorPtr _communicator; + + /** + * The signal-handling policy specified at construction. + * Immutable during run() and until communicator->destroy() has returned. + * Before and after run(), and once communicator->destroy() has returned, + * we assume that only the main thread and CtrlCHandler threads are running. + */ + static SignalPolicy _signalPolicy; + + /** + * The singleton instance. + * Immutable during run() and until communicator->destroy() has returned. + * Before and after run(), and once communicator->destroy() has returned, + * we assume that only the main thread and CtrlCHandler threads are running. + */ + static Application* _application; + +private: + + static void holdInterruptCallback(int); + static void destroyOnInterruptCallback(int); + static void shutdownOnInterruptCallback(int); + static void callbackOnInterruptCallback(int); + +#ifndef ICE_CPP11_MAPPING + // + // Not defined, make Application non-copyable + // + Application(const Application&); + Application& operator=(const Application&); +#endif + +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ArgVector.h b/Sources/IceCpp/include/Ice/ArgVector.h new file mode 100644 index 0000000..095856c --- /dev/null +++ b/Sources/IceCpp/include/Ice/ArgVector.h @@ -0,0 +1,36 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ARGVECTOR_H +#define ICE_ARGVECTOR_H + +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API ArgVector +{ +public: + + ArgVector(int argc, const char* const argv[]); + ArgVector(const ::std::vector< ::std::string>&); + ArgVector(const ArgVector&); + ArgVector& operator=(const ArgVector&); + ~ArgVector(); + + int argc; + char** argv; + +private: + + ::std::vector< ::std::string> _args; + void setupArgcArgv(); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/AsyncResult.h b/Sources/IceCpp/include/Ice/AsyncResult.h new file mode 100644 index 0000000..672ef1a --- /dev/null +++ b/Sources/IceCpp/include/Ice/AsyncResult.h @@ -0,0 +1,155 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ASYNC_RESULT_H +#define ICE_ASYNC_RESULT_H + +#ifndef ICE_CPP11_MAPPING + +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +/** + * Represents the result of an asynchronous invocation using the C++98 mapping. + * \headerfile Ice/Ice.h + */ +class ICE_API AsyncResult : private IceUtil::noncopyable, public Ice::LocalObject +{ +public: + + virtual ~AsyncResult(); + + /** + * Prevents a queued invocation from being sent or, if the invocation has already been sent, + * ignores a reply if the server sends one. cancel is a local operation and has no effect + * on the server. A canceled invocation is considered to be completed, meaning isCompleted + * returns true, and the result of the invocation is an InvocationCanceledException. + */ + virtual void cancel() = 0; + + /** + * Allows you to create ordered or hashed collections of pending asynchronous invocations. + * @return A unique hash code for this object. + */ + virtual Int getHash() const = 0; + + /** + * Obtains the communicator that sent the invocation. + * @return A reference to the communicator. + */ + virtual CommunicatorPtr getCommunicator() const = 0; + + /** + * Obtains the connection that was used for the invocation. Note that, for typical asynchronous + * proxy invocations, this method returns a nil value because the possibility of automatic retries + * means the connection that is currently in use could change unexpectedly. The getConnection + * method only returns a non-nil value when the AsyncResult object is obtained by calling + * Connection::begin_flushBatchRequests. + * @return A reference to the connection. + */ + virtual ConnectionPtr getConnection() const = 0; + + /** + * Obtains the proxy that was used to call the begin_ method, or nil if the AsyncResult object was + * not obtained via an asynchronous proxy invocation. + * @return A reference to the proxy. + */ + virtual ObjectPrxPtr getProxy() const = 0; + + /** + * Obtains the completion status of the invocation. + * @return True if, at the time it is called, the result of an invocation is available, indicating + * that a call to the end_ method will not block the caller. Otherwise, if the result is not yet + * available, the method returns false. + */ + virtual bool isCompleted() const = 0; + + /** + * Blocks the caller until the result of an invocation becomes available. + */ + virtual void waitForCompleted() = 0; + + /** + * Obtains the sent status of the invocation. + * @return True if, at the time it is called, the request has been written to the local transport + * (whether it was initially queued or not). Otherwise, if the request is still queued or an + * exception occurred before the request could be sent, this method returns false. + */ + virtual bool isSent() const = 0; + + /** + * Blocks the calling thread until a request has been written to the client-side transport, + * or an exception occurs. + */ + virtual void waitForSent() = 0; + + /** + * Throws the local exception that caused the invocation to fail. If no exception has occurred yet, + * this method does nothing. + */ + virtual void throwLocalException() const = 0; + + /** + * Determines whether the request was sent synchronously. + * @return True if a request was written to the client-side transport without first being queued. + * If the request was initially queued, sentSynchronously returns false (independent of whether + * the request is still in the queue or has since been written to the client-side transport). + */ + virtual bool sentSynchronously() const = 0; + + /** + * Obtains the cookie that was passed to the begin_ method. + * @return The cookie, or nil if you did not pass a cookie to the begin_ method. + */ + virtual LocalObjectPtr getCookie() const = 0; + + /** + * Obtains the name of the operation. + * @return The operation name. + */ + virtual const std::string& getOperation() const = 0; + + /// \cond INTERNAL + virtual bool _waitForResponse() = 0; + virtual Ice::InputStream* _startReadParams() = 0; + virtual void _endReadParams() = 0; + virtual void _readEmptyParams() = 0; + virtual void _readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&) = 0; + virtual void _throwUserException() = 0; + + static void _check(const AsyncResultPtr&, const ::IceProxy::Ice::Object*, const ::std::string&); + static void _check(const AsyncResultPtr&, const Connection*, const ::std::string&); + static void _check(const AsyncResultPtr&, const Communicator*, const ::std::string&); + + class Callback : public IceUtil::Shared + { + public: + + virtual void run() = 0; + }; + typedef IceUtil::Handle CallbackPtr; + + virtual void _scheduleCallback(const CallbackPtr&) = 0; + /// \endcond + +protected: + + /// \cond INTERNAL + static void check(const AsyncResultPtr&, const ::std::string&); + /// \endcond +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/AsyncResultF.h b/Sources/IceCpp/include/Ice/AsyncResultF.h new file mode 100644 index 0000000..79feb96 --- /dev/null +++ b/Sources/IceCpp/include/Ice/AsyncResultF.h @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ASYNC_RESULT_F_H +#define ICE_ASYNC_RESULT_F_H + +#ifndef ICE_CPP11_MAPPING + +#include +#include + +namespace Ice +{ + +class AsyncResult; +ICE_API IceUtil::Shared* upCast(::Ice::AsyncResult*); +typedef IceInternal::Handle AsyncResultPtr; + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/Base64.h b/Sources/IceCpp/include/Ice/Base64.h new file mode 100644 index 0000000..ca898c5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Base64.h @@ -0,0 +1,31 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_BASE_64_H +#define ICE_BASE_64_H + +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API Base64 +{ +public: + + static std::string encode(const std::vector&); + static std::vector decode(const std::string&); + static bool isBase64(char); + +private: + + static char encode(unsigned char); + static unsigned char decode(char); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/BatchRequestInterceptor.h b/Sources/IceCpp/include/Ice/BatchRequestInterceptor.h new file mode 100644 index 0000000..a65fbef --- /dev/null +++ b/Sources/IceCpp/include/Ice/BatchRequestInterceptor.h @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_BATCH_REQUEST_INTERCEPTOR_H +#define ICE_BATCH_REQUEST_INTERCEPTOR_H + +#include +#include + +namespace Ice +{ + +/** + * Represents an invocation on a proxy configured for batch-oneway or batch-datagram. + * \headerfile Ice/Ice.h + */ +class BatchRequest +{ +public: + + virtual ~BatchRequest() + { + } + + /** + * Queues the request for an eventual flush. + */ + virtual void enqueue() const = 0; + + /** + * Obtains the size of the request. + * @return The number of bytes consumed by the request. + */ + virtual int getSize() const = 0; + + /** + * Obtains the name of the operation. + * @return The operation name. + */ + virtual const std::string& getOperation() const = 0; + + /** + * Obtains the proxy on which the batch request was invoked. + * @return The originating proxy. + */ + virtual const Ice::ObjectPrxPtr& getProxy() const = 0; +}; + +#ifndef ICE_CPP11_MAPPING + +/** + * The base class for a batch request interceptor. Subclasses must implement enqueue. + * The interceptor can be installed via InitializationData. + * \headerfile Ice/Ice.h + */ +class BatchRequestInterceptor : public IceUtil::Shared +{ +public: + + /** + * Called by the Ice run time to enqueue a batch request. + * @param req An object representing the batch request. + * @param count The number of requests currently in the queue. + * @param size The number of bytes consumed by the requests currently in the queue. + */ + virtual void enqueue(const BatchRequest& req, int count, int size) = 0; +}; +typedef IceUtil::Handle BatchRequestInterceptorPtr; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/BatchRequestQueue.h b/Sources/IceCpp/include/Ice/BatchRequestQueue.h new file mode 100644 index 0000000..5ef6921 --- /dev/null +++ b/Sources/IceCpp/include/Ice/BatchRequestQueue.h @@ -0,0 +1,59 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_BATCH_REQUEST_QUEUE_H +#define ICE_BATCH_REQUEST_QUEUE_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace IceInternal +{ + +class BatchRequestQueue : public IceUtil::Shared, private IceUtil::Monitor +{ +public: + + BatchRequestQueue(const InstancePtr&, bool); + + void prepareBatchRequest(Ice::OutputStream*); + void finishBatchRequest(Ice::OutputStream*, const Ice::ObjectPrxPtr&, const std::string&); + void abortBatchRequest(Ice::OutputStream*); + + int swap(Ice::OutputStream*, bool&); + + void destroy(const Ice::LocalException&); + bool isEmpty(); + + void enqueueBatchRequest(const Ice::ObjectPrxPtr&); + +private: + + void waitStreamInUse(bool); + +#ifdef ICE_CPP11_MAPPING + std::function _interceptor; +#else + Ice::BatchRequestInterceptorPtr _interceptor; +#endif + Ice::OutputStream _batchStream; + bool _batchStreamInUse; + bool _batchStreamCanFlush; + bool _batchCompress; + int _batchRequestNum; + size_t _batchMarker; + IceInternal::UniquePtr _exception; + size_t _maxSize; +}; + +}; + +#endif diff --git a/Sources/IceCpp/include/Ice/BatchRequestQueueF.h b/Sources/IceCpp/include/Ice/BatchRequestQueueF.h new file mode 100644 index 0000000..fb91acf --- /dev/null +++ b/Sources/IceCpp/include/Ice/BatchRequestQueueF.h @@ -0,0 +1,20 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_BATCH_REQUEST_QUEUE_F_H +#define ICE_BATCH_REQUEST_QUEUE_F_H + +#include +#include + +namespace IceInternal +{ + +class BatchRequestQueue; +ICE_API IceUtil::Shared* upCast(BatchRequestQueue*); +typedef IceInternal::Handle BatchRequestQueuePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Buffer.h b/Sources/IceCpp/include/Ice/Buffer.h new file mode 100644 index 0000000..5ac50dc --- /dev/null +++ b/Sources/IceCpp/include/Ice/Buffer.h @@ -0,0 +1,154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_BUFFER_H +#define ICE_BUFFER_H + +#include + +namespace IceInternal +{ + +class ICE_API Buffer : private IceUtil::noncopyable +{ +public: + + Buffer() : i(b.begin()) { } + Buffer(const Ice::Byte* beg, const Ice::Byte* end) : b(beg, end), i(b.begin()) { } + Buffer(const std::vector& v) : b(v), i(b.begin()) { } + Buffer(Buffer& o, bool adopt) : b(o.b, adopt), i(b.begin()) { } + + void swapBuffer(Buffer&); + + class ICE_API Container : private IceUtil::noncopyable + { + public: + + // + // Standard vector-like operations. + // + + typedef Ice::Byte value_type; + typedef Ice::Byte* iterator; + typedef const Ice::Byte* const_iterator; + typedef Ice::Byte& reference; + typedef const Ice::Byte& const_reference; + typedef Ice::Byte* pointer; + typedef size_t size_type; + + Container(); + Container(const_iterator, const_iterator); + Container(const std::vector&); + Container(Container&, bool); + + ~Container(); + + iterator begin() + { + return _buf; + } + + const_iterator begin() const + { + return _buf; + } + + iterator end() + { + return _buf + _size; + } + + const_iterator end() const + { + return _buf + _size; + } + + size_type size() const + { + return _size; + } + + bool empty() const + { + return !_size; + } + + void swap(Container&); + + void clear(); + + void resize(size_type n) // Inlined for performance reasons. + { + if(n == 0) + { + clear(); + } + else if(n > _capacity) + { + reserve(n); + } + _size = n; + } + + void reset() + { + if(_size > 0 && _size * 2 < _capacity) + { + // + // If the current buffer size is smaller than the + // buffer capacity, we shrink the buffer memory to the + // current size. This is to avoid holding onto too much + // memory if it's not needed anymore. + // + if(++_shrinkCounter > 2) + { + reserve(_size); + _shrinkCounter = 0; + } + } + else + { + _shrinkCounter = 0; + } + _size = 0; + } + + void push_back(value_type v) + { + resize(_size + 1); + _buf[_size - 1] = v; + } + + reference operator[](size_type n) + { + assert(n < _size); + return _buf[n]; + } + + const_reference operator[](size_type n) const + { + assert(n < _size); + return _buf[n]; + } + + private: + + Container(const Container&); + void operator=(const Container&); + void reserve(size_type); + + pointer _buf; + size_type _size; + size_type _capacity; + int _shrinkCounter; + bool _owned; + }; + + Container b; + Container::iterator i; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/BuiltinSequences.h b/Sources/IceCpp/include/Ice/BuiltinSequences.h new file mode 100644 index 0000000..d2f5ff4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/BuiltinSequences.h @@ -0,0 +1,170 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `BuiltinSequences.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_BuiltinSequences_h__ +#define __Ice_BuiltinSequences_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * A sequence of bools. + */ +using BoolSeq = ::std::vector; + +/** + * A sequence of bytes. + */ +using ByteSeq = ::std::vector; + +/** + * A sequence of shorts. + */ +using ShortSeq = ::std::vector; + +/** + * A sequence of ints. + */ +using IntSeq = ::std::vector; + +/** + * A sequence of longs. + */ +using LongSeq = ::std::vector; + +/** + * A sequence of floats. + */ +using FloatSeq = ::std::vector; + +/** + * A sequence of doubles. + */ +using DoubleSeq = ::std::vector; + +/** + * A sequence of strings. + */ +using StringSeq = ::std::vector<::std::string>; + +/** + * A sequence of objects. + */ +using ObjectSeq = ::std::vector<::std::shared_ptr>; + +/** + * A sequence of object proxies. + */ +using ObjectProxySeq = ::std::vector<::std::shared_ptr>; + +} + +#else // C++98 mapping + +namespace Ice +{ + +/** + * A sequence of bools. + */ +typedef ::std::vector BoolSeq; + +/** + * A sequence of bytes. + */ +typedef ::std::vector ByteSeq; + +/** + * A sequence of shorts. + */ +typedef ::std::vector ShortSeq; + +/** + * A sequence of ints. + */ +typedef ::std::vector IntSeq; + +/** + * A sequence of longs. + */ +typedef ::std::vector LongSeq; + +/** + * A sequence of floats. + */ +typedef ::std::vector FloatSeq; + +/** + * A sequence of doubles. + */ +typedef ::std::vector DoubleSeq; + +/** + * A sequence of strings. + */ +typedef ::std::vector< ::std::string> StringSeq; + +/** + * A sequence of objects. + */ +typedef ::std::vector ObjectSeq; + +/** + * A sequence of object proxies. + */ +typedef ::std::vector ObjectProxySeq; + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/CollocatedRequestHandler.h b/Sources/IceCpp/include/Ice/CollocatedRequestHandler.h new file mode 100644 index 0000000..d0ac16d --- /dev/null +++ b/Sources/IceCpp/include/Ice/CollocatedRequestHandler.h @@ -0,0 +1,87 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_COLLOCATED_REQUEST_HANDLER_H +#define ICE_COLLOCATED_REQUEST_HANDLER_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class ObjectAdapterI; +ICE_DEFINE_PTR(ObjectAdapterIPtr, ObjectAdapterI); + +} + +namespace IceInternal +{ + +class OutgoingAsyncBase; +class OutgoingAsync; + +class CollocatedRequestHandler : public RequestHandler, + public ResponseHandler, + private IceUtil::Monitor +{ +public: + + CollocatedRequestHandler(const ReferencePtr&, const Ice::ObjectAdapterPtr&); + virtual ~CollocatedRequestHandler(); + + virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); + + virtual AsyncStatus sendAsyncRequest(const ProxyOutgoingAsyncBasePtr&); + + virtual void asyncRequestCanceled(const OutgoingAsyncBasePtr&, const Ice::LocalException&); + + virtual void sendResponse(Ice::Int, Ice::OutputStream*, Ice::Byte, bool); + virtual void sendNoResponse(); + virtual bool systemException(Ice::Int, const Ice::SystemException&, bool); + virtual void invokeException(Ice::Int, const Ice::LocalException&, int, bool); + + const ReferencePtr& getReference() const { return _reference; } // Inlined for performances. + + virtual Ice::ConnectionIPtr getConnection(); + virtual Ice::ConnectionIPtr waitForConnection(); + + AsyncStatus invokeAsyncRequest(OutgoingAsyncBase*, int, bool); + + bool sentAsync(OutgoingAsyncBase*); + + void invokeAll(Ice::OutputStream*, Ice::Int, Ice::Int); + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(ResponseHandler::shared_from_this()); + } +#endif + +private: + + void handleException(Ice::Int, const Ice::Exception&, bool); + + const Ice::ObjectAdapterIPtr _adapter; + const bool _dispatcher; + const Ice::LoggerPtr _logger; + const TraceLevelsPtr _traceLevels; + + int _requestId; + std::map _sendAsyncRequests; + std::map _asyncRequests; +}; +ICE_DEFINE_PTR(CollocatedRequestHandlerPtr, CollocatedRequestHandler); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Communicator.h b/Sources/IceCpp/include/Ice/Communicator.h new file mode 100644 index 0000000..2f5fd3a --- /dev/null +++ b/Sources/IceCpp/include/Ice/Communicator.h @@ -0,0 +1,1190 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Communicator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Communicator_h__ +#define __Ice_Communicator_h__ + +#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 + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Communicator; + +} + +namespace Ice +{ + +/** + * The output mode for xxxToString method such as identityToString and proxyToString. + * The actual encoding format for the string is the same for all modes: you + * don't need to specify an encoding format or mode when reading such a string. + */ +enum class ToStringMode : unsigned char +{ + /** + * Characters with ordinal values greater than 127 are kept as-is in the resulting string. + * Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + * or \\unnnn. + */ + Unicode, + /** + * Characters with ordinal values greater than 127 are encoded as universal character names in + * the resulting string: \\unnnn for BMP characters and \\Unnnnnnnn for non-BMP characters. + * Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + * or \\unnnn. + */ + ASCII, + /** + * Characters with ordinal values greater than 127 are encoded as a sequence of UTF-8 bytes using + * octal escapes. Characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) or + * an octal escape. Use this mode to generate strings compatible with Ice 3.6 and earlier. + */ + Compat +}; + +} + +namespace Ice +{ + +/** + * The central object in Ice. One or more communicators can be + * instantiated for an Ice application. Communicator instantiation + * is language-specific, and not specified in Slice code. + * @see Logger + * @see ObjectAdapter + * @see Properties + * @see ValueFactory + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Communicator +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Communicator(); + + /** + * Destroy the communicator. This operation calls {@link #shutdown} + * implicitly. Calling {@link #destroy} cleans up memory, and shuts down + * this communicator's client functionality and destroys all object + * adapters. Subsequent calls to {@link #destroy} are ignored. + * @see #shutdown + * @see ObjectAdapter#destroy + */ + virtual void destroy() noexcept = 0; + + /** + * Shuts down this communicator's server functionality, which + * includes the deactivation of all object adapters. Attempts to use a + * deactivated object adapter raise ObjectAdapterDeactivatedException. + * Subsequent calls to shutdown are ignored. + * + * After shutdown returns, no new requests are processed. However, requests + * that have been started before shutdown was called might still be active. + * You can use {@link #waitForShutdown} to wait for the completion of all + * requests. + * @see #destroy + * @see #waitForShutdown + * @see ObjectAdapter#deactivate + */ + virtual void shutdown() noexcept = 0; + + /** + * Wait until the application has called {@link #shutdown} (or {@link #destroy}). + * On the server side, this operation blocks the calling thread + * until all currently-executing operations have completed. + * On the client side, the operation simply blocks until another + * thread has called {@link #shutdown} or {@link #destroy}. + * + * A typical use of this operation is to call it from the main thread, + * which then waits until some other thread calls {@link #shutdown}. + * After shut-down is complete, the main thread returns and can do some + * cleanup work before it finally calls {@link #destroy} to shut down + * the client functionality, and then exits the application. + * @see #shutdown + * @see #destroy + * @see ObjectAdapter#waitForDeactivate + */ + virtual void waitForShutdown() noexcept = 0; + + /** + * Check whether communicator has been shut down. + * @return True if the communicator has been shut down; false otherwise. + * @see #shutdown + */ + virtual bool isShutdown() const noexcept = 0; + + /** + * Convert a stringified proxy into a proxy. For example, + * MyCategory/MyObject:tcp -h some_host -p + * 10000 creates a proxy that refers to the Ice object + * having an identity with a name "MyObject" and a category + * "MyCategory", with the server running on host "some_host", port + * 10000. If the stringified proxy does not parse correctly, the + * operation throws one of ProxyParseException, EndpointParseException, + * or IdentityParseException. Refer to the Ice manual for a detailed + * description of the syntax supported by stringified proxies. + * @param str The stringified proxy to convert into a proxy. + * @return The proxy, or nil if str is an empty string. + * @see #proxyToString + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> stringToProxy(const ::std::string& str) const = 0; + + /** + * Convert a proxy into a string. + * @param obj The proxy to convert into a stringified proxy. + * @return The stringified proxy, or an empty string if + * obj is nil. + * @see #stringToProxy + */ + virtual ::std::string proxyToString(const ::std::shared_ptr& obj) const = 0; + + /** + * Convert a set of proxy properties into a proxy. The "base" + * name supplied in the property argument refers to a + * property containing a stringified proxy, such as + * MyProxy=id:tcp -h localhost -p 10000. Additional + * properties configure local settings for the proxy, such as + * MyProxy.PreferSecure=1. The "Properties" + * appendix in the Ice manual describes each of the supported + * proxy properties. + * @param property The base property name. + * @return The proxy. + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> propertyToProxy(const ::std::string& property) const = 0; + + /** + * Convert a proxy to a set of proxy properties. + * @param proxy The proxy. + * @param property The base property name. + * @return The property set. + */ + virtual ::Ice::PropertyDict proxyToProperty(const ::std::shared_ptr& proxy, const ::std::string& property) const = 0; + + /** + * Convert a string into an identity. If the string does not parse + * correctly, the operation throws IdentityParseException. + * @param str The string to convert into an identity. + * @return The identity. + * @see #identityToString + * + * @deprecated stringToIdentity() is deprecated, use the static stringToIdentity() method instead. + */ + ICE_DEPRECATED_API("stringToIdentity() is deprecated, use the static stringToIdentity() method instead.") virtual ::Ice::Identity stringToIdentity(const ::std::string& str) const = 0; + + /** + * Convert an identity into a string. + * @param ident The identity to convert into a string. + * @return The "stringified" identity. + * @see #stringToIdentity + */ + virtual ::std::string identityToString(const Identity& ident) const = 0; + + /** + * Create a new object adapter. The endpoints for the object + * adapter are taken from the property name.Endpoints. + * + * It is legal to create an object adapter with the empty string as + * its name. Such an object adapter is accessible via bidirectional + * connections or by collocated invocations that originate from the + * same communicator as is used by the adapter. + * + * Attempts to create a named object adapter for which no configuration + * can be found raise InitializationException. + * @param name The object adapter name. + * @return The new object adapter. + * @see #createObjectAdapterWithEndpoints + * @see ObjectAdapter + * @see Properties + */ + virtual ::std::shared_ptr<::Ice::ObjectAdapter> createObjectAdapter(const ::std::string& name) = 0; + + /** + * Create a new object adapter with endpoints. This operation sets + * the property name.Endpoints, and then calls + * {@link #createObjectAdapter}. It is provided as a convenience + * function. + * + * Calling this operation with an empty name will result in a + * UUID being generated for the name. + * @param name The object adapter name. + * @param endpoints The endpoints for the object adapter. + * @return The new object adapter. + * @see #createObjectAdapter + * @see ObjectAdapter + * @see Properties + */ + virtual ::std::shared_ptr<::Ice::ObjectAdapter> createObjectAdapterWithEndpoints(const ::std::string& name, const ::std::string& endpoints) = 0; + + /** + * Create a new object adapter with a router. This operation + * creates a routed object adapter. + * + * Calling this operation with an empty name will result in a + * UUID being generated for the name. + * @param name The object adapter name. + * @param rtr The router. + * @return The new object adapter. + * @see #createObjectAdapter + * @see ObjectAdapter + * @see Properties + */ + virtual ::std::shared_ptr<::Ice::ObjectAdapter> createObjectAdapterWithRouter(const ::std::string& name, const ::std::shared_ptr& rtr) = 0; + + /** + * Add an object factory to this communicator. Installing a + * factory with an id for which a factory is already registered + * throws AlreadyRegisteredException. + * + * When unmarshaling an Ice object, the Ice run time reads the + * most-derived type id off the wire and attempts to create an + * instance of the type using a factory. If no instance is created, + * either because no factory was found, or because all factories + * returned nil, the behavior of the Ice run time depends on the + * format with which the object was marshaled: + * + * If the object uses the "sliced" format, Ice ascends the class + * hierarchy until it finds a type that is recognized by a factory, + * or it reaches the least-derived type. If no factory is found that + * can create an instance, the run time throws NoValueFactoryException. + * + * If the object uses the "compact" format, Ice immediately raises + * NoValueFactoryException. + * + * The following order is used to locate a factory for a type: + * + *
    + * + *
  1. The Ice run-time looks for a factory registered + * specifically for the type.
  2. + * + *
  3. If no instance has been created, the Ice run-time looks + * for the default factory, which is registered with an empty type id. + *
  4. + * + *
  5. If no instance has been created by any of the preceding + * steps, the Ice run-time looks for a factory that may have been + * statically generated by the language mapping for non-abstract classes. + *
  6. + * + *
+ * @param factory The factory to add. + * @param id The type id for which the factory can create instances, or + * an empty string for the default factory. + * @see #findObjectFactory + * @see ObjectFactory + * @see ValueFactoryManager#add + * + * @deprecated addObjectFactory() is deprecated, use ValueFactoryManager::add() instead. + */ + ICE_DEPRECATED_API("addObjectFactory() is deprecated, use ValueFactoryManager::add() instead.") virtual void addObjectFactory(const ::std::shared_ptr& factory, const ::std::string& id) = 0; + + /** + * Find an object factory registered with this communicator. + * @param id The type id for which the factory can create instances, + * or an empty string for the default factory. + * @return The object factory, or null if no object factory was + * found for the given id. + * @see #addObjectFactory + * @see ObjectFactory + * @see ValueFactoryManager#find + * + * @deprecated findObjectFactory() is deprecated, use ValueFactoryManager::find() instead. + */ + ICE_DEPRECATED_API("findObjectFactory() is deprecated, use ValueFactoryManager::find() instead.") virtual ::std::shared_ptr<::Ice::ObjectFactory> findObjectFactory(const ::std::string& id) const noexcept = 0; + + /** + * Get the implicit context associated with this communicator. + * @return The implicit context associated with this communicator; + * returns null when the property Ice.ImplicitContext is not set + * or is set to None. + */ + virtual ::std::shared_ptr<::Ice::ImplicitContext> getImplicitContext() const noexcept = 0; + + /** + * Get the properties for this communicator. + * @return This communicator's properties. + * @see Properties + */ + virtual ::std::shared_ptr<::Ice::Properties> getProperties() const noexcept = 0; + + /** + * Get the logger for this communicator. + * @return This communicator's logger. + * @see Logger + */ + virtual ::std::shared_ptr<::Ice::Logger> getLogger() const noexcept = 0; + + /** + * Get the observer resolver object for this communicator. + * @return This communicator's observer resolver object. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::CommunicatorObserver> getObserver() const noexcept = 0; + + /** + * Get the default router this communicator. + * @return The default router for this communicator. + * @see #setDefaultRouter + * @see Router + */ + virtual ::std::shared_ptr<::Ice::RouterPrx> getDefaultRouter() const = 0; + + /** + * Set a default router for this communicator. All newly + * created proxies will use this default router. To disable the + * default router, null can be used. Note that this + * operation has no effect on existing proxies. + * + * You can also set a router for an individual proxy + * by calling the operation ice_router on the proxy. + * @param rtr The default router to use for this communicator. + * @see #getDefaultRouter + * @see #createObjectAdapterWithRouter + * @see Router + */ + virtual void setDefaultRouter(const ::std::shared_ptr& rtr) = 0; + + /** + * Get the default locator this communicator. + * @return The default locator for this communicator. + * @see #setDefaultLocator + * @see Locator + */ + virtual ::std::shared_ptr<::Ice::LocatorPrx> getDefaultLocator() const = 0; + + /** + * Set a default Ice locator for this communicator. All newly + * created proxy and object adapters will use this default + * locator. To disable the default locator, null can be used. + * Note that this operation has no effect on existing proxies or + * object adapters. + * + * You can also set a locator for an individual proxy by calling the + * operation ice_locator on the proxy, or for an object adapter + * by calling {@link ObjectAdapter#setLocator} on the object adapter. + * @param loc The default locator to use for this communicator. + * @see #getDefaultLocator + * @see Locator + * @see ObjectAdapter#setLocator + */ + virtual void setDefaultLocator(const ::std::shared_ptr& loc) = 0; + + /** + * Get the plug-in manager for this communicator. + * @return This communicator's plug-in manager. + * @see PluginManager + */ + virtual ::std::shared_ptr<::Ice::PluginManager> getPluginManager() const = 0; + + /** + * Get the value factory manager for this communicator. + * @return This communicator's value factory manager. + * @see ValueFactoryManager + */ + virtual ::std::shared_ptr<::Ice::ValueFactoryManager> getValueFactoryManager() const noexcept = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + */ + virtual void flushBatchRequests(CompressBatch compress) + { + flushBatchRequestsAsync(compress).get(); + } + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param exception The exception callback. + * @param sent The sent callback. + * @return A function that can be called to cancel the invocation locally. + */ + virtual ::std::function + flushBatchRequestsAsync(CompressBatch compress, + ::std::function exception, + ::std::function sent = nullptr) = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto flushBatchRequestsAsync(CompressBatch compress) + -> decltype(::std::declval>().get_future()) + { + using Promise = P; + auto promise = ::std::make_shared(); + flushBatchRequestsAsync(compress, + [promise](::std::exception_ptr ex) + { + promise->set_exception(::std::move(ex)); + }, + [promise](bool) + { + promise->set_value(); + }); + return promise->get_future(); + } + + /** + * Add the Admin object with all its facets to the provided object adapter. + * If Ice.Admin.ServerId is set and the provided object adapter has a {@link Locator}, + * createAdmin registers the Admin's Process facet with the {@link Locator}'s {@link LocatorRegistry}. + * + * createAdmin must only be called once; subsequent calls raise InitializationException. + * @param adminAdapter The object adapter used to host the Admin object; if null and + * Ice.Admin.Endpoints is set, create, activate and use the Ice.Admin object adapter. + * @param adminId The identity of the Admin object. + * @return A proxy to the main ("") facet of the Admin object. Never returns a null proxy. + * @see #getAdmin + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> createAdmin(const ::std::shared_ptr& adminAdapter, const Identity& adminId) = 0; + + /** + * Get a proxy to the main facet of the Admin object. + * + * getAdmin also creates the Admin object and creates and activates the Ice.Admin object + * adapter to host this Admin object if Ice.Admin.Enpoints is set. The identity of the Admin + * object created by getAdmin is {value of Ice.Admin.InstanceName}/admin, or {UUID}/admin + * when Ice.Admin.InstanceName is not set. + * + * If Ice.Admin.DelayCreation is 0 or not set, getAdmin is called by the communicator + * initialization, after initialization of all plugins. + * @return A proxy to the main ("") facet of the Admin object, or a null proxy if no + * Admin object is configured. + * @see #createAdmin + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> getAdmin() const = 0; + + /** + * Add a new facet to the Admin object. + * Adding a servant with a facet that is already registered + * throws AlreadyRegisteredException. + * @param servant The servant that implements the new Admin facet. + * @param facet The name of the new Admin facet. + */ + virtual void addAdminFacet(const ::std::shared_ptr& servant, const ::std::string& facet) = 0; + + /** + * Remove the following facet to the Admin object. + * Removing a facet that was not previously registered throws + * NotRegisteredException. + * @param facet The name of the Admin facet. + * @return The servant associated with this Admin facet. + */ + virtual ::std::shared_ptr<::Ice::Object> removeAdminFacet(const ::std::string& facet) = 0; + + /** + * Returns a facet of the Admin object. + * @param facet The name of the Admin facet. + * @return The servant associated with this Admin facet, or + * null if no facet is registered with the given name. + */ + virtual ::std::shared_ptr<::Ice::Object> findAdminFacet(const ::std::string& facet) = 0; + + /** + * Returns a map of all facets of the Admin object. + * @return A collection containing all the facet names and + * servants of the Admin object. + * @see #findAdminFacet + */ + virtual ::Ice::FacetMap findAllAdminFacets() = 0; + + /** + * Returns the client dispatch queue. + * @return The dispatch queue associated wih this Communicator's + * client thread pool. + */ + virtual dispatch_queue_t getClientDispatchQueue() const = 0; + + /** + * Returns the server dispatch queue. + * @return The dispatch queue associated wih the Communicator's + * server thread pool. + */ + virtual dispatch_queue_t getServerDispatchQueue() const = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using CommunicatorPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +} + +namespace Ice +{ + +class Communicator; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Communicator*); +/// \endcond +typedef ::IceInternal::Handle< Communicator> CommunicatorPtr; + +} + +namespace Ice +{ + +/** + * The output mode for xxxToString method such as identityToString and proxyToString. + * The actual encoding format for the string is the same for all modes: you + * don't need to specify an encoding format or mode when reading such a string. + */ +enum ToStringMode +{ + /** + * Characters with ordinal values greater than 127 are kept as-is in the resulting string. + * Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + * or \\unnnn. + */ + Unicode, + /** + * Characters with ordinal values greater than 127 are encoded as universal character names in + * the resulting string: \\unnnn for BMP characters and \\Unnnnnnnn for non-BMP characters. + * Non-printable ASCII characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) + * or \\unnnn. + */ + ASCII, + /** + * Characters with ordinal values greater than 127 are encoded as a sequence of UTF-8 bytes using + * octal escapes. Characters with ordinal values 127 and below are encoded as \\t, \\n (etc.) or + * an octal escape. Use this mode to generate strings compatible with Ice 3.6 and earlier. + */ + Compat +}; + +} + +/// \cond INTERNAL +namespace IceAsync +{ + +} +/// \endcond + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Communicator::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Communicator_flushBatchRequests. + */ +class Callback_Communicator_flushBatchRequests_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Communicator_flushBatchRequests_Base> Callback_Communicator_flushBatchRequestsPtr; + +} + +namespace IceProxy +{ + +} + +namespace Ice +{ + +/** + * The central object in Ice. One or more communicators can be + * instantiated for an Ice application. Communicator instantiation + * is language-specific, and not specified in Slice code. + * @see Logger + * @see ObjectAdapter + * @see Properties + * @see ValueFactory + * \headerfile Ice/Ice.h + */ +class ICE_API Communicator : public virtual LocalObject +{ +public: + + typedef CommunicatorPtr PointerType; + + virtual ~Communicator(); + +#ifdef ICE_CPP11_COMPILER + Communicator() = default; + Communicator(const Communicator&) = default; + Communicator& operator=(const Communicator&) = default; +#endif + + /** + * Destroy the communicator. This operation calls {@link #shutdown} + * implicitly. Calling {@link #destroy} cleans up memory, and shuts down + * this communicator's client functionality and destroys all object + * adapters. Subsequent calls to {@link #destroy} are ignored. + * @see #shutdown + * @see ObjectAdapter#destroy + */ + virtual void destroy() ICE_NOEXCEPT = 0; + + /** + * Shuts down this communicator's server functionality, which + * includes the deactivation of all object adapters. Attempts to use a + * deactivated object adapter raise ObjectAdapterDeactivatedException. + * Subsequent calls to shutdown are ignored. + * + * After shutdown returns, no new requests are processed. However, requests + * that have been started before shutdown was called might still be active. + * You can use {@link #waitForShutdown} to wait for the completion of all + * requests. + * @see #destroy + * @see #waitForShutdown + * @see ObjectAdapter#deactivate + */ + virtual void shutdown() ICE_NOEXCEPT = 0; + + /** + * Wait until the application has called {@link #shutdown} (or {@link #destroy}). + * On the server side, this operation blocks the calling thread + * until all currently-executing operations have completed. + * On the client side, the operation simply blocks until another + * thread has called {@link #shutdown} or {@link #destroy}. + * + * A typical use of this operation is to call it from the main thread, + * which then waits until some other thread calls {@link #shutdown}. + * After shut-down is complete, the main thread returns and can do some + * cleanup work before it finally calls {@link #destroy} to shut down + * the client functionality, and then exits the application. + * @see #shutdown + * @see #destroy + * @see ObjectAdapter#waitForDeactivate + */ + virtual void waitForShutdown() ICE_NOEXCEPT = 0; + + /** + * Check whether communicator has been shut down. + * @return True if the communicator has been shut down; false otherwise. + * @see #shutdown + */ + virtual bool isShutdown() const ICE_NOEXCEPT = 0; + + /** + * Convert a stringified proxy into a proxy. For example, + * MyCategory/MyObject:tcp -h some_host -p + * 10000 creates a proxy that refers to the Ice object + * having an identity with a name "MyObject" and a category + * "MyCategory", with the server running on host "some_host", port + * 10000. If the stringified proxy does not parse correctly, the + * operation throws one of ProxyParseException, EndpointParseException, + * or IdentityParseException. Refer to the Ice manual for a detailed + * description of the syntax supported by stringified proxies. + * @param str The stringified proxy to convert into a proxy. + * @return The proxy, or nil if str is an empty string. + * @see #proxyToString + */ + virtual ObjectPrx stringToProxy(const ::std::string& str) const = 0; + + /** + * Convert a proxy into a string. + * @param obj The proxy to convert into a stringified proxy. + * @return The stringified proxy, or an empty string if + * obj is nil. + * @see #stringToProxy + */ + virtual ::std::string proxyToString(const ObjectPrx& obj) const = 0; + + /** + * Convert a set of proxy properties into a proxy. The "base" + * name supplied in the property argument refers to a + * property containing a stringified proxy, such as + * MyProxy=id:tcp -h localhost -p 10000. Additional + * properties configure local settings for the proxy, such as + * MyProxy.PreferSecure=1. The "Properties" + * appendix in the Ice manual describes each of the supported + * proxy properties. + * @param property The base property name. + * @return The proxy. + */ + virtual ObjectPrx propertyToProxy(const ::std::string& property) const = 0; + + /** + * Convert a proxy to a set of proxy properties. + * @param proxy The proxy. + * @param property The base property name. + * @return The property set. + */ + virtual PropertyDict proxyToProperty(const ObjectPrx& proxy, const ::std::string& property) const = 0; + + /** + * Convert a string into an identity. If the string does not parse + * correctly, the operation throws IdentityParseException. + * @param str The string to convert into an identity. + * @return The identity. + * @see #identityToString + * + * @deprecated stringToIdentity() is deprecated, use the static stringToIdentity() method instead. + */ + ICE_DEPRECATED_API("stringToIdentity() is deprecated, use the static stringToIdentity() method instead.") virtual Identity stringToIdentity(const ::std::string& str) const = 0; + + /** + * Convert an identity into a string. + * @param ident The identity to convert into a string. + * @return The "stringified" identity. + * @see #stringToIdentity + */ + virtual ::std::string identityToString(const Identity& ident) const = 0; + + /** + * Create a new object adapter. The endpoints for the object + * adapter are taken from the property name.Endpoints. + * + * It is legal to create an object adapter with the empty string as + * its name. Such an object adapter is accessible via bidirectional + * connections or by collocated invocations that originate from the + * same communicator as is used by the adapter. + * + * Attempts to create a named object adapter for which no configuration + * can be found raise InitializationException. + * @param name The object adapter name. + * @return The new object adapter. + * @see #createObjectAdapterWithEndpoints + * @see ObjectAdapter + * @see Properties + */ + virtual ObjectAdapterPtr createObjectAdapter(const ::std::string& name) = 0; + + /** + * Create a new object adapter with endpoints. This operation sets + * the property name.Endpoints, and then calls + * {@link #createObjectAdapter}. It is provided as a convenience + * function. + * + * Calling this operation with an empty name will result in a + * UUID being generated for the name. + * @param name The object adapter name. + * @param endpoints The endpoints for the object adapter. + * @return The new object adapter. + * @see #createObjectAdapter + * @see ObjectAdapter + * @see Properties + */ + virtual ObjectAdapterPtr createObjectAdapterWithEndpoints(const ::std::string& name, const ::std::string& endpoints) = 0; + + /** + * Create a new object adapter with a router. This operation + * creates a routed object adapter. + * + * Calling this operation with an empty name will result in a + * UUID being generated for the name. + * @param name The object adapter name. + * @param rtr The router. + * @return The new object adapter. + * @see #createObjectAdapter + * @see ObjectAdapter + * @see Properties + */ + virtual ObjectAdapterPtr createObjectAdapterWithRouter(const ::std::string& name, const RouterPrx& rtr) = 0; + + /** + * Add an object factory to this communicator. Installing a + * factory with an id for which a factory is already registered + * throws AlreadyRegisteredException. + * + * When unmarshaling an Ice object, the Ice run time reads the + * most-derived type id off the wire and attempts to create an + * instance of the type using a factory. If no instance is created, + * either because no factory was found, or because all factories + * returned nil, the behavior of the Ice run time depends on the + * format with which the object was marshaled: + * + * If the object uses the "sliced" format, Ice ascends the class + * hierarchy until it finds a type that is recognized by a factory, + * or it reaches the least-derived type. If no factory is found that + * can create an instance, the run time throws NoValueFactoryException. + * + * If the object uses the "compact" format, Ice immediately raises + * NoValueFactoryException. + * + * The following order is used to locate a factory for a type: + * + *
    + * + *
  1. The Ice run-time looks for a factory registered + * specifically for the type.
  2. + * + *
  3. If no instance has been created, the Ice run-time looks + * for the default factory, which is registered with an empty type id. + *
  4. + * + *
  5. If no instance has been created by any of the preceding + * steps, the Ice run-time looks for a factory that may have been + * statically generated by the language mapping for non-abstract classes. + *
  6. + * + *
+ * @param factory The factory to add. + * @param id The type id for which the factory can create instances, or + * an empty string for the default factory. + * @see #findObjectFactory + * @see ObjectFactory + * @see ValueFactoryManager#add + * + * @deprecated addObjectFactory() is deprecated, use ValueFactoryManager::add() instead. + */ + ICE_DEPRECATED_API("addObjectFactory() is deprecated, use ValueFactoryManager::add() instead.") virtual void addObjectFactory(const ObjectFactoryPtr& factory, const ::std::string& id) = 0; + + /** + * Find an object factory registered with this communicator. + * @param id The type id for which the factory can create instances, + * or an empty string for the default factory. + * @return The object factory, or null if no object factory was + * found for the given id. + * @see #addObjectFactory + * @see ObjectFactory + * @see ValueFactoryManager#find + * + * @deprecated findObjectFactory() is deprecated, use ValueFactoryManager::find() instead. + */ + ICE_DEPRECATED_API("findObjectFactory() is deprecated, use ValueFactoryManager::find() instead.") virtual ObjectFactoryPtr findObjectFactory(const ::std::string& id) const ICE_NOEXCEPT = 0; + + /** + * Get the implicit context associated with this communicator. + * @return The implicit context associated with this communicator; + * returns null when the property Ice.ImplicitContext is not set + * or is set to None. + */ + virtual ImplicitContextPtr getImplicitContext() const ICE_NOEXCEPT = 0; + + /** + * Get the properties for this communicator. + * @return This communicator's properties. + * @see Properties + */ + virtual PropertiesPtr getProperties() const ICE_NOEXCEPT = 0; + + /** + * Get the logger for this communicator. + * @return This communicator's logger. + * @see Logger + */ + virtual LoggerPtr getLogger() const ICE_NOEXCEPT = 0; + + /** + * Get the observer resolver object for this communicator. + * @return This communicator's observer resolver object. + */ + virtual ::Ice::Instrumentation::CommunicatorObserverPtr getObserver() const ICE_NOEXCEPT = 0; + + /** + * Get the default router this communicator. + * @return The default router for this communicator. + * @see #setDefaultRouter + * @see Router + */ + virtual RouterPrx getDefaultRouter() const = 0; + + /** + * Set a default router for this communicator. All newly + * created proxies will use this default router. To disable the + * default router, null can be used. Note that this + * operation has no effect on existing proxies. + * + * You can also set a router for an individual proxy + * by calling the operation ice_router on the proxy. + * @param rtr The default router to use for this communicator. + * @see #getDefaultRouter + * @see #createObjectAdapterWithRouter + * @see Router + */ + virtual void setDefaultRouter(const RouterPrx& rtr) = 0; + + /** + * Get the default locator this communicator. + * @return The default locator for this communicator. + * @see #setDefaultLocator + * @see Locator + */ + virtual LocatorPrx getDefaultLocator() const = 0; + + /** + * Set a default Ice locator for this communicator. All newly + * created proxy and object adapters will use this default + * locator. To disable the default locator, null can be used. + * Note that this operation has no effect on existing proxies or + * object adapters. + * + * You can also set a locator for an individual proxy by calling the + * operation ice_locator on the proxy, or for an object adapter + * by calling {@link ObjectAdapter#setLocator} on the object adapter. + * @param loc The default locator to use for this communicator. + * @see #getDefaultLocator + * @see Locator + * @see ObjectAdapter#setLocator + */ + virtual void setDefaultLocator(const LocatorPrx& loc) = 0; + + /** + * Get the plug-in manager for this communicator. + * @return This communicator's plug-in manager. + * @see PluginManager + */ + virtual PluginManagerPtr getPluginManager() const = 0; + + /** + * Get the value factory manager for this communicator. + * @return This communicator's value factory manager. + * @see ValueFactoryManager + */ + virtual ValueFactoryManagerPtr getValueFactoryManager() const ICE_NOEXCEPT = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + */ + virtual void flushBatchRequests(CompressBatch compress) = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress) = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress, const CallbackPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress, const Callback_Communicator_flushBatchRequestsPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Flush any pending batch requests for this communicator. + * This means all batch requests invoked on fixed proxies + * for all connections associated with the communicator. + * Any errors that occur while flushing a connection are ignored. + * @param result The asynchronous result object returned by the begin_ method. + */ + virtual void end_flushBatchRequests(const AsyncResultPtr& result) = 0; + + /** + * Add the Admin object with all its facets to the provided object adapter. + * If Ice.Admin.ServerId is set and the provided object adapter has a {@link Locator}, + * createAdmin registers the Admin's Process facet with the {@link Locator}'s {@link LocatorRegistry}. + * + * createAdmin must only be called once; subsequent calls raise InitializationException. + * @param adminAdapter The object adapter used to host the Admin object; if null and + * Ice.Admin.Endpoints is set, create, activate and use the Ice.Admin object adapter. + * @param adminId The identity of the Admin object. + * @return A proxy to the main ("") facet of the Admin object. Never returns a null proxy. + * @see #getAdmin + */ + virtual ObjectPrx createAdmin(const ObjectAdapterPtr& adminAdapter, const Identity& adminId) = 0; + + /** + * Get a proxy to the main facet of the Admin object. + * + * getAdmin also creates the Admin object and creates and activates the Ice.Admin object + * adapter to host this Admin object if Ice.Admin.Enpoints is set. The identity of the Admin + * object created by getAdmin is {value of Ice.Admin.InstanceName}/admin, or {UUID}/admin + * when Ice.Admin.InstanceName is not set. + * + * If Ice.Admin.DelayCreation is 0 or not set, getAdmin is called by the communicator + * initialization, after initialization of all plugins. + * @return A proxy to the main ("") facet of the Admin object, or a null proxy if no + * Admin object is configured. + * @see #createAdmin + */ + virtual ObjectPrx getAdmin() const = 0; + + /** + * Add a new facet to the Admin object. + * Adding a servant with a facet that is already registered + * throws AlreadyRegisteredException. + * @param servant The servant that implements the new Admin facet. + * @param facet The name of the new Admin facet. + */ + virtual void addAdminFacet(const ObjectPtr& servant, const ::std::string& facet) = 0; + + /** + * Remove the following facet to the Admin object. + * Removing a facet that was not previously registered throws + * NotRegisteredException. + * @param facet The name of the Admin facet. + * @return The servant associated with this Admin facet. + */ + virtual ObjectPtr removeAdminFacet(const ::std::string& facet) = 0; + + /** + * Returns a facet of the Admin object. + * @param facet The name of the Admin facet. + * @return The servant associated with this Admin facet, or + * null if no facet is registered with the given name. + */ + virtual ObjectPtr findAdminFacet(const ::std::string& facet) = 0; + + /** + * Returns a map of all facets of the Admin object. + * @return A collection containing all the facet names and + * servants of the Admin object. + * @see #findAdminFacet + */ + virtual FacetMap findAllAdminFacets() = 0; + + /** + * Returns the client dispatch queue. + * @return The dispatch queue associated wih this Communicator's + * client thread pool. + */ + virtual LocalObjectPtr getClientDispatchQueue() const = 0; + + /** + * Returns the server dispatch queue. + * @return The dispatch queue associated wih the Communicator's + * server thread pool. + */ + virtual LocalObjectPtr getServerDispatchQueue() const = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Communicator& lhs, const Communicator& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Communicator& lhs, const Communicator& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/CommunicatorAsync.h b/Sources/IceCpp/include/Ice/CommunicatorAsync.h new file mode 100644 index 0000000..85cc9e7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/CommunicatorAsync.h @@ -0,0 +1,154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_COMMUNICATOR_ASYNC_H +#define ICE_COMMUNICATOR_ASYNC_H + +#ifndef ICE_CPP11_MAPPING + +#include + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Communicator::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Communicator_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Communicator_flushBatchRequests : public Callback_Communicator_flushBatchRequests_Base, + public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC_Communicator_flushBatchRequests(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::CommunicatorPtr communicator = result->getCommunicator(); + assert(communicator); + try + { + communicator->end_flushBatchRequests(result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + } + } + /// \endcond +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Communicator::begin_flushBatchRequests. + */ +template Callback_Communicator_flushBatchRequestsPtr +newCallback_Communicator_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Communicator_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Communicator::begin_flushBatchRequests. + */ +template Callback_Communicator_flushBatchRequestsPtr +newCallback_Communicator_flushBatchRequests(T* instance, void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Communicator_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Communicator::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Communicator_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class Callback_Communicator_flushBatchRequests : public Callback_Communicator_flushBatchRequests_Base, + public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + + Callback_Communicator_flushBatchRequests(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::CommunicatorPtr communicator = result->getCommunicator(); + assert(communicator); + try + { + communicator->end_flushBatchRequests(result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + } + } + /// \endcond +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Communicator::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Communicator_flushBatchRequests. + */ +template Callback_Communicator_flushBatchRequestsPtr +newCallback_Communicator_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Communicator_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Communicator::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Communicator_flushBatchRequests. + */ +template Callback_Communicator_flushBatchRequestsPtr +newCallback_Communicator_flushBatchRequests(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Communicator_flushBatchRequests(instance, excb, sentcb); +} + +} +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/CommunicatorF.h b/Sources/IceCpp/include/Ice/CommunicatorF.h new file mode 100644 index 0000000..54b7b4a --- /dev/null +++ b/Sources/IceCpp/include/Ice/CommunicatorF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `CommunicatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_CommunicatorF_h__ +#define __Ice_CommunicatorF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Communicator; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using CommunicatorPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class Communicator; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Communicator*); +/// \endcond +typedef ::IceInternal::Handle< Communicator> CommunicatorPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/CommunicatorI.h b/Sources/IceCpp/include/Ice/CommunicatorI.h new file mode 100644 index 0000000..3e24479 --- /dev/null +++ b/Sources/IceCpp/include/Ice/CommunicatorI.h @@ -0,0 +1,167 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_COMMUNICATOR_I_H +#define ICE_COMMUNICATOR_I_H + +#include + +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +// +// Class for handling Ice::Communicator::begin_flushBatchRequests +// +class CommunicatorFlushBatchAsync : public OutgoingAsyncBase +{ +public: + + virtual ~CommunicatorFlushBatchAsync(); + + CommunicatorFlushBatchAsync(const InstancePtr&); + + void flushConnection(const Ice::ConnectionIPtr&, Ice::CompressBatch); + void invoke(const std::string&, Ice::CompressBatch); + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(OutgoingAsyncBase::shared_from_this()); + } +#endif + +private: + + void check(bool); + + int _useCount; +}; + +} + +namespace Ice +{ + +class CommunicatorI; +ICE_DEFINE_PTR(CommunicatorIPtr, CommunicatorI); + +class CommunicatorI : public Communicator +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif + +{ +public: + + virtual void destroy() ICE_NOEXCEPT; + virtual void shutdown() ICE_NOEXCEPT; + virtual void waitForShutdown() ICE_NOEXCEPT; + virtual bool isShutdown() const ICE_NOEXCEPT; + + virtual ObjectPrxPtr stringToProxy(const std::string&) const; + virtual std::string proxyToString(const ObjectPrxPtr&) const; + + virtual ObjectPrxPtr propertyToProxy(const std::string&) const; + virtual PropertyDict proxyToProperty(const ObjectPrxPtr&, const std::string&) const; + + virtual Identity stringToIdentity(const std::string&) const; + virtual std::string identityToString(const Identity&) const; + + virtual ObjectAdapterPtr createObjectAdapter(const std::string&); + virtual ObjectAdapterPtr createObjectAdapterWithEndpoints(const std::string&, const std::string&); + virtual ObjectAdapterPtr createObjectAdapterWithRouter(const std::string&, const RouterPrxPtr&); + + virtual void addObjectFactory(const ObjectFactoryPtr&, const std::string&); + virtual ObjectFactoryPtr findObjectFactory(const std::string&) const ICE_NOEXCEPT; + + virtual ImplicitContextPtr getImplicitContext() const ICE_NOEXCEPT; + + virtual PropertiesPtr getProperties() const ICE_NOEXCEPT; + virtual LoggerPtr getLogger() const ICE_NOEXCEPT; + virtual Ice::Instrumentation::CommunicatorObserverPtr getObserver() const ICE_NOEXCEPT; + + virtual RouterPrxPtr getDefaultRouter() const; + virtual void setDefaultRouter(const RouterPrxPtr&); + + virtual LocatorPrxPtr getDefaultLocator() const; + virtual void setDefaultLocator(const LocatorPrxPtr&); + + virtual PluginManagerPtr getPluginManager() const; + + virtual ValueFactoryManagerPtr getValueFactoryManager() const ICE_NOEXCEPT; + +#ifdef ICE_SWIFT + virtual dispatch_queue_t getClientDispatchQueue() const; + virtual dispatch_queue_t getServerDispatchQueue() const; +#endif + +#ifdef ICE_CPP11_MAPPING + virtual ::std::function + flushBatchRequestsAsync(CompressBatch, + ::std::function, + ::std::function = nullptr); +#else + virtual void flushBatchRequests(CompressBatch); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch, const CallbackPtr&, const LocalObjectPtr& = 0); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch, + const Callback_Communicator_flushBatchRequestsPtr&, + const LocalObjectPtr& = 0); + + virtual void end_flushBatchRequests(const AsyncResultPtr&); +#endif + + virtual ObjectPrxPtr createAdmin(const ObjectAdapterPtr&, const Identity&); + virtual ObjectPrxPtr getAdmin() const; + virtual void addAdminFacet(const ObjectPtr&, const std::string&); + virtual ObjectPtr removeAdminFacet(const std::string&); + virtual ObjectPtr findAdminFacet(const std::string&); + virtual FacetMap findAllAdminFacets(); + + virtual ~CommunicatorI(); + +private: + +#ifndef ICE_CPP11_MAPPING + CommunicatorI() {} +#endif + + static CommunicatorIPtr create(const InitializationData&); + + // + // Certain initialization tasks need to be completed after the + // constructor. + // + void finishSetup(int&, const char*[]); + + friend ICE_API CommunicatorPtr initialize(int&, const char*[], const InitializationData&, Int); + friend ICE_API CommunicatorPtr initialize(StringSeq&, const InitializationData&, Int); + friend ICE_API CommunicatorPtr initialize(const InitializationData&, Int); + friend ICE_API ::IceInternal::InstancePtr IceInternal::getInstance(const ::Ice::CommunicatorPtr&); + friend ICE_API ::IceUtil::TimerPtr IceInternal::getInstanceTimer(const ::Ice::CommunicatorPtr&); + +#ifndef ICE_CPP11_MAPPING + AsyncResultPtr _iceI_begin_flushBatchRequests(CompressBatch, + const IceInternal::CallbackBasePtr&, + const LocalObjectPtr&); +#endif + + const ::IceInternal::InstancePtr _instance; + + // + // We don't want the dynamic libraries to be unloaded until the + // Communicator's destructor is invoked. + // + const ::IceInternal::DynamicLibraryListPtr _dynamicLibraryList; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Comparable.h b/Sources/IceCpp/include/Ice/Comparable.h new file mode 100644 index 0000000..de93991 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Comparable.h @@ -0,0 +1,205 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_COMPARABLE_H +#define ICE_COMPARABLE_H + +#include + +namespace Ice +{ + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the contents are equal, false otherwise. + */ +template +inline bool targetEqualTo(const T& lhs, const U& rhs) +{ + if(lhs && rhs) + { + return *lhs == *rhs; + } + else + { + return !lhs && !rhs; + } +} + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares less than the right-hand side, false otherwise. + */ +template +inline bool targetLess(const T& lhs, const U& rhs) +{ + if(lhs && rhs) + { + return *lhs < *rhs; + } + else + { + return !lhs && rhs; + } +} + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares greater than the right-hand side, false otherwise. + */ +template +inline bool targetGreater(const T& lhs, const U& rhs) +{ + return targetLess(rhs, lhs); +} + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares less than or equal to the right-hand side, false otherwise. + */ +template +inline bool targetLessEqual(const T& lhs, const U& rhs) +{ + return !targetGreater(lhs, rhs); +} + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares greater than or equal to the right-hand side, false otherwise. + */ +template +inline bool targetGreaterEqual(const T& lhs, const U& rhs) +{ + return !targetLess(lhs, rhs); +} + +/** + * Compares the contents of two smart pointers. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the contents are not equal, false otherwise. + */ +template +inline bool targetNotEqualTo(const T& lhs, const U& rhs) +{ + return !targetEqualTo(lhs, rhs); +} + +#ifdef ICE_CPP11_MAPPING + +/** + * Functor class that compares the contents of two smart pointers of the given type using the given comparator. + * \headerfile Ice/Ice.h + */ +template class Compare> +struct TargetCompare +{ + /** + * Executes the functor to compare the contents of two smart pointers. + * @return True if the contents satisfy the given comparator, false otherwise. + */ + bool operator()(const T& lhs, const T& rhs) const + { + if(lhs && rhs) + { + return Compare()(*lhs, *rhs); + } + else + { + return Compare()(static_cast(lhs), static_cast(rhs)); + } + } +}; + +// +// Relational operators for generated structs and classes +// + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares less than the right-hand side, false otherwise. + */ +template::value>> +bool operator<(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() < rhs.ice_tuple(); +} + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares less than or equal to the right-hand side, false otherwise. + */ +template::value>> +bool operator<=(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() <= rhs.ice_tuple(); +} + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares greater than the right-hand side, false otherwise. + */ +template::value>> +bool operator>(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() > rhs.ice_tuple(); +} + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares greater than or equal to the right-hand side, false otherwise. + */ +template::value>> +bool operator>=(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() >= rhs.ice_tuple(); +} + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side compares equal to the right-hand side, false otherwise. + */ +template::value>> +bool operator==(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() == rhs.ice_tuple(); +} + +/** + * Relational operator for generated structs and classes. + * @param lhs The left-hand side. + * @param rhs The right-hand side. + * @return True if the left-hand side is not equal to the right-hand side, false otherwise. + */ +template::value>> +bool operator!=(const C& lhs, const C& rhs) +{ + return lhs.ice_tuple() != rhs.ice_tuple(); +} + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Config.h b/Sources/IceCpp/include/Ice/Config.h new file mode 100644 index 0000000..00c1acd --- /dev/null +++ b/Sources/IceCpp/include/Ice/Config.h @@ -0,0 +1,76 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONFIG_H +#define ICE_CONFIG_H + +#include + +// +// Some include files we need almost everywhere +// +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +# include +#else +# include +# include +#endif + +#ifdef ICE_SWIFT +# include +#endif + +// +// Define the Ice and IceInternal namespace, so that we can use the following +// everywhere in our code: +// +// using namespace Ice; +// using namespace IceInternal; +// +namespace Ice +{ +} + +namespace IceInternal +{ +} + +namespace Ice +{ + +/** The mapping for the Slice byte type. */ +typedef unsigned char Byte; +/** The mapping for the Slice short type. */ +typedef short Short; +/** The mapping for the Slice int type. */ +typedef int Int; +#ifdef ICE_CPP11_MAPPING +/** The mapping for the Slice long type. */ +typedef long long int Long; +#else +/** The mapping for the Slice long type. */ +typedef IceUtil::Int64 Long; +#endif +/** The mapping for the Slice float type. */ +typedef float Float; +/** The mapping for the Slice double type. */ +typedef double Double; + +} + +namespace IceInternal +{ + +ICE_API int getSystemErrno(); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectRequestHandler.h b/Sources/IceCpp/include/Ice/ConnectRequestHandler.h new file mode 100644 index 0000000..7b39188 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectRequestHandler.h @@ -0,0 +1,72 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECT_REQUEST_HANDLER_H +#define ICE_CONNECT_REQUEST_HANDLER_H + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace IceInternal +{ + +class ConnectRequestHandler ICE_FINAL : public RequestHandler, + public Reference::GetConnectionCallback, + public RouterInfo::AddProxyCallback, + public IceUtil::Monitor +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + ConnectRequestHandler(const ReferencePtr&, const Ice::ObjectPrxPtr&); + + RequestHandlerPtr connect(const Ice::ObjectPrxPtr&); + virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); + + virtual AsyncStatus sendAsyncRequest(const ProxyOutgoingAsyncBasePtr&); + + virtual void asyncRequestCanceled(const OutgoingAsyncBasePtr&, const Ice::LocalException&); + + virtual Ice::ConnectionIPtr getConnection(); + virtual Ice::ConnectionIPtr waitForConnection(); + + virtual void setConnection(const Ice::ConnectionIPtr&, bool); + virtual void setException(const Ice::LocalException&); + + virtual void addedProxy(); + +private: + + bool initialized(); + void flushRequests(); + + Ice::ObjectPrxPtr _proxy; + std::set _proxies; + + Ice::ConnectionIPtr _connection; + bool _compress; + IceInternal::UniquePtr _exception; + bool _initialized; + bool _flushing; + + std::deque _requests; + + RequestHandlerPtr _requestHandler; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectRequestHandlerF.h b/Sources/IceCpp/include/Ice/ConnectRequestHandlerF.h new file mode 100644 index 0000000..aed35ba --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectRequestHandlerF.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECT_REQUEST_HANDLER_F_H +#define ICE_CONNECT_REQUEST_HANDLER_F_H + +#include +#include + +namespace IceInternal +{ + +class ConnectRequestHandler; +#ifdef ICE_CPP11_MAPPING +using ConnectRequestHandlerPtr = ::std::shared_ptr; +#else +IceUtil::Shared* upCast(ConnectRequestHandler*); +typedef IceInternal::Handle ConnectRequestHandlerPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Connection.h b/Sources/IceCpp/include/Ice/Connection.h new file mode 100644 index 0000000..b73228c --- /dev/null +++ b/Sources/IceCpp/include/Ice/Connection.h @@ -0,0 +1,1703 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Connection.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Connection_h__ +#define __Ice_Connection_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ConnectionInfo; +class Connection; +class IPConnectionInfo; +class TCPConnectionInfo; +class UDPConnectionInfo; +class WSConnectionInfo; + +} + +namespace Ice +{ + +/** + * The batch compression option when flushing queued batch requests. + */ +enum class CompressBatch : unsigned char +{ + /** + * Compress the batch requests. + */ + Yes, + /** + * Don't compress the batch requests. + */ + No, + /** + * Compress the batch requests if at least one request was + * made on a compressed proxy. + */ + BasedOnProxy +}; + +/** + * Specifies the close semantics for Active Connection Management. + */ +enum class ACMClose : unsigned char +{ + /** + * Disables automatic connection closure. + */ + CloseOff, + /** + * Gracefully closes a connection that has been idle for the configured timeout period. + */ + CloseOnIdle, + /** + * Forcefully closes a connection that has been idle for the configured timeout period, + * but only if the connection has pending invocations. + */ + CloseOnInvocation, + /** + * Combines the behaviors of CloseOnIdle and CloseOnInvocation. + */ + CloseOnInvocationAndIdle, + /** + * Forcefully closes a connection that has been idle for the configured timeout period, + * regardless of whether the connection has pending invocations or dispatch. + */ + CloseOnIdleForceful +}; + +/** + * Specifies the heartbeat semantics for Active Connection Management. + */ +enum class ACMHeartbeat : unsigned char +{ + /** + * Disables heartbeats. + */ + HeartbeatOff, + /** + * Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. + */ + HeartbeatOnDispatch, + /** + * Send a heartbeat at regular intervals when the connection is idle. + */ + HeartbeatOnIdle, + /** + * Send a heartbeat at regular intervals until the connection is closed. + */ + HeartbeatAlways +}; + +/** + * A collection of Active Connection Management configuration settings. + * \headerfile Ice/Ice.h + */ +struct ACM +{ + /** + * A timeout value in seconds. + */ + int timeout; + /** + * The close semantics. + */ + ::Ice::ACMClose close; + /** + * The heartbeat semantics. + */ + ::Ice::ACMHeartbeat heartbeat; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(timeout, close, heartbeat); + } +}; + +/** + * Determines the behavior when manually closing a connection. + */ +enum class ConnectionClose : unsigned char +{ + /** + * Close the connection immediately without sending a close connection protocol message to the peer + * and waiting for the peer to acknowledge it. + */ + Forcefully, + /** + * Close the connection by notifying the peer but do not wait for pending outgoing invocations to complete. + * On the server side, the connection will not be closed until all incoming invocations have completed. + */ + Gracefully, + /** + * Wait for all pending invocations to complete before closing the connection. + */ + GracefullyWithWait +}; + +/** + * A collection of HTTP headers. + */ +using HeaderDict = ::std::map<::std::string, ::std::string>; + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +namespace Ice +{ + +/** + * Base class providing access to the connection details. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionInfo(); + + ConnectionInfo() = default; + + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo(ConnectionInfo&&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; + ConnectionInfo& operator=(ConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + */ + ConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId) : + underlying(underlying), + incoming(incoming), + adapterName(adapterName), + connectionId(connectionId) + { + } + + /** + * The information of the underyling transport or null if there's + * no underlying transport. + */ + ::std::shared_ptr<::Ice::ConnectionInfo> underlying; + /** + * Whether or not the connection is an incoming or outgoing + * connection. + */ + bool incoming; + /** + * The name of the adapter associated with the connection. + */ + ::std::string adapterName; + /** + * The connection id. + */ + ::std::string connectionId; +}; + +/** + * This method is called by the the connection when the connection + * is closed. If the callback needs more information about the closure, + * it can call {@link Connection#throwException}. + * @param con The connection that closed. + */ +using CloseCallback = ::std::function& con)>; + +/** + * This method is called by the the connection when a heartbeat is + * received from the peer. + * @param con The connection on which a heartbeat was received. + */ +using HeartbeatCallback = ::std::function& con)>; + +/** + * The user-level interface to a connection. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Connection +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Connection(); + + /** + * Manually close the connection using the specified closure mode. + * @param mode Determines how the connection will be closed. + * @see ConnectionClose + */ + virtual void close(ConnectionClose mode) noexcept = 0; + + /** + * Create a special proxy that always uses this connection. This + * can be used for callbacks from a server to a client if the + * server cannot directly establish a connection to the client, + * for example because of firewalls. In this case, the server + * would create a proxy using an already established connection + * from the client. + * @param id The identity for which a proxy is to be created. + * @return A proxy that matches the given identity and uses this + * connection. + * @see #setAdapter + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> createProxy(const Identity& id) const = 0; + + /** + * Explicitly set an object adapter that dispatches requests that + * are received over this connection. A client can invoke an + * operation on a server using a proxy, and then set an object + * adapter for the outgoing connection that is used by the proxy + * in order to receive callbacks. This is useful if the server + * cannot establish a connection back to the client, for example + * because of firewalls. + * @param adapter The object adapter that should be used by this + * connection to dispatch requests. The object adapter must be + * activated. When the object adapter is deactivated, it is + * automatically removed from the connection. Attempts to use a + * deactivated object adapter raise {@link ObjectAdapterDeactivatedException} + * @see #createProxy + * @see #getAdapter + */ + virtual void setAdapter(const ::std::shared_ptr& adapter) = 0; + + /** + * Get the object adapter that dispatches requests for this + * connection. + * @return The object adapter that dispatches requests for the + * connection, or null if no adapter is set. + * @see #setAdapter + */ + virtual ::std::shared_ptr<::Ice::ObjectAdapter> getAdapter() const noexcept = 0; + + /** + * Get the endpoint from which the connection was created. + * @return The endpoint from which the connection was created. + */ + virtual ::std::shared_ptr<::Ice::Endpoint> getEndpoint() const noexcept = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + */ + virtual void flushBatchRequests(CompressBatch compress) + { + flushBatchRequestsAsync(compress).get(); + } + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param exception The exception callback. + * @param sent The sent callback. + * @return A function that can be called to cancel the invocation locally. + */ + virtual ::std::function + flushBatchRequestsAsync(CompressBatch compress, + ::std::function exception, + ::std::function sent = nullptr) = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto flushBatchRequestsAsync(CompressBatch compress) + -> decltype(::std::declval>().get_future()) + { + using Promise = P; + auto promise = ::std::make_shared(); + flushBatchRequestsAsync(compress, + [promise](::std::exception_ptr ex) + { + promise->set_exception(::std::move(ex)); + }, + [promise](bool) + { + promise->set_value(); + }); + return promise->get_future(); + } + + /** + * Set a close callback on the connection. The callback is called by the + * connection when it's closed. The callback is called from the + * Ice thread pool associated with the connection. If the callback needs + * more information about the closure, it can call {@link Connection#throwException}. + * @param callback The close callback object. + */ + virtual void setCloseCallback(CloseCallback callback) = 0; + + /** + * Set a heartbeat callback on the connection. The callback is called by the + * connection when a heartbeat is received. The callback is called + * from the Ice thread pool associated with the connection. + * @param callback The heartbeat callback object. + */ + virtual void setHeartbeatCallback(HeartbeatCallback callback) = 0; + + /** + * Send a heartbeat message. + */ + virtual void heartbeat() + { + heartbeatAsync().get(); + } + + /** + * Send a heartbeat message. + * @param exception The exception callback. + * @param sent The sent callback. + * @return A function that can be called to cancel the invocation locally. + */ + virtual ::std::function + heartbeatAsync(::std::function exception, + ::std::function sent = nullptr) = 0; + + /** + * Send a heartbeat message. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto heartbeatAsync() + -> decltype(::std::declval>().get_future()) + { + using Promise = P; + auto promise = ::std::make_shared(); + heartbeatAsync([promise](::std::exception_ptr ex) + { + promise->set_exception(::std::move(ex)); + }, + [promise](bool) + { + promise->set_value(); + }); + return promise->get_future(); + } + + /** + * Set the active connection management parameters. + * @param timeout The timeout value in seconds, must be >= 0. + * @param close The close condition + * @param heartbeat The hertbeat condition + */ + virtual void setACM(const Ice::optional& timeout, const Ice::optional& close, const Ice::optional& heartbeat) = 0; + + /** + * Get the ACM parameters. + * @return The ACM parameters. + */ + virtual ::Ice::ACM getACM() noexcept = 0; + + /** + * Return the connection type. This corresponds to the endpoint + * type, i.e., "tcp", "udp", etc. + * @return The type of the connection. + */ + virtual ::std::string type() const noexcept = 0; + + /** + * Get the timeout for the connection. + * @return The connection's timeout. + */ + virtual int timeout() const noexcept = 0; + + /** + * Return a description of the connection as human readable text, + * suitable for logging or error messages. + * @return The description of the connection as human readable + * text. + */ + virtual ::std::string toString() const noexcept = 0; + + /** + * Returns the connection information. + * @return The connection information. + */ + virtual ::std::shared_ptr<::Ice::ConnectionInfo> getInfo() const = 0; + + /** + * Set the connection buffer receive/send size. + * @param rcvSize The connection receive buffer size. + * @param sndSize The connection send buffer size. + */ + virtual void setBufferSize(int rcvSize, int sndSize) = 0; + + /** + * Throw an exception indicating the reason for connection closure. For example, + * {@link CloseConnectionException} is raised if the connection was closed gracefully, + * whereas {@link ConnectionManuallyClosedException} is raised if the connection was + * manually closed by the application. This operation does nothing if the connection is + * not yet closed. + */ + virtual void throwException() const = 0; +}; + +/** + * Provides access to the connection details of an IP connection + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IPConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IPConnectionInfo(); + + IPConnectionInfo() : + localAddress(""), + localPort(-1), + remoteAddress(""), + remotePort(-1) + { + } + + IPConnectionInfo(const IPConnectionInfo&) = default; + IPConnectionInfo(IPConnectionInfo&&) = default; + IPConnectionInfo& operator=(const IPConnectionInfo&) = default; + IPConnectionInfo& operator=(IPConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + */ + IPConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, int localPort, const ::std::string& remoteAddress, int remotePort) : + ConnectionInfo(underlying, incoming, adapterName, connectionId), + localAddress(localAddress), + localPort(localPort), + remoteAddress(remoteAddress), + remotePort(remotePort) + { + } + + /** + * The local address. + */ + ::std::string localAddress; + /** + * The local port. + */ + int localPort = -1; + /** + * The remote address. + */ + ::std::string remoteAddress; + /** + * The remote port. + */ + int remotePort = -1; +}; + +/** + * Provides access to the connection details of a TCP connection + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) TCPConnectionInfo : public ::Ice::IPConnectionInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~TCPConnectionInfo(); + + TCPConnectionInfo() : + rcvSize(0), + sndSize(0) + { + } + + TCPConnectionInfo(const TCPConnectionInfo&) = default; + TCPConnectionInfo(TCPConnectionInfo&&) = default; + TCPConnectionInfo& operator=(const TCPConnectionInfo&) = default; + TCPConnectionInfo& operator=(TCPConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + * @param rcvSize The connection buffer receive size. + * @param sndSize The connection buffer send size. + */ + TCPConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, int localPort, const ::std::string& remoteAddress, int remotePort, int rcvSize, int sndSize) : + IPConnectionInfo(underlying, incoming, adapterName, connectionId, localAddress, localPort, remoteAddress, remotePort), + rcvSize(rcvSize), + sndSize(sndSize) + { + } + + /** + * The connection buffer receive size. + */ + int rcvSize = 0; + /** + * The connection buffer send size. + */ + int sndSize = 0; +}; + +/** + * Provides access to the connection details of a UDP connection + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UDPConnectionInfo : public ::Ice::IPConnectionInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UDPConnectionInfo(); + + UDPConnectionInfo() : + mcastPort(-1), + rcvSize(0), + sndSize(0) + { + } + + UDPConnectionInfo(const UDPConnectionInfo&) = default; + UDPConnectionInfo(UDPConnectionInfo&&) = default; + UDPConnectionInfo& operator=(const UDPConnectionInfo&) = default; + UDPConnectionInfo& operator=(UDPConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + * @param mcastAddress The multicast address. + * @param mcastPort The multicast port. + * @param rcvSize The connection buffer receive size. + * @param sndSize The connection buffer send size. + */ + UDPConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, int localPort, const ::std::string& remoteAddress, int remotePort, const ::std::string& mcastAddress, int mcastPort, int rcvSize, int sndSize) : + IPConnectionInfo(underlying, incoming, adapterName, connectionId, localAddress, localPort, remoteAddress, remotePort), + mcastAddress(mcastAddress), + mcastPort(mcastPort), + rcvSize(rcvSize), + sndSize(sndSize) + { + } + + /** + * The multicast address. + */ + ::std::string mcastAddress; + /** + * The multicast port. + */ + int mcastPort = -1; + /** + * The connection buffer receive size. + */ + int rcvSize = 0; + /** + * The connection buffer send size. + */ + int sndSize = 0; +}; + +/** + * Provides access to the connection details of a WebSocket connection + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) WSConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~WSConnectionInfo(); + + WSConnectionInfo() = default; + + WSConnectionInfo(const WSConnectionInfo&) = default; + WSConnectionInfo(WSConnectionInfo&&) = default; + WSConnectionInfo& operator=(const WSConnectionInfo&) = default; + WSConnectionInfo& operator=(WSConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param headers The headers from the HTTP upgrade request. + */ + WSConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::Ice::HeaderDict& headers) : + ConnectionInfo(underlying, incoming, adapterName, connectionId), + headers(headers) + { + } + + /** + * The headers from the HTTP upgrade request. + */ + ::Ice::HeaderDict headers; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ConnectionInfoPtr = ::std::shared_ptr; + +using ConnectionPtr = ::std::shared_ptr; + +using IPConnectionInfoPtr = ::std::shared_ptr; + +using TCPConnectionInfoPtr = ::std::shared_ptr; + +using UDPConnectionInfoPtr = ::std::shared_ptr; + +using WSConnectionInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionInfo> ConnectionInfoPtr; + +class Connection; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Connection*); +/// \endcond +typedef ::IceInternal::Handle< Connection> ConnectionPtr; + +class CloseCallback; +/// \cond INTERNAL +ICE_API LocalObject* upCast(CloseCallback*); +/// \endcond +typedef ::IceInternal::Handle< CloseCallback> CloseCallbackPtr; + +class HeartbeatCallback; +/// \cond INTERNAL +ICE_API LocalObject* upCast(HeartbeatCallback*); +/// \endcond +typedef ::IceInternal::Handle< HeartbeatCallback> HeartbeatCallbackPtr; + +class IPConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(IPConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< IPConnectionInfo> IPConnectionInfoPtr; + +class TCPConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(TCPConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< TCPConnectionInfo> TCPConnectionInfoPtr; + +class UDPConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(UDPConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< UDPConnectionInfo> UDPConnectionInfoPtr; + +class WSConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(WSConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< WSConnectionInfo> WSConnectionInfoPtr; + +} + +namespace Ice +{ + +/** + * The batch compression option when flushing queued batch requests. + */ +enum CompressBatch +{ + /** + * Compress the batch requests. + */ + CompressBatchYes, + /** + * Don't compress the batch requests. + */ + CompressBatchNo, + /** + * Compress the batch requests if at least one request was + * made on a compressed proxy. + */ + CompressBatchBasedOnProxy +}; + +/** + * Specifies the close semantics for Active Connection Management. + */ +enum ACMClose +{ + /** + * Disables automatic connection closure. + */ + CloseOff, + /** + * Gracefully closes a connection that has been idle for the configured timeout period. + */ + CloseOnIdle, + /** + * Forcefully closes a connection that has been idle for the configured timeout period, + * but only if the connection has pending invocations. + */ + CloseOnInvocation, + /** + * Combines the behaviors of CloseOnIdle and CloseOnInvocation. + */ + CloseOnInvocationAndIdle, + /** + * Forcefully closes a connection that has been idle for the configured timeout period, + * regardless of whether the connection has pending invocations or dispatch. + */ + CloseOnIdleForceful +}; + +/** + * Specifies the heartbeat semantics for Active Connection Management. + */ +enum ACMHeartbeat +{ + /** + * Disables heartbeats. + */ + HeartbeatOff, + /** + * Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. + */ + HeartbeatOnDispatch, + /** + * Send a heartbeat at regular intervals when the connection is idle. + */ + HeartbeatOnIdle, + /** + * Send a heartbeat at regular intervals until the connection is closed. + */ + HeartbeatAlways +}; + +/** + * A collection of Active Connection Management configuration settings. + * \headerfile Ice/Ice.h + */ +struct ACM +{ + /** + * A timeout value in seconds. + */ + ::Ice::Int timeout; + /** + * The close semantics. + */ + ::Ice::ACMClose close; + /** + * The heartbeat semantics. + */ + ::Ice::ACMHeartbeat heartbeat; + + bool operator==(const ACM& rhs_) const + { + if(this == &rhs_) + { + return true; + } + if(timeout != rhs_.timeout) + { + return false; + } + if(close != rhs_.close) + { + return false; + } + if(heartbeat != rhs_.heartbeat) + { + return false; + } + return true; + } + + bool operator<(const ACM& rhs_) const + { + if(this == &rhs_) + { + return false; + } + if(timeout < rhs_.timeout) + { + return true; + } + else if(rhs_.timeout < timeout) + { + return false; + } + if(close < rhs_.close) + { + return true; + } + else if(rhs_.close < close) + { + return false; + } + if(heartbeat < rhs_.heartbeat) + { + return true; + } + else if(rhs_.heartbeat < heartbeat) + { + return false; + } + return false; + } + + bool operator!=(const ACM& rhs_) const + { + return !operator==(rhs_); + } + bool operator<=(const ACM& rhs_) const + { + return operator<(rhs_) || operator==(rhs_); + } + bool operator>(const ACM& rhs_) const + { + return !operator<(rhs_) && !operator==(rhs_); + } + bool operator>=(const ACM& rhs_) const + { + return !operator<(rhs_); + } +}; + +/** + * Determines the behavior when manually closing a connection. + */ +enum ConnectionClose +{ + /** + * Close the connection immediately without sending a close connection protocol message to the peer + * and waiting for the peer to acknowledge it. + */ + ConnectionCloseForcefully, + /** + * Close the connection by notifying the peer but do not wait for pending outgoing invocations to complete. + * On the server side, the connection will not be closed until all incoming invocations have completed. + */ + ConnectionCloseGracefully, + /** + * Wait for all pending invocations to complete before closing the connection. + */ + ConnectionCloseGracefullyWithWait +}; + +/** + * A collection of HTTP headers. + */ +typedef ::std::map< ::std::string, ::std::string> HeaderDict; + +} + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Connection::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_flushBatchRequests. + */ +class Callback_Connection_flushBatchRequests_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Connection_flushBatchRequests_Base> Callback_Connection_flushBatchRequestsPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Connection::begin_heartbeat. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_heartbeat. + */ +class Callback_Connection_heartbeat_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Connection_heartbeat_Base> Callback_Connection_heartbeatPtr; + +} + +namespace Ice +{ + +/** + * Base class providing access to the connection details. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionInfo : public virtual LocalObject +{ +public: + + typedef ConnectionInfoPtr PointerType; + + virtual ~ConnectionInfo(); + + ConnectionInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + */ + ConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId) : + underlying(underlying), + incoming(incoming), + adapterName(adapterName), + connectionId(connectionId) + { + } + +#ifdef ICE_CPP11_COMPILER + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; +#endif + + /** + * The information of the underyling transport or null if there's + * no underlying transport. + */ + ::Ice::ConnectionInfoPtr underlying; + /** + * Whether or not the connection is an incoming or outgoing + * connection. + */ + bool incoming; + /** + * The name of the adapter associated with the connection. + */ + ::std::string adapterName; + /** + * The connection id. + */ + ::std::string connectionId; +}; + +/// \cond INTERNAL +inline bool operator==(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * An application can implement this interface to receive notifications when + * a connection closes. + * @see Connection#setCloseCallback + * \headerfile Ice/Ice.h + */ +class ICE_API CloseCallback : public virtual LocalObject +{ +public: + + typedef CloseCallbackPtr PointerType; + + virtual ~CloseCallback(); + +#ifdef ICE_CPP11_COMPILER + CloseCallback() = default; + CloseCallback(const CloseCallback&) = default; + CloseCallback& operator=(const CloseCallback&) = default; +#endif + + /** + * This method is called by the the connection when the connection + * is closed. If the callback needs more information about the closure, + * it can call {@link Connection#throwException}. + * @param con The connection that closed. + */ + virtual void closed(const ConnectionPtr& con) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const CloseCallback& lhs, const CloseCallback& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const CloseCallback& lhs, const CloseCallback& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * An application can implement this interface to receive notifications when + * a connection receives a heartbeat message. + * @see Connection#setHeartbeatCallback + * \headerfile Ice/Ice.h + */ +class ICE_API HeartbeatCallback : public virtual LocalObject +{ +public: + + typedef HeartbeatCallbackPtr PointerType; + + virtual ~HeartbeatCallback(); + +#ifdef ICE_CPP11_COMPILER + HeartbeatCallback() = default; + HeartbeatCallback(const HeartbeatCallback&) = default; + HeartbeatCallback& operator=(const HeartbeatCallback&) = default; +#endif + + /** + * This method is called by the the connection when a heartbeat is + * received from the peer. + * @param con The connection on which a heartbeat was received. + */ + virtual void heartbeat(const ConnectionPtr& con) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const HeartbeatCallback& lhs, const HeartbeatCallback& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const HeartbeatCallback& lhs, const HeartbeatCallback& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The user-level interface to a connection. + * \headerfile Ice/Ice.h + */ +class ICE_API Connection : public virtual LocalObject +{ +public: + + typedef ConnectionPtr PointerType; + + virtual ~Connection(); + +#ifdef ICE_CPP11_COMPILER + Connection() = default; + Connection(const Connection&) = default; + Connection& operator=(const Connection&) = default; +#endif + + /** + * Manually close the connection using the specified closure mode. + * @param mode Determines how the connection will be closed. + * @see ConnectionClose + */ + virtual void close(ConnectionClose mode) ICE_NOEXCEPT = 0; + + /** + * Create a special proxy that always uses this connection. This + * can be used for callbacks from a server to a client if the + * server cannot directly establish a connection to the client, + * for example because of firewalls. In this case, the server + * would create a proxy using an already established connection + * from the client. + * @param id The identity for which a proxy is to be created. + * @return A proxy that matches the given identity and uses this + * connection. + * @see #setAdapter + */ + virtual ObjectPrx createProxy(const Identity& id) const = 0; + + /** + * Explicitly set an object adapter that dispatches requests that + * are received over this connection. A client can invoke an + * operation on a server using a proxy, and then set an object + * adapter for the outgoing connection that is used by the proxy + * in order to receive callbacks. This is useful if the server + * cannot establish a connection back to the client, for example + * because of firewalls. + * @param adapter The object adapter that should be used by this + * connection to dispatch requests. The object adapter must be + * activated. When the object adapter is deactivated, it is + * automatically removed from the connection. Attempts to use a + * deactivated object adapter raise {@link ObjectAdapterDeactivatedException} + * @see #createProxy + * @see #getAdapter + */ + virtual void setAdapter(const ObjectAdapterPtr& adapter) = 0; + + /** + * Get the object adapter that dispatches requests for this + * connection. + * @return The object adapter that dispatches requests for the + * connection, or null if no adapter is set. + * @see #setAdapter + */ + virtual ObjectAdapterPtr getAdapter() const ICE_NOEXCEPT = 0; + + /** + * Get the endpoint from which the connection was created. + * @return The endpoint from which the connection was created. + */ + virtual EndpointPtr getEndpoint() const ICE_NOEXCEPT = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + */ + virtual void flushBatchRequests(CompressBatch compress) = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress) = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress, const CallbackPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param compress Specifies whether or not the queued batch requests + * should be compressed before being sent over the wire. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch compress, const Callback_Connection_flushBatchRequestsPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Flush any pending batch requests for this connection. + * This means all batch requests invoked on fixed proxies + * associated with the connection. + * @param result The asynchronous result object returned by the begin_ method. + */ + virtual void end_flushBatchRequests(const AsyncResultPtr& result) = 0; + + /** + * Set a close callback on the connection. The callback is called by the + * connection when it's closed. The callback is called from the + * Ice thread pool associated with the connection. If the callback needs + * more information about the closure, it can call {@link Connection#throwException}. + * @param callback The close callback object. + */ + virtual void setCloseCallback(const CloseCallbackPtr& callback) = 0; + + /** + * Set a heartbeat callback on the connection. The callback is called by the + * connection when a heartbeat is received. The callback is called + * from the Ice thread pool associated with the connection. + * @param callback The heartbeat callback object. + */ + virtual void setHeartbeatCallback(const HeartbeatCallbackPtr& callback) = 0; + + /** + * Send a heartbeat message. + */ + virtual void heartbeat() = 0; + + /** + * Send a heartbeat message. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_heartbeat() = 0; + + /** + * Send a heartbeat message. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_heartbeat(const CallbackPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Send a heartbeat message. + * @param cb Callback to be invoked when the invocation completes + * @param cookie Extra data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + virtual AsyncResultPtr begin_heartbeat(const Callback_Connection_heartbeatPtr& cb, const LocalObjectPtr& cookie = 0) = 0; + + /** + * Send a heartbeat message. + * @param result The asynchronous result object returned by the begin_ method. + */ + virtual void end_heartbeat(const AsyncResultPtr& result) = 0; + + /** + * Set the active connection management parameters. + * @param timeout The timeout value in seconds, must be >= 0. + * @param close The close condition + * @param heartbeat The hertbeat condition + */ + virtual void setACM(const IceUtil::Optional& timeout, const IceUtil::Optional& close, const IceUtil::Optional& heartbeat) = 0; + + /** + * Get the ACM parameters. + * @return The ACM parameters. + */ + virtual ACM getACM() ICE_NOEXCEPT = 0; + + /** + * Return the connection type. This corresponds to the endpoint + * type, i.e., "tcp", "udp", etc. + * @return The type of the connection. + */ + virtual ::std::string type() const ICE_NOEXCEPT = 0; + + /** + * Get the timeout for the connection. + * @return The connection's timeout. + */ + virtual Int timeout() const ICE_NOEXCEPT = 0; + + /** + * Return a description of the connection as human readable text, + * suitable for logging or error messages. + * @return The description of the connection as human readable + * text. + */ + virtual ::std::string toString() const ICE_NOEXCEPT = 0; + + /** + * Returns the connection information. + * @return The connection information. + */ + virtual ConnectionInfoPtr getInfo() const = 0; + + /** + * Set the connection buffer receive/send size. + * @param rcvSize The connection receive buffer size. + * @param sndSize The connection send buffer size. + */ + virtual void setBufferSize(Int rcvSize, Int sndSize) = 0; + + /** + * Throw an exception indicating the reason for connection closure. For example, + * {@link CloseConnectionException} is raised if the connection was closed gracefully, + * whereas {@link ConnectionManuallyClosedException} is raised if the connection was + * manually closed by the application. This operation does nothing if the connection is + * not yet closed. + */ + virtual void throwException() const = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Connection& lhs, const Connection& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Connection& lhs, const Connection& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the connection details of an IP connection + * \headerfile Ice/Ice.h + */ +class ICE_API IPConnectionInfo : public ConnectionInfo +{ +public: + + typedef IPConnectionInfoPtr PointerType; + + virtual ~IPConnectionInfo(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + IPConnectionInfo() : + localAddress(""), + localPort(-1), + remoteAddress(""), + remotePort(-1) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + */ + IPConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, ::Ice::Int localPort, const ::std::string& remoteAddress, ::Ice::Int remotePort) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + localAddress(localAddress), + localPort(localPort), + remoteAddress(remoteAddress), + remotePort(remotePort) + { + } + +#ifdef ICE_CPP11_COMPILER + IPConnectionInfo(const IPConnectionInfo&) = default; + IPConnectionInfo& operator=(const IPConnectionInfo&) = default; +#endif + + /** + * The local address. + */ + ::std::string localAddress; + /** + * The local port. + */ + ::Ice::Int localPort; + /** + * The remote address. + */ + ::std::string remoteAddress; + /** + * The remote port. + */ + ::Ice::Int remotePort; +}; + +/// \cond INTERNAL +inline bool operator==(const IPConnectionInfo& lhs, const IPConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const IPConnectionInfo& lhs, const IPConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the connection details of a TCP connection + * \headerfile Ice/Ice.h + */ +class ICE_API TCPConnectionInfo : public IPConnectionInfo +{ +public: + + typedef TCPConnectionInfoPtr PointerType; + + virtual ~TCPConnectionInfo(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + TCPConnectionInfo() : + rcvSize(0), + sndSize(0) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + * @param rcvSize The connection buffer receive size. + * @param sndSize The connection buffer send size. + */ + TCPConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, ::Ice::Int localPort, const ::std::string& remoteAddress, ::Ice::Int remotePort, ::Ice::Int rcvSize, ::Ice::Int sndSize) : + ::Ice::IPConnectionInfo(underlying, incoming, adapterName, connectionId, localAddress, localPort, remoteAddress, remotePort), + rcvSize(rcvSize), + sndSize(sndSize) + { + } + +#ifdef ICE_CPP11_COMPILER + TCPConnectionInfo(const TCPConnectionInfo&) = default; + TCPConnectionInfo& operator=(const TCPConnectionInfo&) = default; +#endif + + /** + * The connection buffer receive size. + */ + ::Ice::Int rcvSize; + /** + * The connection buffer send size. + */ + ::Ice::Int sndSize; +}; + +/// \cond INTERNAL +inline bool operator==(const TCPConnectionInfo& lhs, const TCPConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const TCPConnectionInfo& lhs, const TCPConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the connection details of a UDP connection + * \headerfile Ice/Ice.h + */ +class ICE_API UDPConnectionInfo : public IPConnectionInfo +{ +public: + + typedef UDPConnectionInfoPtr PointerType; + + virtual ~UDPConnectionInfo(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + UDPConnectionInfo() : + mcastPort(-1), + rcvSize(0), + sndSize(0) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param localAddress The local address. + * @param localPort The local port. + * @param remoteAddress The remote address. + * @param remotePort The remote port. + * @param mcastAddress The multicast address. + * @param mcastPort The multicast port. + * @param rcvSize The connection buffer receive size. + * @param sndSize The connection buffer send size. + */ + UDPConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& localAddress, ::Ice::Int localPort, const ::std::string& remoteAddress, ::Ice::Int remotePort, const ::std::string& mcastAddress, ::Ice::Int mcastPort, ::Ice::Int rcvSize, ::Ice::Int sndSize) : + ::Ice::IPConnectionInfo(underlying, incoming, adapterName, connectionId, localAddress, localPort, remoteAddress, remotePort), + mcastAddress(mcastAddress), + mcastPort(mcastPort), + rcvSize(rcvSize), + sndSize(sndSize) + { + } + +#ifdef ICE_CPP11_COMPILER + UDPConnectionInfo(const UDPConnectionInfo&) = default; + UDPConnectionInfo& operator=(const UDPConnectionInfo&) = default; +#endif + + /** + * The multicast address. + */ + ::std::string mcastAddress; + /** + * The multicast port. + */ + ::Ice::Int mcastPort; + /** + * The connection buffer receive size. + */ + ::Ice::Int rcvSize; + /** + * The connection buffer send size. + */ + ::Ice::Int sndSize; +}; + +/// \cond INTERNAL +inline bool operator==(const UDPConnectionInfo& lhs, const UDPConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const UDPConnectionInfo& lhs, const UDPConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the connection details of a WebSocket connection + * \headerfile Ice/Ice.h + */ +class ICE_API WSConnectionInfo : public ConnectionInfo +{ +public: + + typedef WSConnectionInfoPtr PointerType; + + virtual ~WSConnectionInfo(); + + WSConnectionInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param headers The headers from the HTTP upgrade request. + */ + WSConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::Ice::HeaderDict& headers) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + headers(headers) + { + } + +#ifdef ICE_CPP11_COMPILER + WSConnectionInfo(const WSConnectionInfo&) = default; + WSConnectionInfo& operator=(const WSConnectionInfo&) = default; +#endif + + /** + * The headers from the HTTP upgrade request. + */ + ::Ice::HeaderDict headers; +}; + +/// \cond INTERNAL +inline bool operator==(const WSConnectionInfo& lhs, const WSConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const WSConnectionInfo& lhs, const WSConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionAsync.h b/Sources/IceCpp/include/Ice/ConnectionAsync.h new file mode 100644 index 0000000..7a62256 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionAsync.h @@ -0,0 +1,302 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTION_ASYNC_H +#define ICE_CONNECTION_ASYNC_H + +#ifndef ICE_CPP11_MAPPING + +#include +#include + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Connection::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Connection_flushBatchRequests : public Callback_Connection_flushBatchRequests_Base, + public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC_Connection_flushBatchRequests(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::ConnectionPtr connection = result->getConnection(); + assert(connection); + try + { + connection->end_flushBatchRequests(result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + } + } + /// \endcond +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_flushBatchRequests. + */ +template Callback_Connection_flushBatchRequestsPtr +newCallback_Connection_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Connection_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_flushBatchRequests. + */ +template Callback_Connection_flushBatchRequestsPtr +newCallback_Connection_flushBatchRequests(T* instance, void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Connection_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Connection::begin_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class Callback_Connection_flushBatchRequests : public Callback_Connection_flushBatchRequests_Base, + public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + + Callback_Connection_flushBatchRequests(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::ConnectionPtr connection = result->getConnection(); + assert(connection); + try + { + connection->end_flushBatchRequests(result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + } + } + /// \endcond +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_flushBatchRequests. + */ +template Callback_Connection_flushBatchRequestsPtr +newCallback_Connection_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Connection_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_flushBatchRequests. + */ +template Callback_Connection_flushBatchRequestsPtr +newCallback_Connection_flushBatchRequests(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Connection_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Connection::begin_heartbeat. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_heartbeat. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Connection_heartbeat : public Callback_Connection_heartbeat_Base, + public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC_Connection_heartbeat(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& __result) const + { + ::Ice::ConnectionPtr __con = __result->getConnection(); + assert(__con); + try + { + __con->end_heartbeat(__result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(__result, ex); + } + } + /// \endcond +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_heartbeat. + */ +template Callback_Connection_heartbeatPtr +newCallback_Connection_heartbeat(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Connection_heartbeat(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_heartbeat. + */ +template Callback_Connection_heartbeatPtr +newCallback_Connection_heartbeat(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Connection_heartbeat(instance, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * Ice::Connection::begin_heartbeat. + * Create a wrapper instance by calling ::Ice::newCallback_Connection_heartbeat. + * \headerfile Ice/Ice.h + */ +template +class Callback_Connection_heartbeat : public Callback_Connection_heartbeat_Base, + public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + + Callback_Connection_heartbeat(const TPtr& obj, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, 0, excb, sentcb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& __result) const + { + ::Ice::ConnectionPtr __con = __result->getConnection(); + assert(__con); + try + { + __con->end_heartbeat(__result); + assert(false); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(__result, ex); + } + } + /// \endcond +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_heartbeat. + */ +template Callback_Connection_heartbeatPtr +newCallback_Connection_heartbeat(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Connection_heartbeat(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * Ice::Connection::begin_heartbeat. + */ +template Callback_Connection_heartbeatPtr +newCallback_Connection_heartbeat(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Connection_heartbeat(instance, excb, sentcb); +} + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionF.h b/Sources/IceCpp/include/Ice/ConnectionF.h new file mode 100644 index 0000000..767af6d --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionF.h @@ -0,0 +1,119 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ConnectionF_h__ +#define __Ice_ConnectionF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ConnectionInfo; +class WSConnectionInfo; +class Connection; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ConnectionInfoPtr = ::std::shared_ptr; + +using WSConnectionInfoPtr = ::std::shared_ptr; + +using ConnectionPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionInfo> ConnectionInfoPtr; + +class WSConnectionInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(WSConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< WSConnectionInfo> WSConnectionInfoPtr; + +class Connection; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Connection*); +/// \endcond +typedef ::IceInternal::Handle< Connection> ConnectionPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionFactory.h b/Sources/IceCpp/include/Ice/ConnectionFactory.h new file mode 100644 index 0000000..abe938b --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionFactory.h @@ -0,0 +1,264 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTION_FACTORY_H +#define ICE_CONNECTION_FACTORY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Ice +{ + +class LocalException; +class ObjectAdapterI; +ICE_DEFINE_PTR(ObjectAdapterIPtr, ObjectAdapterI); + +} + +namespace IceInternal +{ + +class OutgoingConnectionFactory : public virtual IceUtil::Shared, public IceUtil::Monitor +{ +public: + + class CreateConnectionCallback : public virtual IceUtil::Shared + { + public: + + virtual void setConnection(const Ice::ConnectionIPtr&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle CreateConnectionCallbackPtr; + + void destroy(); + + void updateConnectionObservers(); + + void waitUntilFinished(); + + void create(const std::vector&, bool, Ice::EndpointSelectionType, const CreateConnectionCallbackPtr&); + void setRouterInfo(const RouterInfoPtr&); + void removeAdapter(const Ice::ObjectAdapterPtr&); + void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, Ice::CompressBatch); + + OutgoingConnectionFactory(const Ice::CommunicatorPtr&, const InstancePtr&); + virtual ~OutgoingConnectionFactory(); + friend class Instance; + +private: + + struct ConnectorInfo + { + ConnectorInfo(const ConnectorPtr& c, const EndpointIPtr& e) : connector(c), endpoint(e) + { + } + + bool operator==(const ConnectorInfo& other) const; + + ConnectorPtr connector; + EndpointIPtr endpoint; + }; + + class ConnectCallback : public Ice::ConnectionI::StartCallback, + public IceInternal::EndpointI_connectors +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif + + { + public: + + ConnectCallback(const InstancePtr&, const OutgoingConnectionFactoryPtr&, const std::vector&, bool, + const CreateConnectionCallbackPtr&, Ice::EndpointSelectionType); + + virtual void connectionStartCompleted(const Ice::ConnectionIPtr&); + virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&); + + virtual void connectors(const std::vector&); + virtual void exception(const Ice::LocalException&); + + void getConnectors(); + void nextEndpoint(); + + void getConnection(); + void nextConnector(); + + void setConnection(const Ice::ConnectionIPtr&, bool); + void setException(const Ice::LocalException&); + + bool hasConnector(const ConnectorInfo&); + bool removeConnectors(const std::vector&); + void removeFromPending(); + + bool operator<(const ConnectCallback&) const; + + private: + + bool connectionStartFailedImpl(const Ice::LocalException&); + + const InstancePtr _instance; + const OutgoingConnectionFactoryPtr _factory; + const std::vector _endpoints; + const bool _hasMore; + const CreateConnectionCallbackPtr _callback; + const Ice::EndpointSelectionType _selType; + Ice::Instrumentation::ObserverPtr _observer; + std::vector::const_iterator _endpointsIter; + std::vector _connectors; + std::vector::const_iterator _iter; + }; + ICE_DEFINE_PTR(ConnectCallbackPtr, ConnectCallback); + friend class ConnectCallback; + + std::vector applyOverrides(const std::vector&); + Ice::ConnectionIPtr findConnection(const std::vector&, bool&); + void incPendingConnectCount(); + void decPendingConnectCount(); + Ice::ConnectionIPtr getConnection(const std::vector&, const ConnectCallbackPtr&, bool&); + void finishGetConnection(const std::vector&, const ConnectorInfo&, const Ice::ConnectionIPtr&, + const ConnectCallbackPtr&); + void finishGetConnection(const std::vector&, const Ice::LocalException&, const ConnectCallbackPtr&); + + bool addToPending(const ConnectCallbackPtr&, const std::vector&); + void removeFromPending(const ConnectCallbackPtr&, const std::vector&); + + Ice::ConnectionIPtr findConnection(const std::vector&, bool&); + Ice::ConnectionIPtr createConnection(const TransceiverPtr&, const ConnectorInfo&); + + void handleException(const Ice::LocalException&, bool); + void handleConnectionException(const Ice::LocalException&, bool); + + Ice::CommunicatorPtr _communicator; + const InstancePtr _instance; + const FactoryACMMonitorPtr _monitor; + bool _destroyed; + + std::multimap _connections; + std::map > _pending; + +#ifdef ICE_CPP11_MAPPING + std::multimap> _connectionsByEndpoint; +#else + std::multimap _connectionsByEndpoint; +#endif + int _pendingConnectCount; +}; + +class IncomingConnectionFactory : public EventHandler, + public Ice::ConnectionI::StartCallback, + public IceUtil::Monitor +{ +public: + + void activate(); + void hold(); + void destroy(); + + void startAcceptor(); + void stopAcceptor(); + + void updateConnectionObservers(); + + void waitUntilHolding() const; + void waitUntilFinished(); + + bool isLocal(const EndpointIPtr&) const; + EndpointIPtr endpoint() const; + std::list connections() const; + void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, Ice::CompressBatch); + + // + // Operations from EventHandler + // + +#if defined(ICE_USE_IOCP) + virtual bool startAsync(SocketOperation); + virtual bool finishAsync(SocketOperation); +#endif + + virtual void message(ThreadPoolCurrent&); + virtual void finished(ThreadPoolCurrent&, bool); +#if TARGET_OS_IPHONE != 0 + void finish(); +#endif + virtual std::string toString() const; + virtual NativeInfoPtr getNativeInfo(); + + virtual void connectionStartCompleted(const Ice::ConnectionIPtr&); + virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&); + + IncomingConnectionFactory(const InstancePtr&, const EndpointIPtr&, const EndpointIPtr&, + const Ice::ObjectAdapterIPtr&); + void initialize(); + virtual ~IncomingConnectionFactory(); + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(EventHandler::shared_from_this()); + } +#endif + +private: + + friend class Ice::ObjectAdapterI; + + enum State + { + StateActive, + StateHolding, + StateClosed, + StateFinished + }; + + void setState(State); + + void createAcceptor(); + void closeAcceptor(); + + const InstancePtr _instance; + const FactoryACMMonitorPtr _monitor; + + AcceptorPtr _acceptor; + const TransceiverPtr _transceiver; + EndpointIPtr _endpoint; + EndpointIPtr _publishedEndpoint; + + bool _acceptorStarted; + bool _acceptorStopped; + + Ice::ObjectAdapterIPtr _adapter; + const bool _warn; + std::set _connections; + State _state; + +#if defined(ICE_USE_IOCP) + IceInternal::UniquePtr _acceptorException; +#endif +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionFactoryF.h b/Sources/IceCpp/include/Ice/ConnectionFactoryF.h new file mode 100644 index 0000000..40829f3 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionFactoryF.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTION_FACTORY_F_H +#define ICE_CONNECTION_FACTORY_F_H + +#include + +#include + +namespace IceInternal +{ + +class OutgoingConnectionFactory; +IceUtil::Shared* upCast(OutgoingConnectionFactory*); +typedef IceInternal::Handle OutgoingConnectionFactoryPtr; + +class IncomingConnectionFactory; + +#ifdef ICE_CPP11_MAPPING +using IncomingConnectionFactoryPtr = ::std::shared_ptr; +#else +IceUtil::Shared* upCast(IncomingConnectionFactory*); +typedef IceInternal::Handle IncomingConnectionFactoryPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionI.h b/Sources/IceCpp/include/Ice/ConnectionI.h new file mode 100644 index 0000000..dd1ec43 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionI.h @@ -0,0 +1,389 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTION_I_H +#define ICE_CONNECTION_I_H + +#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 + +#ifndef ICE_HAS_BZIP2 +# define ICE_HAS_BZIP2 +#endif + +namespace Ice +{ + +class LocalException; +class ObjectAdapterI; +ICE_DEFINE_PTR(ObjectAdapterIPtr, ObjectAdapterI); + +class ConnectionI : public Connection, + public IceInternal::EventHandler, + public IceInternal::ResponseHandler, + public IceInternal::CancellationHandler, + public IceUtil::Monitor +{ + class Observer : public IceInternal::ObserverHelperT + { + public: + + Observer(); + + void startRead(const IceInternal::Buffer&); + void finishRead(const IceInternal::Buffer&); + void startWrite(const IceInternal::Buffer&); + void finishWrite(const IceInternal::Buffer&); + + void attach(const Ice::Instrumentation::ConnectionObserverPtr&); + + private: + + Ice::Byte* _readStreamPos; + Ice::Byte* _writeStreamPos; + }; + +public: + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::dynamic_pointer_cast(VirtualEnableSharedFromThisBase::shared_from_this()); + } +#endif + + struct OutgoingMessage + { + OutgoingMessage(Ice::OutputStream* str, bool comp) : + stream(str), compress(comp), requestId(0), adopted(false) +#if defined(ICE_USE_IOCP) + , isSent(false), invokeSent(false), receivedReply(false) +#endif + { + } + + OutgoingMessage(const IceInternal::OutgoingAsyncBasePtr& o, Ice::OutputStream* str, + bool comp, int rid) : + stream(str), outAsync(o), compress(comp), requestId(rid), adopted(false) +#if defined(ICE_USE_IOCP) + , isSent(false), invokeSent(false), receivedReply(false) +#endif + { + } + + void adopt(Ice::OutputStream*); + void canceled(bool); + bool sent(); + void completed(const Ice::LocalException&); + + Ice::OutputStream* stream; + IceInternal::OutgoingAsyncBasePtr outAsync; + bool compress; + int requestId; + bool adopted; +#if defined(ICE_USE_IOCP) + bool isSent; + bool invokeSent; + bool receivedReply; +#endif + }; + +#ifdef ICE_CPP11_MAPPING + class StartCallback + { + public: + + virtual void connectionStartCompleted(const ConnectionIPtr&) = 0; + virtual void connectionStartFailed(const ConnectionIPtr&, const Ice::LocalException&) = 0; + }; + using StartCallbackPtr = ::std::shared_ptr; +#else + class StartCallback : public virtual IceUtil::Shared + { + public: + + virtual void connectionStartCompleted(const ConnectionIPtr&) = 0; + virtual void connectionStartFailed(const ConnectionIPtr&, const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle StartCallbackPtr; +#endif + + enum DestructionReason + { + ObjectAdapterDeactivated, + CommunicatorDestroyed + }; + + void start(const StartCallbackPtr&); + void activate(); + void hold(); + void destroy(DestructionReason); + virtual void close(ConnectionClose) ICE_NOEXCEPT; // From Connection. + + bool isActiveOrHolding() const; + bool isFinished() const; + + virtual void throwException() const; // From Connection. Throws the connection exception if destroyed. + + void waitUntilHolding() const; + void waitUntilFinished(); // Not const, as this might close the connection upon timeout. + + void updateObserver(); + + void monitor(const IceUtil::Time&, const IceInternal::ACMConfig&); + + IceInternal::AsyncStatus sendAsyncRequest(const IceInternal::OutgoingAsyncBasePtr&, bool, bool, int); + + IceInternal::BatchRequestQueuePtr getBatchRequestQueue() const; + +#ifdef ICE_CPP11_MAPPING + virtual std::function + flushBatchRequestsAsync(CompressBatch, + ::std::function, + ::std::function = nullptr); +#else + virtual void flushBatchRequests(CompressBatch); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch, const CallbackPtr&, const LocalObjectPtr& = 0); + virtual AsyncResultPtr begin_flushBatchRequests(CompressBatch, + const Callback_Connection_flushBatchRequestsPtr&, + const LocalObjectPtr& = 0); + + virtual void end_flushBatchRequests(const AsyncResultPtr&); +#endif + + virtual void setCloseCallback(ICE_IN(ICE_DELEGATE(CloseCallback))); + virtual void setHeartbeatCallback(ICE_IN(ICE_DELEGATE(HeartbeatCallback))); + + virtual void heartbeat(); + +#ifdef ICE_CPP11_MAPPING + virtual std::function + heartbeatAsync(::std::function, ::std::function = nullptr); +#else + virtual AsyncResultPtr begin_heartbeat(); + virtual AsyncResultPtr begin_heartbeat(const CallbackPtr&, const LocalObjectPtr& = 0); + virtual AsyncResultPtr begin_heartbeat(const Callback_Connection_heartbeatPtr&, const LocalObjectPtr& = 0); + + virtual void end_heartbeat(const AsyncResultPtr&); +#endif + + virtual void setACM(const IceUtil::Optional&, + const IceUtil::Optional&, + const IceUtil::Optional&); + virtual ACM getACM() ICE_NOEXCEPT; + + virtual void asyncRequestCanceled(const IceInternal::OutgoingAsyncBasePtr&, const LocalException&); + + virtual void sendResponse(Int, Ice::OutputStream*, Byte, bool); + virtual void sendNoResponse(); + virtual bool systemException(Int, const SystemException&, bool); + virtual void invokeException(Ice::Int, const LocalException&, int, bool); + + IceInternal::EndpointIPtr endpoint() const; + IceInternal::ConnectorPtr connector() const; + + virtual void setAdapter(const ObjectAdapterPtr&); // From Connection. + virtual ObjectAdapterPtr getAdapter() const ICE_NOEXCEPT; // From Connection. + virtual EndpointPtr getEndpoint() const ICE_NOEXCEPT; // From Connection. + virtual ObjectPrxPtr createProxy(const Identity& ident) const; // From Connection. + + void setAdapterAndServantManager(const ObjectAdapterPtr&, const IceInternal::ServantManagerPtr&); + + // + // Operations from EventHandler + // +#if defined(ICE_USE_IOCP) + bool startAsync(IceInternal::SocketOperation); + bool finishAsync(IceInternal::SocketOperation); +#endif + + virtual void message(IceInternal::ThreadPoolCurrent&); + virtual void finished(IceInternal::ThreadPoolCurrent&, bool); + virtual std::string toString() const ICE_NOEXCEPT; // From Connection and EvantHandler. + virtual IceInternal::NativeInfoPtr getNativeInfo(); + + void timedOut(); + + virtual std::string type() const ICE_NOEXCEPT; // From Connection. + virtual Ice::Int timeout() const ICE_NOEXCEPT; // From Connection. + virtual ConnectionInfoPtr getInfo() const; // From Connection + + virtual void setBufferSize(Ice::Int rcvSize, Ice::Int sndSize); // From Connection + + void exception(const LocalException&); + + void dispatch(const StartCallbackPtr&, const std::vector&, Byte, Int, Int, + const IceInternal::ServantManagerPtr&, const ObjectAdapterPtr&, + const IceInternal::OutgoingAsyncBasePtr&, + const ICE_DELEGATE(HeartbeatCallback)&, Ice::InputStream&); + void finish(bool); + + void closeCallback(const ICE_DELEGATE(CloseCallback)&); + + virtual ~ConnectionI(); + +private: + + ConnectionI(const Ice::CommunicatorPtr&, const IceInternal::InstancePtr&, const IceInternal::ACMMonitorPtr&, + const IceInternal::TransceiverPtr&, const IceInternal::ConnectorPtr&, + const IceInternal::EndpointIPtr&, const ObjectAdapterIPtr&); + + static ConnectionIPtr + create(const Ice::CommunicatorPtr&, const IceInternal::InstancePtr&, const IceInternal::ACMMonitorPtr&, + const IceInternal::TransceiverPtr&, const IceInternal::ConnectorPtr&, + const IceInternal::EndpointIPtr&, const ObjectAdapterIPtr&); + + enum State + { + StateNotInitialized, + StateNotValidated, + StateActive, + StateHolding, + StateClosing, + StateClosingPending, + StateClosed, + StateFinished + }; + + friend class IceInternal::IncomingConnectionFactory; + friend class IceInternal::OutgoingConnectionFactory; + + void setState(State, const LocalException&); + void setState(State); + + void initiateShutdown(); + void sendHeartbeatNow(); + + bool initialize(IceInternal::SocketOperation = IceInternal::SocketOperationNone); + bool validate(IceInternal::SocketOperation = IceInternal::SocketOperationNone); + IceInternal::SocketOperation sendNextMessage(std::vector&); + IceInternal::AsyncStatus sendMessage(OutgoingMessage&); + +#ifdef ICE_HAS_BZIP2 + void doCompress(Ice::OutputStream&, Ice::OutputStream&); + void doUncompress(Ice::InputStream&, Ice::InputStream&); +#endif + + IceInternal::SocketOperation parseMessage(Ice::InputStream&, Int&, Int&, Byte&, + IceInternal::ServantManagerPtr&, ObjectAdapterPtr&, + IceInternal::OutgoingAsyncBasePtr&, ICE_DELEGATE(HeartbeatCallback)&, int&); + + void invokeAll(Ice::InputStream&, Int, Int, Byte, + const IceInternal::ServantManagerPtr&, const ObjectAdapterPtr&); + + void scheduleTimeout(IceInternal::SocketOperation status); + void unscheduleTimeout(IceInternal::SocketOperation status); + + Ice::ConnectionInfoPtr initConnectionInfo() const; + Ice::Instrumentation::ConnectionState toConnectionState(State) const; + + IceInternal::SocketOperation read(IceInternal::Buffer&); + IceInternal::SocketOperation write(IceInternal::Buffer&); + + void reap(); + +#ifndef ICE_CPP11_MAPPING + AsyncResultPtr _iceI_begin_flushBatchRequests(CompressBatch, + const IceInternal::CallbackBasePtr&, + const LocalObjectPtr&); + AsyncResultPtr _iceI_begin_heartbeat(const IceInternal::CallbackBasePtr&, const LocalObjectPtr&); +#endif + + Ice::CommunicatorPtr _communicator; + const IceInternal::InstancePtr _instance; + IceInternal::ACMMonitorPtr _monitor; + const IceInternal::TransceiverPtr _transceiver; + const std::string _desc; + const std::string _type; + const IceInternal::ConnectorPtr _connector; + const IceInternal::EndpointIPtr _endpoint; + + mutable Ice::ConnectionInfoPtr _info; + + ObjectAdapterPtr _adapter; + IceInternal::ServantManagerPtr _servantManager; + + const bool _dispatcher; + const LoggerPtr _logger; + const IceInternal::TraceLevelsPtr _traceLevels; + const IceInternal::ThreadPoolPtr _threadPool; + + const IceUtil::TimerPtr _timer; + const IceUtil::TimerTaskPtr _writeTimeout; + bool _writeTimeoutScheduled; + const IceUtil::TimerTaskPtr _readTimeout; + bool _readTimeoutScheduled; + + StartCallbackPtr _startCallback; + + const bool _warn; + const bool _warnUdp; + + IceUtil::Time _acmLastActivity; + + const int _compressionLevel; + + Int _nextRequestId; + + std::map _asyncRequests; + std::map::iterator _asyncRequestsHint; + + IceInternal::UniquePtr _exception; + + const size_t _messageSizeMax; + IceInternal::BatchRequestQueuePtr _batchRequestQueue; + + std::deque _sendStreams; + + Ice::InputStream _readStream; + bool _readHeader; + Ice::OutputStream _writeStream; + + Observer _observer; + + int _dispatchCount; + + State _state; // The current state. + bool _shutdownInitiated; + bool _initialized; + bool _validated; + + ICE_DELEGATE(CloseCallback) _closeCallback; + ICE_DELEGATE(HeartbeatCallback) _heartbeatCallback; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionIF.h b/Sources/IceCpp/include/Ice/ConnectionIF.h new file mode 100644 index 0000000..ae1dd9c --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionIF.h @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTIONI_F_H +#define ICE_CONNECTIONI_F_H + +#include +#include + +namespace Ice +{ + +/// \cond INTERNAL +class ConnectionI; +#ifdef ICE_CPP11_MAPPING // C++11 mapping +using ConnectionIPtr = ::std::shared_ptr; +#else // C++98 mapping +ICE_API Ice::LocalObject* upCast(Ice::ConnectionI*); +typedef IceInternal::Handle ConnectionIPtr; +#endif +/// \endcond + +} + +namespace IceInternal +{ + +enum AsyncStatus +{ + AsyncStatusQueued = 0, + AsyncStatusSent = 1, + AsyncStatusInvokeSentCallback = 2 +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectionRequestHandler.h b/Sources/IceCpp/include/Ice/ConnectionRequestHandler.h new file mode 100644 index 0000000..097aee7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectionRequestHandler.h @@ -0,0 +1,41 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTION_REQUEST_HANDLER_H +#define ICE_CONNECTION_REQUEST_HANDLER_H + +#include +#include +#include + +namespace IceInternal +{ + +class ConnectionRequestHandler ICE_FINAL : public RequestHandler +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + ConnectionRequestHandler(const ReferencePtr&, const Ice::ConnectionIPtr&, bool); + + virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); + + virtual AsyncStatus sendAsyncRequest(const ProxyOutgoingAsyncBasePtr&); + + virtual void asyncRequestCanceled(const OutgoingAsyncBasePtr&, const Ice::LocalException&); + + virtual Ice::ConnectionIPtr getConnection(); + virtual Ice::ConnectionIPtr waitForConnection(); + +private: + + Ice::ConnectionIPtr _connection; + bool _compress; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Connector.h b/Sources/IceCpp/include/Ice/Connector.h new file mode 100644 index 0000000..1daa7a1 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Connector.h @@ -0,0 +1,32 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTOR_H +#define ICE_CONNECTOR_H + +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API Connector : public ::IceUtil::Shared +{ +public: + + virtual ~Connector(); + + virtual TransceiverPtr connect() = 0; + + virtual Ice::Short type() const = 0; + virtual std::string toString() const = 0; + + virtual bool operator==(const Connector&) const = 0; + virtual bool operator<(const Connector&) const = 0; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConnectorF.h b/Sources/IceCpp/include/Ice/ConnectorF.h new file mode 100644 index 0000000..22a5a82 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConnectorF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONNECTOR_F_H +#define ICE_CONNECTOR_F_H + +#include + +#include + +namespace IceInternal +{ + +class Connector; +ICE_API IceUtil::Shared* upCast(Connector*); +typedef Handle ConnectorPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ConsoleUtil.h b/Sources/IceCpp/include/Ice/ConsoleUtil.h new file mode 100644 index 0000000..3faf8e0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ConsoleUtil.h @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_CONSOLE_UTIL_H +#define ICE_CONSOLE_UTIL_H + +#include + +namespace IceInternal +{ + +using IceUtilInternal::consoleOut; +using IceUtilInternal::consoleErr; + +#if defined(_WIN32) +using IceUtilInternal::endl; +using IceUtilInternal::flush; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Current.h b/Sources/IceCpp/include/Ice/Current.h new file mode 100644 index 0000000..bf6c3ce --- /dev/null +++ b/Sources/IceCpp/include/Ice/Current.h @@ -0,0 +1,322 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Current.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Current_h__ +#define __Ice_Current_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * A request context. Context is used to transmit metadata about a + * request from the server to the client, such as Quality-of-Service + * (QoS) parameters. Each operation on the client has a Context as + * its implicit final parameter. + */ +using Context = ::std::map<::std::string, ::std::string>; + +/** + * Determines the retry behavior an invocation in case of a (potentially) recoverable error. + */ +enum class OperationMode : unsigned char +{ + /** + * Ordinary operations have Normal mode. These operations + * modify object state; invoking such an operation twice in a row + * has different semantics than invoking it once. The Ice run time + * guarantees that it will not violate at-most-once semantics for + * Normal operations. + */ + Normal, + /** + * Operations that use the Slice nonmutating keyword must not + * modify object state. For C++, nonmutating operations generate + * const member functions in the skeleton. In addition, the Ice + * run time will attempt to transparently recover from certain + * run-time errors by re-issuing a failed request and propagate + * the failure to the application only if the second attempt + * fails. + * + *

Nonmutating is deprecated; Use the + * idempotent keyword instead. For C++, to retain the mapping + * of nonmutating operations to C++ const + * member functions, use the ["cpp:const"] metadata + * directive. + */ + Nonmutating, + /** + * Operations that use the Slice idempotent keyword can modify + * object state, but invoking an operation twice in a row must + * result in the same object state as invoking it once. For + * example, x = 1 is an idempotent statement, + * whereas x += 1 is not. For idempotent + * operations, the Ice run-time uses the same retry behavior + * as for nonmutating operations in case of a potentially + * recoverable error. + */ + Idempotent +}; + +/** + * Information about the current method invocation for servers. Each + * operation on the server has a Current as its implicit final + * parameter. Current is mostly used for Ice services. Most + * applications ignore this parameter. + * \headerfile Ice/Ice.h + */ +struct Current +{ + /** + * The object adapter. + */ + ::std::shared_ptr<::Ice::ObjectAdapter> adapter; + /** + * Information about the connection over which the current method + * invocation was received. If the invocation is direct due to + * collocation optimization, this value is set to null. + */ + ::std::shared_ptr<::Ice::Connection> con; + /** + * The Ice object identity. + */ + ::Ice::Identity id; + /** + * The facet. + */ + ::std::string facet; + /** + * The operation name. + */ + ::std::string operation; + /** + * The mode of the operation. + */ + ::Ice::OperationMode mode; + /** + * The request context, as received from the client. + */ + ::Ice::Context ctx; + /** + * The request id unless oneway (0). + */ + int requestId; + /** + * The encoding version used to encode the input and output parameters. + */ + ::Ice::EncodingVersion encoding; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple&, const ::std::shared_ptr<::Ice::Connection>&, const ::Ice::Identity&, const ::std::string&, const ::std::string&, const ::Ice::OperationMode&, const ::Ice::Context&, const int&, const ::Ice::EncodingVersion&> ice_tuple() const + { + return std::tie(adapter, con, id, facet, operation, mode, ctx, requestId, encoding); + } +}; + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::OperationMode> +{ + static const StreamHelperCategory helper = StreamHelperCategoryEnum; + static const int minValue = 0; + static const int maxValue = 2; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +/** + * A request context. Context is used to transmit metadata about a + * request from the server to the client, such as Quality-of-Service + * (QoS) parameters. Each operation on the client has a Context as + * its implicit final parameter. + */ +typedef ::std::map< ::std::string, ::std::string> Context; + +/** + * Determines the retry behavior an invocation in case of a (potentially) recoverable error. + */ +enum OperationMode +{ + /** + * Ordinary operations have Normal mode. These operations + * modify object state; invoking such an operation twice in a row + * has different semantics than invoking it once. The Ice run time + * guarantees that it will not violate at-most-once semantics for + * Normal operations. + */ + Normal, + /** + * Operations that use the Slice nonmutating keyword must not + * modify object state. For C++, nonmutating operations generate + * const member functions in the skeleton. In addition, the Ice + * run time will attempt to transparently recover from certain + * run-time errors by re-issuing a failed request and propagate + * the failure to the application only if the second attempt + * fails. + * + *

Nonmutating is deprecated; Use the + * idempotent keyword instead. For C++, to retain the mapping + * of nonmutating operations to C++ const + * member functions, use the ["cpp:const"] metadata + * directive. + */ + Nonmutating, + /** + * Operations that use the Slice idempotent keyword can modify + * object state, but invoking an operation twice in a row must + * result in the same object state as invoking it once. For + * example, x = 1 is an idempotent statement, + * whereas x += 1 is not. For idempotent + * operations, the Ice run-time uses the same retry behavior + * as for nonmutating operations in case of a potentially + * recoverable error. + */ + Idempotent +}; + +/** + * Information about the current method invocation for servers. Each + * operation on the server has a Current as its implicit final + * parameter. Current is mostly used for Ice services. Most + * applications ignore this parameter. + * \headerfile Ice/Ice.h + */ +struct Current +{ + /** + * The object adapter. + */ + ::Ice::ObjectAdapterPtr adapter; + /** + * Information about the connection over which the current method + * invocation was received. If the invocation is direct due to + * collocation optimization, this value is set to null. + */ + ::Ice::ConnectionPtr con; + /** + * The Ice object identity. + */ + ::Ice::Identity id; + /** + * The facet. + */ + ::std::string facet; + /** + * The operation name. + */ + ::std::string operation; + /** + * The mode of the operation. + */ + ::Ice::OperationMode mode; + /** + * The request context, as received from the client. + */ + ::Ice::Context ctx; + /** + * The request id unless oneway (0). + */ + ::Ice::Int requestId; + /** + * The encoding version used to encode the input and output parameters. + */ + ::Ice::EncodingVersion encoding; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::OperationMode> +{ + static const StreamHelperCategory helper = StreamHelperCategoryEnum; + static const int minValue = 0; + static const int maxValue = 2; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/DefaultValueFactory.h b/Sources/IceCpp/include/Ice/DefaultValueFactory.h new file mode 100644 index 0000000..645e8f1 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DefaultValueFactory.h @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DEFAULT_VALUE_FACTORY_H +#define ICE_DEFAULT_VALUE_FACTORY_H + +#include +#include + +namespace IceInternal +{ + +#ifdef ICE_CPP11_MAPPING + +template +::std::shared_ptr<::Ice::Value> +#ifdef NDEBUG +defaultValueFactory(const std::string&) +#else +defaultValueFactory(const std::string& typeId) +#endif +{ + assert(typeId == V::ice_staticId()); + return std::make_shared(); +} + +#else + +template +class DefaultValueFactory : public Ice::ValueFactory +{ +public: + + DefaultValueFactory(const ::std::string& typeId) : + _typeId(typeId) + { + } + +#ifndef NDEBUG + virtual ::Ice::ObjectPtr create(const ::std::string& typeId) +#else + virtual ::Ice::ObjectPtr create(const ::std::string&) +#endif + { + assert(typeId == _typeId); + return new V; + } + +private: + const ::std::string _typeId; +}; + +#endif + +} +#endif diff --git a/Sources/IceCpp/include/Ice/DefaultsAndOverrides.h b/Sources/IceCpp/include/Ice/DefaultsAndOverrides.h new file mode 100644 index 0000000..fbff736 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DefaultsAndOverrides.h @@ -0,0 +1,52 @@ + +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DEFAULTS_AND_OVERRIDES_H +#define ICE_DEFAULTS_AND_OVERRIDES_H + +#include +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class DefaultsAndOverrides : public ::IceUtil::Shared +{ +public: + + DefaultsAndOverrides(const ::Ice::PropertiesPtr&, const ::Ice::LoggerPtr&); + + std::string defaultHost; + Address defaultSourceAddress; + std::string defaultProtocol; + bool defaultCollocationOptimization; + Ice::EndpointSelectionType defaultEndpointSelection; + int defaultTimeout; + int defaultInvocationTimeout; + int defaultLocatorCacheTimeout; + bool defaultPreferSecure; + Ice::EncodingVersion defaultEncoding; + Ice::FormatType defaultFormat; + + bool overrideTimeout; + Ice::Int overrideTimeoutValue; + bool overrideConnectTimeout; + Ice::Int overrideConnectTimeoutValue; + bool overrideCloseTimeout; + Ice::Int overrideCloseTimeoutValue; + bool overrideCompress; + bool overrideCompressValue; + bool overrideSecure; + bool overrideSecureValue; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/DefaultsAndOverridesF.h b/Sources/IceCpp/include/Ice/DefaultsAndOverridesF.h new file mode 100644 index 0000000..7f1d987 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DefaultsAndOverridesF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DEFAULTS_AND_OVERRIDES_F_H +#define ICE_DEFAULTS_AND_OVERRIDES_F_H + +#include + +#include + +namespace IceInternal +{ + +class DefaultsAndOverrides; +IceUtil::Shared* upCast(DefaultsAndOverrides*); +typedef Handle DefaultsAndOverridesPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/DispatchInterceptor.h b/Sources/IceCpp/include/Ice/DispatchInterceptor.h new file mode 100644 index 0000000..c436902 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DispatchInterceptor.h @@ -0,0 +1,41 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DISPATCH_INTERCEPTOR_H +#define ICE_DISPATCH_INTERCEPTOR_H + +#include + +namespace Ice +{ + +/** + * Base class for a dispatch interceptor, which is a servant that dispatches requests + * to another servant. A subclass must implement the dispatch method. A dispatch interceptor + * can be registered with an object adapter just like any other servant. + * \headerfile Ice/Ice.h + */ +class ICE_API DispatchInterceptor : public virtual Object +{ +public: + + /** + * Called by the Ice run time when a new request needs to be dispatched. The implementation + * must eventually call ice_dispatch on the delegate servant and pass the given request object. + * @param req An opaque object representing the request to be dispatched. + * @return True if the request was dispatched synchronously, or false if the request was + * dispatched asynchronously. + */ + virtual bool dispatch(Request& req) = 0; + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond +}; + +ICE_DEFINE_PTR(DispatchInterceptorPtr, DispatchInterceptor); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Dispatcher.h b/Sources/IceCpp/include/Ice/Dispatcher.h new file mode 100644 index 0000000..46939d8 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Dispatcher.h @@ -0,0 +1,67 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DISPATCHER_H +#define ICE_DISPATCHER_H + +#if !defined(ICE_CPP11_MAPPING) || defined(ICE_BUILDING_SRC) +// +// Part of the C++98 mapping, and "internal" definitions when building Ice +// with the C++11 mapping +// + +#include +#include +#include +#include + +namespace Ice +{ + +/** + * Encapsulates all the details of a request dispatch or AMI callback. + * The application must eventually invoke run to dispatch the call. + * \headerfile Ice/Ice.h + */ +class ICE_API DispatcherCall : public virtual IceUtil::Shared +{ +public: + + virtual ~DispatcherCall(); + + /** + * Dispatches the call. + */ + virtual void run() = 0; +}; + +typedef IceUtil::Handle DispatcherCallPtr; + +/** + * Base class for a dispatcher. A subclass must define the dispatch method. + * The dispatcher can be installed via InitializationData. + * \headerfile Ice/Ice.h + */ +class ICE_API Dispatcher : public virtual IceUtil::Shared +{ +public: + + virtual ~Dispatcher(); + + /** + * Called by the Ice run time when an incoming request or an AMI callback needs to + * be dispatched. The implementation must eventually invoke run on the call object. + * @param call An object representing the call that must be dispatched. + * @param connection The connection object associated with the call, or nil if no + * connection is associated with the call. + */ + virtual void dispatch(const DispatcherCallPtr& call, const ConnectionPtr& connection) = 0; +}; + +typedef IceUtil::Handle DispatcherPtr; + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/DynamicLibrary.h b/Sources/IceCpp/include/Ice/DynamicLibrary.h new file mode 100644 index 0000000..ed092d4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DynamicLibrary.h @@ -0,0 +1,102 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DYNAMIC_LIBRARY_H +#define ICE_DYNAMIC_LIBRARY_H + +#include +#include + +namespace IceInternal +{ + +class ICE_API DynamicLibrary : public ::IceUtil::Shared +{ +public: + + DynamicLibrary(); + virtual ~DynamicLibrary(); + +#ifdef _WIN32 + typedef FARPROC symbol_type; +#else + typedef void* symbol_type; +#endif + + // + // Load an entry point. This is really a convenience function + // which combines calls to load() and getSymbol(). However, it + // does add some value. + // + // An entry point has the following format: + // + // name[,version]:function + // + // The name of the library is constructed from the given + // information. If no version is supplied and the boolean + // argument is true, the Ice version (10 * major + minor) is + // used instead. + // + // For example, consider the following entry point: + // + // foo:create + // + // This would result in libfoo.so.11 (Unix) and foo11.dll + // (Windows), where the Ice version is 1.1.x. + // + // Now consider this entry point: + // + // foo,12:create + // + // The library names in this case are libfoo.so.12 (Unix) and + // foo12.dll (Windows). + // + // On Windows platforms, a 'd' is appended to the version for + // debug builds. + // + // Returns 0 if a failure occurred. + // + symbol_type loadEntryPoint(const std::string&, bool = true); + + // + // Open a library with the given path. + // + bool load(const std::string&); + + // + // Retrieve a symbol from the library. Returns 0 if no match is found. + // + symbol_type getSymbol(const std::string&); + + // + // Get the error message for the last failure. + // + const std::string& getErrorMessage() const; + +private: + +#ifdef _WIN32 + HINSTANCE _hnd; +#else + void* _hnd; +#endif + std::string _err; +}; + +class ICE_API DynamicLibraryList : public ::IceUtil::Shared +{ +public: + + virtual ~DynamicLibraryList(); + + void add(const DynamicLibraryPtr&); + +private: + + std::vector _libraries; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/DynamicLibraryF.h b/Sources/IceCpp/include/Ice/DynamicLibraryF.h new file mode 100644 index 0000000..e462835 --- /dev/null +++ b/Sources/IceCpp/include/Ice/DynamicLibraryF.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_DYNAMIC_LIBRARY_F_H +#define ICE_DYNAMIC_LIBRARY_F_H + +#include + +#include + +namespace IceInternal +{ + +class DynamicLibrary; +ICE_API IceUtil::Shared* upCast(DynamicLibrary*); +typedef Handle DynamicLibraryPtr; + +class DynamicLibraryList; +ICE_API IceUtil::Shared* upCast(DynamicLibraryList*); +typedef Handle DynamicLibraryListPtr; + +} +#endif diff --git a/Sources/IceCpp/include/Ice/Endpoint.h b/Sources/IceCpp/include/Ice/Endpoint.h new file mode 100644 index 0000000..3ad5147 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Endpoint.h @@ -0,0 +1,979 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Endpoint.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Endpoint_h__ +#define __Ice_Endpoint_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class EndpointInfo; +class Endpoint; +class IPEndpointInfo; +class TCPEndpointInfo; +class UDPEndpointInfo; +class WSEndpointInfo; +class OpaqueEndpointInfo; + +} + +namespace Ice +{ + +/** + * Uniquely identifies TCP endpoints. + */ +constexpr short TCPEndpointType = 1; + +/** + * Uniquely identifies SSL endpoints. + */ +constexpr short SSLEndpointType = 2; + +/** + * Uniquely identifies UDP endpoints. + */ +constexpr short UDPEndpointType = 3; + +/** + * Uniquely identifies TCP-based WebSocket endpoints. + */ +constexpr short WSEndpointType = 4; + +/** + * Uniquely identifies SSL-based WebSocket endpoints. + */ +constexpr short WSSEndpointType = 5; + +/** + * Uniquely identifies Bluetooth endpoints. + */ +constexpr short BTEndpointType = 6; + +/** + * Uniquely identifies SSL Bluetooth endpoints. + */ +constexpr short BTSEndpointType = 7; + +/** + * Uniquely identifies iAP-based endpoints. + */ +constexpr short iAPEndpointType = 8; + +/** + * Uniquely identifies SSL iAP-based endpoints. + */ +constexpr short iAPSEndpointType = 9; + +} + +namespace Ice +{ + +/** + * Base class providing access to the endpoint details. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) EndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~EndpointInfo(); + + EndpointInfo() = default; + + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo(EndpointInfo&&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; + EndpointInfo& operator=(EndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + */ + EndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress) : + underlying(underlying), + timeout(timeout), + compress(compress) + { + } + + /** + * Returns the type of the endpoint. + * @return The endpoint type. + */ + virtual short type() const noexcept = 0; + + /** + * Returns true if this endpoint is a datagram endpoint. + * @return True for a datagram endpoint. + */ + virtual bool datagram() const noexcept = 0; + + /** + * Returns true if this endpoint is a secure endpoint. + * @return True for a secure endpoint. + */ + virtual bool secure() const noexcept = 0; + + /** + * The information of the underyling endpoint of null if there's + * no underlying endpoint. + */ + ::std::shared_ptr<::Ice::EndpointInfo> underlying; + /** + * The timeout for the endpoint in milliseconds. 0 means + * non-blocking, -1 means no timeout. + */ + int timeout; + /** + * Specifies whether or not compression should be used if + * available when using this endpoint. + */ + bool compress; +}; + +/** + * The user-level interface to an endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Endpoint +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Endpoint(); + + virtual bool operator==(const Endpoint&) const = 0; + virtual bool operator<(const Endpoint&) const = 0; + + /** + * Return a string representation of the endpoint. + * @return The string representation of the endpoint. + */ + virtual ::std::string toString() const noexcept = 0; + + /** + * Returns the endpoint information. + * @return The endpoint information class. + */ + virtual ::std::shared_ptr<::Ice::EndpointInfo> getInfo() const noexcept = 0; +}; + +/** + * Provides access to the address details of a IP endpoint. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IPEndpointInfo : public ::Ice::EndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IPEndpointInfo(); + + IPEndpointInfo() = default; + + IPEndpointInfo(const IPEndpointInfo&) = default; + IPEndpointInfo(IPEndpointInfo&&) = default; + IPEndpointInfo& operator=(const IPEndpointInfo&) = default; + IPEndpointInfo& operator=(IPEndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + */ + IPEndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::std::string& host, int port, const ::std::string& sourceAddress) : + EndpointInfo(underlying, timeout, compress), + host(host), + port(port), + sourceAddress(sourceAddress) + { + } + + /** + * The host or address configured with the endpoint. + */ + ::std::string host; + /** + * The port number. + */ + int port; + /** + * The source IP address. + */ + ::std::string sourceAddress; +}; + +/** + * Provides access to a TCP endpoint information. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) TCPEndpointInfo : public ::Ice::IPEndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~TCPEndpointInfo(); + + TCPEndpointInfo() = default; + + TCPEndpointInfo(const TCPEndpointInfo&) = default; + TCPEndpointInfo(TCPEndpointInfo&&) = default; + TCPEndpointInfo& operator=(const TCPEndpointInfo&) = default; + TCPEndpointInfo& operator=(TCPEndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + */ + TCPEndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::std::string& host, int port, const ::std::string& sourceAddress) : + IPEndpointInfo(underlying, timeout, compress, host, port, sourceAddress) + { + } +}; + +/** + * Provides access to an UDP endpoint information. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UDPEndpointInfo : public ::Ice::IPEndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UDPEndpointInfo(); + + UDPEndpointInfo() = default; + + UDPEndpointInfo(const UDPEndpointInfo&) = default; + UDPEndpointInfo(UDPEndpointInfo&&) = default; + UDPEndpointInfo& operator=(const UDPEndpointInfo&) = default; + UDPEndpointInfo& operator=(UDPEndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + * @param mcastInterface The multicast interface. + * @param mcastTtl The multicast time-to-live (or hops). + */ + UDPEndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::std::string& host, int port, const ::std::string& sourceAddress, const ::std::string& mcastInterface, int mcastTtl) : + IPEndpointInfo(underlying, timeout, compress, host, port, sourceAddress), + mcastInterface(mcastInterface), + mcastTtl(mcastTtl) + { + } + + /** + * The multicast interface. + */ + ::std::string mcastInterface; + /** + * The multicast time-to-live (or hops). + */ + int mcastTtl; +}; + +/** + * Provides access to a WebSocket endpoint information. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) WSEndpointInfo : public ::Ice::EndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~WSEndpointInfo(); + + WSEndpointInfo() = default; + + WSEndpointInfo(const WSEndpointInfo&) = default; + WSEndpointInfo(WSEndpointInfo&&) = default; + WSEndpointInfo& operator=(const WSEndpointInfo&) = default; + WSEndpointInfo& operator=(WSEndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param resource The URI configured with the endpoint. + */ + WSEndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::std::string& resource) : + EndpointInfo(underlying, timeout, compress), + resource(resource) + { + } + + /** + * The URI configured with the endpoint. + */ + ::std::string resource; +}; + +/** + * Provides access to the details of an opaque endpoint. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) OpaqueEndpointInfo : public ::Ice::EndpointInfo +{ +public: + + ICE_MEMBER(ICE_API) virtual ~OpaqueEndpointInfo(); + + OpaqueEndpointInfo() = default; + + OpaqueEndpointInfo(const OpaqueEndpointInfo&) = default; + OpaqueEndpointInfo(OpaqueEndpointInfo&&) = default; + OpaqueEndpointInfo& operator=(const OpaqueEndpointInfo&) = default; + OpaqueEndpointInfo& operator=(OpaqueEndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param rawEncoding The encoding version of the opaque endpoint (to decode or encode the rawBytes). + * @param rawBytes The raw encoding of the opaque endpoint. + */ + OpaqueEndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::Ice::EncodingVersion& rawEncoding, const ::Ice::ByteSeq& rawBytes) : + EndpointInfo(underlying, timeout, compress), + rawEncoding(rawEncoding), + rawBytes(rawBytes) + { + } + + /** + * The encoding version of the opaque endpoint (to decode or + * encode the rawBytes). + */ + ::Ice::EncodingVersion rawEncoding; + /** + * The raw encoding of the opaque endpoint. + */ + ::Ice::ByteSeq rawBytes; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using EndpointInfoPtr = ::std::shared_ptr; + +using EndpointPtr = ::std::shared_ptr; + +using IPEndpointInfoPtr = ::std::shared_ptr; + +using TCPEndpointInfoPtr = ::std::shared_ptr; + +using UDPEndpointInfoPtr = ::std::shared_ptr; + +using WSEndpointInfoPtr = ::std::shared_ptr; + +using OpaqueEndpointInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class EndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(EndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< EndpointInfo> EndpointInfoPtr; + +class Endpoint; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Endpoint*); +/// \endcond +typedef ::IceInternal::Handle< Endpoint> EndpointPtr; + +class IPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(IPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< IPEndpointInfo> IPEndpointInfoPtr; + +class TCPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(TCPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< TCPEndpointInfo> TCPEndpointInfoPtr; + +class UDPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(UDPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< UDPEndpointInfo> UDPEndpointInfoPtr; + +class WSEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(WSEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< WSEndpointInfo> WSEndpointInfoPtr; + +class OpaqueEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(OpaqueEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< OpaqueEndpointInfo> OpaqueEndpointInfoPtr; + +} + +namespace Ice +{ + +/** + * Uniquely identifies TCP endpoints. + */ +const Short TCPEndpointType = 1; + +/** + * Uniquely identifies SSL endpoints. + */ +const Short SSLEndpointType = 2; + +/** + * Uniquely identifies UDP endpoints. + */ +const Short UDPEndpointType = 3; + +/** + * Uniquely identifies TCP-based WebSocket endpoints. + */ +const Short WSEndpointType = 4; + +/** + * Uniquely identifies SSL-based WebSocket endpoints. + */ +const Short WSSEndpointType = 5; + +/** + * Uniquely identifies Bluetooth endpoints. + */ +const Short BTEndpointType = 6; + +/** + * Uniquely identifies SSL Bluetooth endpoints. + */ +const Short BTSEndpointType = 7; + +/** + * Uniquely identifies iAP-based endpoints. + */ +const Short iAPEndpointType = 8; + +/** + * Uniquely identifies SSL iAP-based endpoints. + */ +const Short iAPSEndpointType = 9; + +} + +namespace Ice +{ + +/** + * Base class providing access to the endpoint details. + * \headerfile Ice/Ice.h + */ +class ICE_API EndpointInfo : public virtual LocalObject +{ +public: + + typedef EndpointInfoPtr PointerType; + + virtual ~EndpointInfo(); + + EndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + */ + EndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress) : + underlying(underlying), + timeout(timeout), + compress(compress) + { + } + +#ifdef ICE_CPP11_COMPILER + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; +#endif + + /** + * Returns the type of the endpoint. + * @return The endpoint type. + */ + virtual Short type() const ICE_NOEXCEPT = 0; + + /** + * Returns true if this endpoint is a datagram endpoint. + * @return True for a datagram endpoint. + */ + virtual bool datagram() const ICE_NOEXCEPT = 0; + + /** + * Returns true if this endpoint is a secure endpoint. + * @return True for a secure endpoint. + */ + virtual bool secure() const ICE_NOEXCEPT = 0; + + /** + * The information of the underyling endpoint of null if there's + * no underlying endpoint. + */ + ::Ice::EndpointInfoPtr underlying; + /** + * The timeout for the endpoint in milliseconds. 0 means + * non-blocking, -1 means no timeout. + */ + ::Ice::Int timeout; + /** + * Specifies whether or not compression should be used if + * available when using this endpoint. + */ + bool compress; +}; + +/// \cond INTERNAL +inline bool operator==(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The user-level interface to an endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_API Endpoint : public virtual LocalObject +{ +public: + + typedef EndpointPtr PointerType; + + virtual ~Endpoint(); + +#ifdef ICE_CPP11_COMPILER + Endpoint() = default; + Endpoint(const Endpoint&) = default; + Endpoint& operator=(const Endpoint&) = default; +#endif + + /** + * Return a string representation of the endpoint. + * @return The string representation of the endpoint. + */ + virtual ::std::string toString() const ICE_NOEXCEPT = 0; + + /** + * Returns the endpoint information. + * @return The endpoint information class. + */ + virtual EndpointInfoPtr getInfo() const ICE_NOEXCEPT = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Endpoint& lhs, const Endpoint& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Endpoint& lhs, const Endpoint& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the address details of a IP endpoint. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_API IPEndpointInfo : public EndpointInfo +{ +public: + + typedef IPEndpointInfoPtr PointerType; + + virtual ~IPEndpointInfo(); + + IPEndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + */ + IPEndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::std::string& host, ::Ice::Int port, const ::std::string& sourceAddress) : + ::Ice::EndpointInfo(underlying, timeout, compress), + host(host), + port(port), + sourceAddress(sourceAddress) + { + } + +#ifdef ICE_CPP11_COMPILER + IPEndpointInfo(const IPEndpointInfo&) = default; + IPEndpointInfo& operator=(const IPEndpointInfo&) = default; +#endif + + /** + * The host or address configured with the endpoint. + */ + ::std::string host; + /** + * The port number. + */ + ::Ice::Int port; + /** + * The source IP address. + */ + ::std::string sourceAddress; +}; + +/// \cond INTERNAL +inline bool operator==(const IPEndpointInfo& lhs, const IPEndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const IPEndpointInfo& lhs, const IPEndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to a TCP endpoint information. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_API TCPEndpointInfo : public IPEndpointInfo +{ +public: + + typedef TCPEndpointInfoPtr PointerType; + + virtual ~TCPEndpointInfo(); + + TCPEndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + */ + TCPEndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::std::string& host, ::Ice::Int port, const ::std::string& sourceAddress) : + ::Ice::IPEndpointInfo(underlying, timeout, compress, host, port, sourceAddress) + { + } + +#ifdef ICE_CPP11_COMPILER + TCPEndpointInfo(const TCPEndpointInfo&) = default; + TCPEndpointInfo& operator=(const TCPEndpointInfo&) = default; +#endif +}; + +/// \cond INTERNAL +inline bool operator==(const TCPEndpointInfo& lhs, const TCPEndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const TCPEndpointInfo& lhs, const TCPEndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to an UDP endpoint information. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_API UDPEndpointInfo : public IPEndpointInfo +{ +public: + + typedef UDPEndpointInfoPtr PointerType; + + virtual ~UDPEndpointInfo(); + + UDPEndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param host The host or address configured with the endpoint. + * @param port The port number. + * @param sourceAddress The source IP address. + * @param mcastInterface The multicast interface. + * @param mcastTtl The multicast time-to-live (or hops). + */ + UDPEndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::std::string& host, ::Ice::Int port, const ::std::string& sourceAddress, const ::std::string& mcastInterface, ::Ice::Int mcastTtl) : + ::Ice::IPEndpointInfo(underlying, timeout, compress, host, port, sourceAddress), + mcastInterface(mcastInterface), + mcastTtl(mcastTtl) + { + } + +#ifdef ICE_CPP11_COMPILER + UDPEndpointInfo(const UDPEndpointInfo&) = default; + UDPEndpointInfo& operator=(const UDPEndpointInfo&) = default; +#endif + + /** + * The multicast interface. + */ + ::std::string mcastInterface; + /** + * The multicast time-to-live (or hops). + */ + ::Ice::Int mcastTtl; +}; + +/// \cond INTERNAL +inline bool operator==(const UDPEndpointInfo& lhs, const UDPEndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const UDPEndpointInfo& lhs, const UDPEndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to a WebSocket endpoint information. + * \headerfile Ice/Ice.h + */ +class ICE_API WSEndpointInfo : public EndpointInfo +{ +public: + + typedef WSEndpointInfoPtr PointerType; + + virtual ~WSEndpointInfo(); + + WSEndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param resource The URI configured with the endpoint. + */ + WSEndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::std::string& resource) : + ::Ice::EndpointInfo(underlying, timeout, compress), + resource(resource) + { + } + +#ifdef ICE_CPP11_COMPILER + WSEndpointInfo(const WSEndpointInfo&) = default; + WSEndpointInfo& operator=(const WSEndpointInfo&) = default; +#endif + + /** + * The URI configured with the endpoint. + */ + ::std::string resource; +}; + +/// \cond INTERNAL +inline bool operator==(const WSEndpointInfo& lhs, const WSEndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const WSEndpointInfo& lhs, const WSEndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides access to the details of an opaque endpoint. + * @see Endpoint + * \headerfile Ice/Ice.h + */ +class ICE_API OpaqueEndpointInfo : public EndpointInfo +{ +public: + + typedef OpaqueEndpointInfoPtr PointerType; + + virtual ~OpaqueEndpointInfo(); + + OpaqueEndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param rawEncoding The encoding version of the opaque endpoint (to decode or encode the rawBytes). + * @param rawBytes The raw encoding of the opaque endpoint. + */ + OpaqueEndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::Ice::EncodingVersion& rawEncoding, const ::Ice::ByteSeq& rawBytes) : + ::Ice::EndpointInfo(underlying, timeout, compress), + rawEncoding(rawEncoding), + rawBytes(rawBytes) + { + } + +#ifdef ICE_CPP11_COMPILER + OpaqueEndpointInfo(const OpaqueEndpointInfo&) = default; + OpaqueEndpointInfo& operator=(const OpaqueEndpointInfo&) = default; +#endif + + /** + * The encoding version of the opaque endpoint (to decode or + * encode the rawBytes). + */ + ::Ice::EncodingVersion rawEncoding; + /** + * The raw encoding of the opaque endpoint. + */ + ::Ice::ByteSeq rawBytes; +}; + +/// \cond INTERNAL +inline bool operator==(const OpaqueEndpointInfo& lhs, const OpaqueEndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const OpaqueEndpointInfo& lhs, const OpaqueEndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointF.h b/Sources/IceCpp/include/Ice/EndpointF.h new file mode 100644 index 0000000..ac10bf1 --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointF.h @@ -0,0 +1,166 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_EndpointF_h__ +#define __Ice_EndpointF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class EndpointInfo; +class IPEndpointInfo; +class TCPEndpointInfo; +class UDPEndpointInfo; +class WSEndpointInfo; +class Endpoint; + +} + +namespace Ice +{ + +/** + * A sequence of endpoints. + */ +using EndpointSeq = ::std::vector<::std::shared_ptr>; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using EndpointInfoPtr = ::std::shared_ptr; + +using IPEndpointInfoPtr = ::std::shared_ptr; + +using TCPEndpointInfoPtr = ::std::shared_ptr; + +using UDPEndpointInfoPtr = ::std::shared_ptr; + +using WSEndpointInfoPtr = ::std::shared_ptr; + +using EndpointPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class EndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(EndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< EndpointInfo> EndpointInfoPtr; + +class IPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(IPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< IPEndpointInfo> IPEndpointInfoPtr; + +class TCPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(TCPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< TCPEndpointInfo> TCPEndpointInfoPtr; + +class UDPEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(UDPEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< UDPEndpointInfo> UDPEndpointInfoPtr; + +class WSEndpointInfo; +/// \cond INTERNAL +ICE_API LocalObject* upCast(WSEndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< WSEndpointInfo> WSEndpointInfoPtr; + +class Endpoint; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Endpoint*); +/// \endcond +typedef ::IceInternal::Handle< Endpoint> EndpointPtr; + +} + +namespace Ice +{ + +/** + * A sequence of endpoints. + */ +typedef ::std::vector EndpointSeq; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointFactory.h b/Sources/IceCpp/include/Ice/EndpointFactory.h new file mode 100644 index 0000000..4bcbf5b --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointFactory.h @@ -0,0 +1,117 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_FACTORY_H +#define ICE_ENDPOINT_FACTORY_H + +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class InputStream; + +} + +namespace IceInternal +{ + +class ICE_API EndpointFactory : public ::IceUtil::Shared +{ +public: + + virtual ~EndpointFactory(); + + virtual void initialize(); + virtual Ice::Short type() const = 0; + virtual std::string protocol() const = 0; + virtual EndpointIPtr create(std::vector&, bool) const = 0; + virtual EndpointIPtr read(Ice::InputStream*) const = 0; + virtual void destroy() = 0; + + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const = 0; + +protected: + + EndpointFactory(); +}; + +// +// The endpoint factory with underlying create endpoints that delegate to an underlying +// endpoint (e.g.: the SSL/WS endpoints are endpoints with underlying endpoints). +// +class ICE_API EndpointFactoryWithUnderlying : public EndpointFactory +{ +public: + + EndpointFactoryWithUnderlying(const ProtocolInstancePtr&, Ice::Short); + + virtual void initialize(); + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual EndpointIPtr create(std::vector&, bool) const; + virtual EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + + virtual EndpointFactoryPtr cloneWithUnderlying(const ProtocolInstancePtr&, Ice::Short) const = 0; + +protected: + + virtual EndpointIPtr createWithUnderlying(const EndpointIPtr&, std::vector&, bool) const = 0; + virtual EndpointIPtr readWithUnderlying(const EndpointIPtr&, Ice::InputStream*) const = 0; + + ProtocolInstancePtr _instance; + const Ice::Short _type; + EndpointFactoryPtr _underlying; +}; + +// +// The underlying endpoint factory creates endpoints with a factory of the given +// type. If this factory is of the EndpointFactoryWithUnderlying type, it will +// delegate to the given underlying factory (this is used by IceIAP/IceBT plugins +// for the BTS/iAPS endpoint factories). +// +class ICE_API UnderlyingEndpointFactory : public EndpointFactory +{ +public: + + UnderlyingEndpointFactory(const ProtocolInstancePtr&, Ice::Short, Ice::Short); + + virtual void initialize(); + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual EndpointIPtr create(std::vector&, bool) const; + virtual EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + +private: + + ProtocolInstancePtr _instance; + const Ice::Short _type; + const Ice::Short _underlying; + EndpointFactoryPtr _factory; +}; + +class ICE_API EndpointFactoryPlugin : public Ice::Plugin +{ +public: + + EndpointFactoryPlugin(const Ice::CommunicatorPtr&, const EndpointFactoryPtr&); + + virtual void initialize(); + virtual void destroy(); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointFactoryF.h b/Sources/IceCpp/include/Ice/EndpointFactoryF.h new file mode 100644 index 0000000..22ae52d --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointFactoryF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_FACTORY_F_H +#define ICE_ENDPOINT_FACTORY_F_H + +#include + +#include + +namespace IceInternal +{ + +class EndpointFactory; +ICE_API IceUtil::Shared* upCast(EndpointFactory*); +typedef Handle EndpointFactoryPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointFactoryManager.h b/Sources/IceCpp/include/Ice/EndpointFactoryManager.h new file mode 100644 index 0000000..b2ef39b --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointFactoryManager.h @@ -0,0 +1,47 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_FACTORY_MANAGER_H +#define ICE_ENDPOINT_FACTORY_MANAGER_H + +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class InputStream; + +} + +namespace IceInternal +{ + +class EndpointFactoryManager : public ::IceUtil::Shared, public ::IceUtil::Mutex +{ +public: + + void initialize() const; + void add(const EndpointFactoryPtr&); + EndpointFactoryPtr get(::Ice::Short) const; + EndpointIPtr create(const std::string&, bool) const; + EndpointIPtr read(Ice::InputStream*) const; + +private: + + EndpointFactoryManager(const InstancePtr&); + void destroy(); + friend class Instance; + + InstancePtr _instance; + std::vector _factories; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointFactoryManagerF.h b/Sources/IceCpp/include/Ice/EndpointFactoryManagerF.h new file mode 100644 index 0000000..f24fb5c --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointFactoryManagerF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_FACTORY_MANAGER_F_H +#define ICE_ENDPOINT_FACTORY_MANAGER_F_H + +#include + +#include + +namespace IceInternal +{ + +class EndpointFactoryManager; +IceUtil::Shared* upCast(EndpointFactoryManager*); +typedef Handle EndpointFactoryManagerPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointI.h b/Sources/IceCpp/include/Ice/EndpointI.h new file mode 100644 index 0000000..0929d3e --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointI.h @@ -0,0 +1,218 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_I_H +#define ICE_ENDPOINT_I_H + +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +} + +namespace IceInternal +{ + +class ICE_API EndpointI_connectors +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + virtual ~EndpointI_connectors(); + + virtual void connectors(const std::vector&) = 0; + virtual void exception(const Ice::LocalException&) = 0; +}; + +class ICE_API EndpointI : public Ice::Endpoint +{ +public: + + // + // Marshal the endpoint. + // + virtual void streamWrite(Ice::OutputStream*) const; + virtual void streamWriteImpl(Ice::OutputStream*) const = 0; + + // + // Return the endpoint type. + // + virtual Ice::Short type() const = 0; + + // + // Return the protocol name + // + virtual const std::string& protocol() const = 0; + + // + // Return the timeout for the endpoint in milliseconds. 0 means + // non-blocking, -1 means no timeout. + // + virtual Ice::Int timeout() const = 0; + + // + // Return a new endpoint with a different timeout value, provided + // that timeouts are supported by the endpoint. Otherwise the same + // endpoint is returned. + // + virtual EndpointIPtr timeout(Ice::Int) const = 0; + + // + // Returns the endpoint connection id. + // + virtual const std::string& connectionId() const = 0; + + // + // Return a new endpoint with a different connection id. + // + virtual EndpointIPtr connectionId(const ::std::string&) const = 0; + + // + // Return true if the endpoints support bzip2 compress, or false + // otherwise. + // + virtual bool compress() const = 0; + + // + // Return a new endpoint with a different compression value, + // provided that compression is supported by the + // endpoint. Otherwise the same endpoint is returned. + // + virtual EndpointIPtr compress(bool) const = 0; + + // + // Return true if the endpoint is datagram-based. + // + virtual bool datagram() const = 0; + + // + // Return true if the endpoint is secure. + // + virtual bool secure() const = 0; + + // + // Return a server side transceiver for this endpoint, or null if a + // transceiver can only be created by an acceptor. + // + virtual TransceiverPtr transceiver() const = 0; + + // + // Return connectors for this endpoint, or empty vector if no + // connector is available. Implementation is responsible for + // returning connectors sorted according to the endpoint selection + // type. + // + virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const = 0; + + // + // Return an acceptor for this endpoint, or null if no acceptors + // is available. + // + virtual AcceptorPtr acceptor(const std::string&) const = 0; + + // + // Expand endpoint out into separate endpoints for each local + // host if listening on INADDR_ANY on server side. + // + virtual std::vector expandIfWildcard() const = 0; + + // + // Expand endpoint out into separate endpoints for each IP + // address returned by the DNS resolver. Also returns the + // endpoint which can be used to connect to the returned + // endpoints or null if no specific endpoint can be used to + // connect to these endpoints (e.g.: with the IP endpoint, + // it returns this endpoint if it uses a fixed port, null + // otherwise). + // + virtual std::vector expandHost(IceInternal::EndpointIPtr&) const = 0; + + // + // Check whether the endpoint is equivalent to another one. + // + virtual bool equivalent(const EndpointIPtr&) const = 0; + + // + // Compare endpoints for sorting purposes. + // +#ifndef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::LocalObject&) const = 0; + virtual bool operator<(const Ice::LocalObject&) const = 0; +#endif + + virtual ::Ice::Int hash() const = 0; + + // + // Returns the stringified options + // + virtual std::string options() const = 0; + + virtual std::string toString() const ICE_NOEXCEPT; + void initWithOptions(std::vector&); + +protected: + + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + +}; + +#ifndef ICE_CPP11_MAPPING +inline bool operator==(const EndpointI& l, const EndpointI& r) +{ + return static_cast(l) == static_cast(r); +} + +inline bool operator<(const EndpointI& l, const EndpointI& r) +{ + return static_cast(l) < static_cast(r); +} +#endif + +template class InfoI : public T +{ +public: + + InfoI(const EndpointIPtr& endpoint) : _endpoint(endpoint) + { + T::compress = _endpoint->compress(); + T::timeout = _endpoint->timeout(); + } + + virtual Ice::Short + type() const ICE_NOEXCEPT + { + return _endpoint->type(); + } + + virtual bool + datagram() const ICE_NOEXCEPT + { + return _endpoint->datagram(); + } + + virtual bool + secure() const ICE_NOEXCEPT + { + return _endpoint->secure(); + } + +private: + + const EndpointIPtr _endpoint; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointIF.h b/Sources/IceCpp/include/Ice/EndpointIF.h new file mode 100644 index 0000000..7944b28 --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointIF.h @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ENDPOINT_I_F_H +#define ICE_ENDPOINT_I_F_H + +#include +#include + +namespace IceInternal +{ + +class EndpointI; +class TcpEndpointI; +class UdpEndpointI; +class WSEndpoint; +class EndpointI_connectors; + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +using EndpointIPtr = ::std::shared_ptr; +using TcpEndpointIPtr = ::std::shared_ptr; +using UdpEndpointIPtr = ::std::shared_ptr; +using WSEndpointPtr = ::std::shared_ptr; +using EndpointI_connectorsPtr = ::std::shared_ptr; + +#else // C++98 mapping + +ICE_API IceUtil::Shared* upCast(EndpointI*); +typedef Handle EndpointIPtr; + +ICE_API IceUtil::Shared* upCast(TcpEndpointI*); +typedef Handle TcpEndpointIPtr; + +ICE_API IceUtil::Shared* upCast(UdpEndpointI*); +typedef Handle UdpEndpointIPtr; + +ICE_API IceUtil::Shared* upCast(WSEndpoint*); +typedef Handle WSEndpointPtr; + +ICE_API IceUtil::Shared* upCast(EndpointI_connectors*); +typedef Handle EndpointI_connectorsPtr; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EndpointTypes.h b/Sources/IceCpp/include/Ice/EndpointTypes.h new file mode 100644 index 0000000..f502ce7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/EndpointTypes.h @@ -0,0 +1,118 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointTypes.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_EndpointTypes_h__ +#define __Ice_EndpointTypes_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * Determines the order in which the Ice run time uses the endpoints + * in a proxy when establishing a connection. + */ +enum class EndpointSelectionType : unsigned char +{ + /** + * Random causes the endpoints to be arranged in a random order. + */ + Random, + /** + * Ordered forces the Ice run time to use the endpoints in the + * order they appeared in the proxy. + */ + Ordered +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +/** + * Determines the order in which the Ice run time uses the endpoints + * in a proxy when establishing a connection. + */ +enum EndpointSelectionType +{ + /** + * Random causes the endpoints to be arranged in a random order. + */ + Random, + /** + * Ordered forces the Ice run time to use the endpoints in the + * order they appeared in the proxy. + */ + Ordered +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/EventHandler.h b/Sources/IceCpp/include/Ice/EventHandler.h new file mode 100644 index 0000000..c3c45b7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/EventHandler.h @@ -0,0 +1,81 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_EVENT_HANDLER_H +#define ICE_EVENT_HANDLER_H + +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API EventHandler : +#ifdef ICE_CPP11_MAPPING + public EnableSharedFromThis +#else + public virtual Ice::LocalObject +#endif +{ +public: + +#if defined(ICE_USE_IOCP) + // + // Called to start a new asynchronous read or write operation. + // + virtual bool startAsync(SocketOperation) = 0; + virtual bool finishAsync(SocketOperation) = 0; +#endif + + // + // Called when there's a message ready to be processed. + // + virtual void message(ThreadPoolCurrent&) = 0; + + // + // Called when the event handler is unregistered. + // + virtual void finished(ThreadPoolCurrent&, bool) = 0; + + // + // Get a textual representation of the event handler. + // + virtual std::string toString() const = 0; + + // + // Get the native information of the handler, this is used by the selector. + // + virtual NativeInfoPtr getNativeInfo() = 0; + +protected: + + EventHandler(); + virtual ~EventHandler(); + +#if defined(ICE_USE_IOCP) + SocketOperation _pending; + SocketOperation _started; + SocketOperation _completed; + bool _finish; +#else + SocketOperation _disabled; +#endif + SocketOperation _ready; + SocketOperation _registered; + + friend class ThreadPool; + friend class ThreadPoolCurrent; + friend class Selector; +#ifdef ICE_USE_CFSTREAM + friend class EventHandlerWrapper; +#endif +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/EventHandlerF.h b/Sources/IceCpp/include/Ice/EventHandlerF.h new file mode 100644 index 0000000..e762d31 --- /dev/null +++ b/Sources/IceCpp/include/Ice/EventHandlerF.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_EVENT_HANDLER_F_H +#define ICE_EVENT_HANDLER_F_H + +#include + +#include + +namespace IceInternal +{ + +class EventHandler; +#ifdef ICE_CPP11_MAPPING +using EventHandlerPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(EventHandler*); +typedef Handle EventHandlerPtr; +#endif +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Exception.h b/Sources/IceCpp/include/Ice/Exception.h new file mode 100644 index 0000000..13f86ad --- /dev/null +++ b/Sources/IceCpp/include/Ice/Exception.h @@ -0,0 +1,161 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_EXCEPTION_H +#define ICE_EXCEPTION_H + +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +typedef IceUtil::Exception Exception; + +/** + * Base class for all Ice run-time exceptions. + * \headerfile Ice/Ice.h + */ +class ICE_API LocalException : public IceUtil::Exception +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + LocalException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + LocalException(const LocalException&) = default; + virtual ~LocalException(); +#else + virtual ~LocalException() throw(); +#endif + + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ +#ifdef ICE_CPP11_MAPPING + std::unique_ptr ice_clone() const; +#else + virtual LocalException* ice_clone() const = 0; +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + static const std::string& ice_staticId(); +}; + +/** + * Base class for all Ice user exceptions. + * \headerfile Ice/Ice.h + */ +class ICE_API UserException : public IceUtil::Exception +{ +public: + + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ +#ifdef ICE_CPP11_MAPPING + std::unique_ptr ice_clone() const; +#else + virtual UserException* ice_clone() const = 0; +#endif + virtual Ice::SlicedDataPtr ice_getSlicedData() const; + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + static const std::string& ice_staticId(); + + /// \cond STREAM + virtual void _write(::Ice::OutputStream*) const; + virtual void _read(::Ice::InputStream*); + + virtual bool _usesClasses() const; + /// \endcond + +protected: + + /// \cond STREAM + virtual void _writeImpl(::Ice::OutputStream*) const {} + virtual void _readImpl(::Ice::InputStream*) {} + /// \endcond +}; + +/** + * Base class for all Ice system exceptions. + * + * System exceptions are currently Ice internal, non-documented + * exceptions. + * \headerfile Ice/Ice.h + */ +class ICE_API SystemException : public IceUtil::Exception +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SystemException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + SystemException(const SystemException&) = default; + virtual ~SystemException(); +#else + virtual ~SystemException() throw(); +#endif + + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ +#ifdef ICE_CPP11_MAPPING + std::unique_ptr ice_clone() const; +#else + virtual SystemException* ice_clone() const = 0; +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + static const std::string& ice_staticId(); +}; + +} + +namespace IceInternal +{ + +namespace Ex +{ + +ICE_API void throwUOE(const ::std::string&, const ::Ice::ValuePtr&); +ICE_API void throwMemoryLimitException(const char*, int, size_t, size_t); +ICE_API void throwMarshalException(const char*, int, const std::string&); + +} + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ExceptionHelpers.h b/Sources/IceCpp/include/Ice/ExceptionHelpers.h new file mode 100644 index 0000000..eb799ff --- /dev/null +++ b/Sources/IceCpp/include/Ice/ExceptionHelpers.h @@ -0,0 +1,74 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_EXCEPTION_HELPERS_H +#define ICE_EXCEPTION_HELPERS_H + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#include +#include + +namespace Ice +{ + +class LocalException; + +/** + * Helper template for the implementation of Ice::LocalException. It implements ice_id. + * \headerfile Ice/Ice.h + */ +template class LocalExceptionHelper : public IceUtil::ExceptionHelper +{ +public: + + using IceUtil::ExceptionHelper::ExceptionHelper; + + virtual std::string ice_id() const override + { + return T::ice_staticId(); + } +}; + +/** + * Helper template for the implementation of Ice::UserException. It implements ice_id. + * \headerfile Ice/Ice.h + */ +template class UserExceptionHelper : public IceUtil::ExceptionHelper +{ +public: + + using IceUtil::ExceptionHelper::ExceptionHelper; + + virtual std::string ice_id() const override + { + return T::ice_staticId(); + } + +protected: + + /// \cond STREAM + virtual void _writeImpl(Ice::OutputStream* os) const override + { + os->startSlice(T::ice_staticId(), -1, std::is_same::value ? true : false); + Ice::StreamWriter::write(os, static_cast(*this)); + os->endSlice(); + B::_writeImpl(os); + } + + virtual void _readImpl(Ice::InputStream* is) override + { + is->startSlice(); + Ice::StreamReader::read(is, static_cast(*this)); + is->endSlice(); + B::_readImpl(is); + } + /// \endcond +}; + +} + +#endif // C++11 mapping end + +#endif diff --git a/Sources/IceCpp/include/Ice/FacetMap.h b/Sources/IceCpp/include/Ice/FacetMap.h new file mode 100644 index 0000000..41e252f --- /dev/null +++ b/Sources/IceCpp/include/Ice/FacetMap.h @@ -0,0 +1,80 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `FacetMap.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_FacetMap_h__ +#define __Ice_FacetMap_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * A mapping from facet name to servant. + */ +using FacetMap = ::std::map<::std::string, ::std::shared_ptr>; + +} + +#else // C++98 mapping + +namespace Ice +{ + +/** + * A mapping from facet name to servant. + */ +typedef ::std::map< ::std::string, ObjectPtr> FacetMap; + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/FactoryTable.h b/Sources/IceCpp/include/Ice/FactoryTable.h new file mode 100644 index 0000000..8da37f8 --- /dev/null +++ b/Sources/IceCpp/include/Ice/FactoryTable.h @@ -0,0 +1,73 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_FACTORYTABLE_H +#define ICE_FACTORYTABLE_H + +#include +#include +#include + +namespace Ice +{ + +/** + * The base class for a compact ID resolver. Subclasses must implement resolve. + * The resolver can be installed via InitializationData. + * \headerfile Ice/Ice.h + */ +class ICE_API CompactIdResolver : public IceUtil::Shared +{ +public: + + /** + * Called by the Ice run time when a compact ID must be translated into a type ID. + * @param id The compact ID. + * @return The fully-scoped Slice type ID, or an empty string if the compact ID is unknown. + */ + virtual ::std::string resolve(Ice::Int id) const = 0; +}; +typedef IceUtil::Handle CompactIdResolverPtr; + +} + +namespace IceInternal +{ + +class ICE_API FactoryTable : private IceUtil::noncopyable +{ +public: + + void addExceptionFactory(const ::std::string&, ICE_IN(ICE_DELEGATE(::Ice::UserExceptionFactory))); + ICE_DELEGATE(::Ice::UserExceptionFactory) getExceptionFactory(const ::std::string&) const; + void removeExceptionFactory(const ::std::string&); + + void addValueFactory(const ::std::string&, ICE_IN(ICE_DELEGATE(::Ice::ValueFactory))); + ICE_DELEGATE(::Ice::ValueFactory) getValueFactory(const ::std::string&) const; + void removeValueFactory(const ::std::string&); + + void addTypeId(int, const ::std::string&); + std::string getTypeId(int) const; + void removeTypeId(int); + +private: + + IceUtil::Mutex _m; + + typedef ::std::pair< ICE_DELEGATE(::Ice::UserExceptionFactory), int> EFPair; + typedef ::std::map< ::std::string, EFPair> EFTable; + EFTable _eft; + + typedef ::std::pair< ICE_DELEGATE(::Ice::ValueFactory), int> VFPair; + typedef ::std::map< ::std::string, VFPair> VFTable; + VFTable _vft; + + typedef ::std::pair< ::std::string, int> TypeIdPair; + typedef ::std::map TypeIdTable; + TypeIdTable _typeIdTable; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/FactoryTableInit.h b/Sources/IceCpp/include/Ice/FactoryTableInit.h new file mode 100644 index 0000000..9aca183 --- /dev/null +++ b/Sources/IceCpp/include/Ice/FactoryTableInit.h @@ -0,0 +1,84 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_FACTORYTABLEINIT_H +#define ICE_FACTORYTABLEINIT_H + +#include +#include + +namespace IceInternal +{ + +class ICE_API FactoryTableInit +{ +public: + + FactoryTableInit(); + ~FactoryTableInit(); +}; + +static FactoryTableInit factoryTableInitializer; // Dummy variable to force initialization of factoryTable + +extern ICE_API FactoryTable* factoryTable ICE_GLOBAL_VAR_SUFFIX; + +class ICE_API CompactIdInit +{ +public: + + CompactIdInit(const char*, int); + ~CompactIdInit(); + +private: + + const int _compactId; +}; + +template +class DefaultUserExceptionFactoryInit +{ +public: + + DefaultUserExceptionFactoryInit(const char* tId) : typeId(tId) + { +#ifdef ICE_CPP11_MAPPING + factoryTable->addExceptionFactory(typeId, defaultUserExceptionFactory); +#else + factoryTable->addExceptionFactory(typeId, new DefaultUserExceptionFactory(typeId)); +#endif + } + + ~DefaultUserExceptionFactoryInit() + { + factoryTable->removeExceptionFactory(typeId); + } + + const ::std::string typeId; +}; + +template +class DefaultValueFactoryInit +{ +public: + + DefaultValueFactoryInit(const char* tId) : typeId(tId) + { +#ifdef ICE_CPP11_MAPPING + factoryTable->addValueFactory(typeId, defaultValueFactory); +#else + factoryTable->addValueFactory(typeId, new DefaultValueFactory(typeId)); +#endif + } + + ~DefaultValueFactoryInit() + { + factoryTable->removeValueFactory(typeId); + } + + const ::std::string typeId; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Format.h b/Sources/IceCpp/include/Ice/Format.h new file mode 100644 index 0000000..5cb76ec --- /dev/null +++ b/Sources/IceCpp/include/Ice/Format.h @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_FORMAT_H +#define ICE_FORMAT_H + +#include + +namespace Ice +{ + +/** + * Describes the possible formats for classes and exceptions. + */ +#ifdef ICE_CPP11_MAPPING +enum class FormatType : unsigned char +#else +enum FormatType +#endif +{ + /** + * Indicates that no preference was specified. + */ + DefaultFormat, + /** + * A minimal format that eliminates the possibility for slicing unrecognized types. + */ + CompactFormat, + /** + * Allow slicing and preserve slices for unknown types. + */ + SlicedFormat +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Functional.h b/Sources/IceCpp/include/Ice/Functional.h new file mode 100644 index 0000000..1696eea --- /dev/null +++ b/Sources/IceCpp/include/Ice/Functional.h @@ -0,0 +1,140 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_FUNCTIONAL_H +#define ICE_FUNCTIONAL_H + +#include + +#if !defined(ICE_CPP11_MAPPING) && (ICE_CPLUSPLUS < 201703L) + +#include +#include + +// ---------------------------------------------------------------------- +// Inline functions that return function objects that work with +// IceInternal::Handle +// ---------------------------------------------------------------------- + +namespace Ice +{ + +/// \cond INTERNAL +template +inline ::IceUtilInternal::MemFun > +memFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::MemFun >(p); +} + +template +inline ::IceUtilInternal::MemFun1, A> +memFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::MemFun1, A>(p); +} + +template +inline ::IceUtilInternal::VoidMemFun > +voidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::VoidMemFun >(p); +} + +template +inline ::IceUtilInternal::VoidMemFun1, A> +voidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::VoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondMemFun > +secondMemFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::SecondMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondMemFun1, A> +secondMemFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::SecondMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun > +secondVoidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::SecondVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun1, A> +secondVoidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::SecondVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstMemFun > +constMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstMemFun1, A> +constMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun > +constVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun1, A> +constVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun > +secondConstMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun1, A> +secondConstMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun > +secondConstVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun1, A> +secondConstVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun1, A>(p); +} +/// \endcond + +} + +# endif +#endif diff --git a/Sources/IceCpp/include/Ice/GCObject.h b/Sources/IceCpp/include/Ice/GCObject.h new file mode 100644 index 0000000..d08f680 --- /dev/null +++ b/Sources/IceCpp/include/Ice/GCObject.h @@ -0,0 +1,76 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_GC_OBJECT_H +#define ICE_GC_OBJECT_H + +#ifndef ICE_CPP11_MAPPING + +#include + +#include +#include + +namespace IceInternal +{ + +class GCObject; + +class GCVisitor +{ +public: + + virtual ~GCVisitor() + { + } + + virtual bool visit(GCObject*) = 0; +}; + +class ICE_API GCObject : public virtual Ice::Object +{ +public: + + // + // Flags constant used for collection of graphs + // + static const unsigned char Collectable; + static const unsigned char CycleMember; + static const unsigned char Visiting; + + // + // Override IceUtil::Shared methods + // + virtual void __incRef(); + virtual void __decRef(); + virtual int __getRef() const; + virtual void __setNoDelete(bool); + + // + // Override Object methods + // + virtual bool _iceGcVisit(GCVisitor&); + virtual void ice_collectable(bool); + + // + // This method is implemented by Slice classes to visit class + // members. + // + virtual void _iceGcVisitMembers(IceInternal::GCVisitor&) = 0; + + int _iceGetRefUnsafe() + { + return _ref; + } + +private: + + bool collect(IceUtilInternal::MutexPtrLock&); +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/Handle.h b/Sources/IceCpp/include/Ice/Handle.h new file mode 100644 index 0000000..8455518 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Handle.h @@ -0,0 +1,182 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_HANDLE_H +#define ICE_HANDLE_H + +#include +#include + +// +// "Handle" or "smart pointer" template for classes derived from +// IceInternal::GCShared, IceUtil::Shared, or IceUtil::SimpleShared. +// +// In constrast to IceUtil::Handle, IceInternal::Handle can be used +// for a type T that has been declared but not defined. The only +// requirement is a declaration of the following function: +// +// namespace IceInternal +// { +// X* upCast(T*); +// } +// +// Where X is (or derives from) IceUtil::Shared or IceUtil::SimpleShared. +// + +namespace IceInternal +{ + +template +class Handle : public ::IceUtil::HandleBase +{ +public: + + Handle(T* p = 0) + { + this->_ptr = p; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + template + Handle(const Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + template + Handle(const ::IceUtil::Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + Handle(const Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + ~Handle() + { + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + } + + Handle& operator=(T* p) + { + if(this->_ptr != p) + { + if(p) + { + upCast(p)->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = p; + + if(ptr) + { + upCast(ptr)->__decRef(); + } + } + return *this; + } + + template + Handle& operator=(const Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = r._ptr; + + if(ptr) + { + upCast(ptr)->__decRef(); + } + } + return *this; + } + + template + Handle& operator=(const ::IceUtil::Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = r._ptr; + + if(ptr) + { + upCast(ptr)->__decRef(); + } + } + return *this; + } + + Handle& operator=(const Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = r._ptr; + + if(ptr) + { + upCast(ptr)->__decRef(); + } + } + return *this; + } + + template + static Handle dynamicCast(const ::IceUtil::HandleBase& r) + { + return Handle(dynamic_cast(r._ptr)); + } + + template + static Handle dynamicCast(Y* p) + { + return Handle(dynamic_cast(p)); + } +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/HashUtil.h b/Sources/IceCpp/include/Ice/HashUtil.h new file mode 100644 index 0000000..1a543d9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/HashUtil.h @@ -0,0 +1,53 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_HASH_UTIL_H +#define ICE_HASH_UTIL_H + +namespace IceInternal +{ + +inline void +hashAdd(Ice::Int& hashCode, Ice::Int value) +{ + hashCode = ((hashCode << 5) + hashCode) ^ static_cast(2654435761u) * value; +} + +inline void +hashAdd(Ice::Int& hashCode, bool value) +{ + hashCode = ((hashCode << 5) + hashCode) ^ (value ? 1 : 0); +} + +inline void +hashAdd(Ice::Int& hashCode, const std::string& value) +{ + for(std::string::const_iterator p = value.begin(); p != value.end(); ++p) + { + hashCode = ((hashCode << 5) + hashCode) ^ *p; + } +} + +template void +hashAdd(Ice::Int& hashCode, const std::vector& seq) +{ + for(typename std::vector::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + hashAdd(hashCode, *p); + } +} + +template void +hashAdd(Ice::Int& hashCode, const std::map& map) +{ + for(typename std::map::const_iterator p = map.begin(); p != map.end(); ++p) + { + hashAdd(hashCode, p->first); + hashAdd(hashCode, p->second); + } +} + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/HttpParser.h b/Sources/IceCpp/include/Ice/HttpParser.h new file mode 100644 index 0000000..b2528c0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/HttpParser.h @@ -0,0 +1,117 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_HTTP_PARSER_H +#define ICE_HTTP_PARSER_H + +#include +#include +#include + +namespace IceInternal +{ + +std::vector calcSHA1(const std::vector&); + +typedef std::map > HeaderFields; + +class WebSocketException +{ +public: + WebSocketException(const std::string&); + + std::string reason; +}; + +class HttpParser : public IceUtil::Shared +{ +public: + + HttpParser(); + + enum Type + { + TypeUnknown, + TypeRequest, + TypeResponse + }; + + const Ice::Byte* isCompleteMessage(const Ice::Byte*, const Ice::Byte*) const; + + bool parse(const Ice::Byte*, const Ice::Byte*); + + Type type() const; + + std::string method() const; + std::string uri() const; + int versionMajor() const; + int versionMinor() const; + + int status() const; + std::string reason() const; + + bool getHeader(const std::string&, std::string&, bool) const; + + std::map getHeaders() const; + +private: + + Type _type; + + std::string _method; + std::string _uri; + + HeaderFields _headers; + std::string _headerName; + + int _versionMajor; + int _versionMinor; + + int _status; + std::string _reason; + + enum State + { + StateInit, + StateType, + StateTypeCheck, + StateRequest, + StateRequestMethod, + StateRequestMethodSP, + StateRequestURI, + StateRequestURISP, + StateRequestLF, + StateHeaderFieldStart, + StateHeaderFieldContStart, + StateHeaderFieldCont, + StateHeaderFieldNameStart, + StateHeaderFieldName, + StateHeaderFieldNameEnd, + StateHeaderFieldValueStart, + StateHeaderFieldValue, + StateHeaderFieldValueEnd, + StateHeaderFieldLF, + StateHeaderFieldEndLF, + StateVersion, + StateVersionH, + StateVersionHT, + StateVersionHTT, + StateVersionHTTP, + StateVersionMajor, + StateVersionMinor, + StateResponse, + StateResponseVersionSP, + StateResponseStatus, + StateResponseReasonStart, + StateResponseReason, + StateResponseLF, + StateComplete + }; + State _state; +}; +typedef IceUtil::Handle HttpParserPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/IPEndpointI.h b/Sources/IceCpp/include/Ice/IPEndpointI.h new file mode 100644 index 0000000..1d103a9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IPEndpointI.h @@ -0,0 +1,152 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IP_ENDPOINT_I_H +#define ICE_IP_ENDPOINT_I_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace IceInternal +{ + +class ICE_API IPEndpointInfoI : public Ice::IPEndpointInfo +{ +public: + + IPEndpointInfoI(const EndpointIPtr&); + virtual ~IPEndpointInfoI(); + + virtual Ice::Short type() const ICE_NOEXCEPT; + virtual bool datagram() const ICE_NOEXCEPT; + virtual bool secure() const ICE_NOEXCEPT; + +private: + + const EndpointIPtr _endpoint; +}; + +class ICE_API IPEndpointI : public EndpointI +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; + virtual bool secure() const; + + virtual const std::string& connectionId() const; + virtual EndpointIPtr connectionId(const ::std::string&) const; + + virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; + virtual std::vector expandIfWildcard() const; + virtual std::vector expandHost(EndpointIPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; + virtual ::Ice::Int hash() const; + virtual std::string options() const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + + virtual std::vector connectors(const std::vector
&, const NetworkProxyPtr&) const; + + virtual void hashInit(Ice::Int&) const; + virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; + + using EndpointI::connectionId; + + virtual void initWithOptions(std::vector&, bool); + +protected: + + friend class EndpointHostResolver; + + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + + virtual ConnectorPtr createConnector(const Address& address, const NetworkProxyPtr&) const = 0; + virtual IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const = 0; + + IPEndpointI(const ProtocolInstancePtr&, const std::string&, int, const Address&, const std::string&); + IPEndpointI(const ProtocolInstancePtr&); + IPEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); + + const ProtocolInstancePtr _instance; + const std::string _host; + const int _port; + const Address _sourceAddr; + const std::string _connectionId; + +private: + + mutable bool _hashInitialized; + mutable Ice::Int _hashValue; +}; + +class ICE_API EndpointHostResolver : public IceUtil::Thread, public IceUtil::Monitor +{ +public: + + EndpointHostResolver(const InstancePtr&); + + void resolve(const std::string&, int, Ice::EndpointSelectionType, const IPEndpointIPtr&, + const EndpointI_connectorsPtr&); + void destroy(); + + virtual void run(); + void updateObserver(); + +private: + + struct ResolveEntry + { + std::string host; + int port; + Ice::EndpointSelectionType selType; + IPEndpointIPtr endpoint; + EndpointI_connectorsPtr callback; + Ice::Instrumentation::ObserverPtr observer; + }; + + const InstancePtr _instance; + const IceInternal::ProtocolSupport _protocol; + const bool _preferIPv6; + bool _destroyed; + std::deque _queue; + ObserverHelperT _observer; +}; + +#ifndef ICE_CPP11_MAPPING +inline bool operator==(const IPEndpointI& l, const IPEndpointI& r) +{ + return static_cast(l) == static_cast(r); +} + +inline bool operator<(const IPEndpointI& l, const IPEndpointI& r) +{ + return static_cast(l) < static_cast(r); +} +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/IPEndpointIF.h b/Sources/IceCpp/include/Ice/IPEndpointIF.h new file mode 100644 index 0000000..1125285 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IPEndpointIF.h @@ -0,0 +1,28 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IP_ENDPOINT_I_F_H +#define ICE_IP_ENDPOINT_I_F_H + +#include +#include + +namespace IceInternal +{ + +class IPEndpointI; + +#ifdef ICE_CPP11_MAPPING +using IPEndpointIPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(IPEndpointI*); +typedef Handle IPEndpointIPtr; +#endif + +class EndpointHostResolver; +ICE_API IceUtil::Shared* upCast(EndpointHostResolver*); +typedef Handle EndpointHostResolverPtr; +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Ice.h b/Sources/IceCpp/include/Ice/Ice.h new file mode 100644 index 0000000..b4029eb --- /dev/null +++ b/Sources/IceCpp/include/Ice/Ice.h @@ -0,0 +1,55 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ICE_H +#define ICE_ICE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 +# include +#endif +#include +#include +#include +#include +#include +#include + +#endif diff --git a/Sources/IceCpp/include/Ice/IconvStringConverter.h b/Sources/IceCpp/include/Ice/IconvStringConverter.h new file mode 100644 index 0000000..7d1deb3 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IconvStringConverter.h @@ -0,0 +1,377 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ICONV_STRING_CONVERTER +#define ICE_ICONV_STRING_CONVERTER + +#include + +// +// For all platforms except Windows +// +#ifndef _WIN32 + +#include +#include +#include +#include + +#include +#include +#include + +#if (defined(__APPLE__) && _LIBICONV_VERSION < 0x010B) +// +// See http://sourceware.org/bugzilla/show_bug.cgi?id=2962 +// +# define ICE_CONST_ICONV_INBUF 1 +#endif + +namespace Ice +{ + +/** + * Indicates that Iconv does not support the code. + * \headerfile Ice/Ice.h + */ +class ICE_API IconvInitializationException : public IceUtil::ExceptionHelper +{ +public: + + /** + * Constructs the exception with a reason. The file and line number are required. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason More detail about the failure. + */ + IconvInitializationException(const char* file, int line, const std::string& reason); + +#ifndef ICE_CPP11_COMPILER + virtual ~IconvInitializationException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual std::string ice_id() const; + + /** + * Prints a description of this exception to the given stream. + * @param str The output stream. + */ + virtual void ice_print(std::ostream& str) const; + +#ifndef ICE_CPP11_MAPPING + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual IconvInitializationException* ice_clone() const; +#endif + + /** + * Obtains the reason for the failure. + * @return The reason. + */ + std::string reason() const; + +private: + + std::string _reason; +}; + +} + +namespace IceInternal +{ + +// +// Converts charT encoded with internalCode to and from UTF-8 byte sequences +// +// The implementation allocates a pair of iconv_t on each thread, to avoid +// opening / closing iconv_t objects all the time. +// +// +template +class IconvStringConverter : public IceUtil::BasicStringConverter +{ +public: + + IconvStringConverter(const std::string&); + + virtual ~IconvStringConverter(); + + virtual Ice::Byte* toUTF8(const charT*, const charT*, Ice::UTF8Buffer&) const; + + virtual void fromUTF8(const Ice::Byte*, const Ice::Byte*, std::basic_string&) const; + +private: + + std::pair createDescriptors() const; + std::pair getDescriptors() const; + + static void cleanupKey(void*); + static void close(std::pair); + + mutable pthread_key_t _key; + const std::string _internalCode; +}; + +// +// Implementation +// + +#ifdef __SUNPRO_CC +extern "C" +{ + typedef void (*IcePthreadKeyDestructor)(void*); +} +#endif + +template +IconvStringConverter::IconvStringConverter(const std::string& internalCode) : + _internalCode(internalCode) +{ + // + // Verify that iconv supports conversion to/from internalCode + // + try + { + close(createDescriptors()); + } + catch(const Ice::IllegalConversionException& sce) + { + throw Ice::IconvInitializationException(__FILE__, __LINE__, sce.reason()); + } + + // + // Create thread-specific key + // +#ifdef __SUNPRO_CC + int rs = pthread_key_create(&_key, reinterpret_cast(&cleanupKey)); +#else + int rs = pthread_key_create(&_key, &cleanupKey); +#endif + + if(rs != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rs); + } +} + +template +IconvStringConverter::~IconvStringConverter() +{ + void* val = pthread_getspecific(_key); + if(val != 0) + { + cleanupKey(val); + } + if(pthread_key_delete(_key) != 0) + { + assert(0); + } +} + +template std::pair +IconvStringConverter::createDescriptors() const +{ + std::pair cdp; + + const char* externalCode = "UTF-8"; + + cdp.first = iconv_open(_internalCode.c_str(), externalCode); + if(cdp.first == iconv_t(-1)) + { + std::ostringstream os; + os << "iconv cannot convert from " << externalCode << " to " << _internalCode; + throw Ice::IllegalConversionException(__FILE__, __LINE__, os.str()); + } + + cdp.second = iconv_open(externalCode, _internalCode.c_str()); + if(cdp.second == iconv_t(-1)) + { + iconv_close(cdp.first); + std::ostringstream os; + os << "iconv cannot convert from " << _internalCode << " to " << externalCode; + throw Ice::IllegalConversionException(__FILE__, __LINE__, os.str()); + } + return cdp; +} + +template std::pair +IconvStringConverter::getDescriptors() const +{ + void* val = pthread_getspecific(_key); + if(val != 0) + { + return *static_cast*>(val); + } + else + { + std::pair cdp = createDescriptors(); + int rs = pthread_setspecific(_key, new std::pair(cdp)); + if(rs != 0) + { + throw IceUtil::ThreadSyscallException(__FILE__, __LINE__, rs); + } + return cdp; + } +} + +template /*static*/ void +IconvStringConverter::cleanupKey(void* val) +{ + std::pair* cdp = static_cast*>(val); + + close(*cdp); + delete cdp; +} + +template /*static*/ void +IconvStringConverter::close(std::pair cdp) +{ +#ifndef NDEBUG + int rs = iconv_close(cdp.first); + assert(rs == 0); + + rs = iconv_close(cdp.second); + assert(rs == 0); +#else + iconv_close(cdp.first); + iconv_close(cdp.second); +#endif +} + +template Ice::Byte* +IconvStringConverter::toUTF8(const charT* sourceStart, + const charT* sourceEnd, + Ice::UTF8Buffer& buf) const +{ + iconv_t cd = getDescriptors().second; + + // + // Reset cd + // +#ifdef NDEBUG + iconv(cd, 0, 0, 0, 0); +#else + size_t rs = iconv(cd, 0, 0, 0, 0); + assert(rs == 0); +#endif + +#ifdef ICE_CONST_ICONV_INBUF + const char* inbuf = reinterpret_cast(sourceStart); +#else + char* inbuf = reinterpret_cast(const_cast(sourceStart)); +#endif + size_t inbytesleft = static_cast(sourceEnd - sourceStart) * sizeof(charT); + char* outbuf = 0; + + size_t count = 0; + // + // Loop while we need more buffer space + // + do + { + size_t howMany = std::max(inbytesleft, size_t(4)); + outbuf = reinterpret_cast(buf.getMoreBytes(howMany, + reinterpret_cast(outbuf))); + count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &howMany); + } while(count == size_t(-1) && errno == E2BIG); + + if(count == size_t(-1)) + { + throw Ice::IllegalConversionException(__FILE__, __LINE__, + errno == 0 ? "Unknown error" : IceUtilInternal::errorToString(errno)); + } + return reinterpret_cast(outbuf); +} + +template void +IconvStringConverter::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, + std::basic_string& target) const +{ + iconv_t cd = getDescriptors().first; + + // + // Reset cd + // +#ifdef NDEBUG + iconv(cd, 0, 0, 0, 0); +#else + size_t rs = iconv(cd, 0, 0, 0, 0); + assert(rs == 0); +#endif + +#ifdef ICE_CONST_ICONV_INBUF + const char* inbuf = reinterpret_cast(sourceStart); +#else + char* inbuf = reinterpret_cast(const_cast(sourceStart)); +#endif + assert(sourceEnd > sourceStart); + size_t inbytesleft = static_cast(sourceEnd - sourceStart); + + char* outbuf = 0; + size_t outbytesleft = 0; + size_t count = 0; + + // + // Loop while we need more buffer space + // + do + { + size_t bytesused = 0; + if(outbuf != 0) + { + bytesused = static_cast(outbuf - reinterpret_cast(target.data())); + } + + const size_t increment = std::max(inbytesleft, 4); + target.resize(target.size() + increment); + outbuf = const_cast(reinterpret_cast(target.data())) + bytesused; + outbytesleft += increment * sizeof(charT); + + count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + + } while(count == size_t(-1) && errno == E2BIG); + + if(count == size_t(-1)) + { + throw Ice::IllegalConversionException(__FILE__, __LINE__, + errno == 0 ? "Unknown error" : IceUtilInternal::errorToString(errno)); + } + + target.resize(target.size() - (outbytesleft / sizeof(charT))); +} +} + +namespace Ice +{ + +/** + * Creates a string converter for the given code. + * @param internalCodeWithDefault The desired code. If empty or not provided, a default code is used. + * @return The converter object. + * @throws IconvInitializationException If the code is not supported. + */ +template +ICE_HANDLE > +createIconvStringConverter(const std::string& internalCodeWithDefault = "") +{ + std::string internalCode = internalCodeWithDefault; + + if(internalCode.empty()) + { + internalCode = nl_langinfo(CODESET); + } + + return ICE_MAKE_SHARED(IceInternal::IconvStringConverter, internalCode); +} + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/Identity.h b/Sources/IceCpp/include/Ice/Identity.h new file mode 100644 index 0000000..ca48426 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Identity.h @@ -0,0 +1,264 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Identity.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Identity_h__ +#define __Ice_Identity_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * The identity of an Ice object. In a proxy, an empty {@link Identity#name} denotes a nil + * proxy. An identity with an empty {@link Identity#name} and a non-empty {@link Identity#category} + * is illegal. You cannot add a servant with an empty name to the Active Servant Map. + * @see ServantLocator + * @see ObjectAdapter#addServantLocator + * \headerfile Ice/Ice.h + */ +struct Identity +{ + /** + * The name of the Ice object. + */ + ::std::string name; + /** + * The Ice object category. + */ + ::std::string category; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(name, category); + } +}; + +/** + * A mapping between identities and Ice objects. + */ +using ObjectDict = ::std::map>; + +/** + * A sequence of identities. + */ +using IdentitySeq = ::std::vector; + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits<::Ice::Identity> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; + +template +struct StreamReader<::Ice::Identity, S> +{ + static void read(S* istr, ::Ice::Identity& v) + { + istr->readAll(v.name, v.category); + } +}; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +/** + * The identity of an Ice object. In a proxy, an empty {@link Identity#name} denotes a nil + * proxy. An identity with an empty {@link Identity#name} and a non-empty {@link Identity#category} + * is illegal. You cannot add a servant with an empty name to the Active Servant Map. + * @see ServantLocator + * @see ObjectAdapter#addServantLocator + * \headerfile Ice/Ice.h + */ +struct Identity +{ + /** + * The name of the Ice object. + */ + ::std::string name; + /** + * The Ice object category. + */ + ::std::string category; + + bool operator==(const Identity& rhs_) const + { + if(this == &rhs_) + { + return true; + } + if(name != rhs_.name) + { + return false; + } + if(category != rhs_.category) + { + return false; + } + return true; + } + + bool operator<(const Identity& rhs_) const + { + if(this == &rhs_) + { + return false; + } + if(name < rhs_.name) + { + return true; + } + else if(rhs_.name < name) + { + return false; + } + if(category < rhs_.category) + { + return true; + } + else if(rhs_.category < category) + { + return false; + } + return false; + } + + bool operator!=(const Identity& rhs_) const + { + return !operator==(rhs_); + } + bool operator<=(const Identity& rhs_) const + { + return operator<(rhs_) || operator==(rhs_); + } + bool operator>(const Identity& rhs_) const + { + return !operator<(rhs_) && !operator==(rhs_); + } + bool operator>=(const Identity& rhs_) const + { + return !operator<(rhs_); + } +}; + +/** + * A mapping between identities and Ice objects. + */ +typedef ::std::map ObjectDict; + +/** + * A sequence of identities. + */ +typedef ::std::vector IdentitySeq; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::Identity> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; + +template +struct StreamWriter< ::Ice::Identity, S> +{ + static void write(S* ostr, const ::Ice::Identity& v) + { + ostr->write(v.name); + ostr->write(v.category); + } +}; + +template +struct StreamReader< ::Ice::Identity, S> +{ + static void read(S* istr, ::Ice::Identity& v) + { + istr->read(v.name); + istr->read(v.category); + } +}; + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ImplicitContext.h b/Sources/IceCpp/include/Ice/ImplicitContext.h new file mode 100644 index 0000000..2a9ec73 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ImplicitContext.h @@ -0,0 +1,284 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContext.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ImplicitContext_h__ +#define __Ice_ImplicitContext_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ImplicitContext; + +} + +namespace Ice +{ + +/** + * An interface to associate implict contexts with communicators. + * + * When you make a remote invocation without an explicit context parameter, + * Ice uses the per-proxy context (if any) combined with the ImplicitContext + * associated with the communicator. + * + * Ice provides several implementations of ImplicitContext. The implementation + * used depends on the value of the Ice.ImplicitContext property. + *
+ *
None (default)
+ *
No implicit context at all.
+ *
PerThread
+ *
The implementation maintains a context per thread.
+ *
Shared
+ *
The implementation maintains a single context shared by all threads.
+ *
+ * + * ImplicitContext also provides a number of operations to create, update or retrieve + * an entry in the underlying context without first retrieving a copy of the entire + * context. These operations correspond to a subset of the java.util.Map methods, + * with java.lang.Object replaced by string and null replaced by the empty-string. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ImplicitContext +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ImplicitContext(); + + /** + * Get a copy of the underlying context. + * @return A copy of the underlying context. + */ + virtual ::Ice::Context getContext() const = 0; + + /** + * Set the underlying context. + * @param newContext The new context. + */ + virtual void setContext(const Context& newContext) = 0; + + /** + * Check if this key has an associated value in the underlying context. + * @param key The key. + * @return True if the key has an associated value, False otherwise. + */ + virtual bool containsKey(const ::std::string& key) const = 0; + + /** + * Get the value associated with the given key in the underlying context. + * Returns an empty string if no value is associated with the key. + * {@link #containsKey} allows you to distinguish between an empty-string value and + * no value at all. + * @param key The key. + * @return The value associated with the key. + */ + virtual ::std::string get(const ::std::string& key) const = 0; + + /** + * Create or update a key/value entry in the underlying context. + * @param key The key. + * @param value The value. + * @return The previous value associated with the key, if any. + */ + virtual ::std::string put(const ::std::string& key, const ::std::string& value) = 0; + + /** + * Remove the entry for the given key in the underlying context. + * @param key The key. + * @return The value associated with the key, if any. + */ + virtual ::std::string remove(const ::std::string& key) = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ImplicitContextPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ImplicitContext; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ImplicitContext*); +/// \endcond +typedef ::IceInternal::Handle< ImplicitContext> ImplicitContextPtr; + +} + +namespace Ice +{ + +/** + * An interface to associate implict contexts with communicators. + * + * When you make a remote invocation without an explicit context parameter, + * Ice uses the per-proxy context (if any) combined with the ImplicitContext + * associated with the communicator. + * + * Ice provides several implementations of ImplicitContext. The implementation + * used depends on the value of the Ice.ImplicitContext property. + *
+ *
None (default)
+ *
No implicit context at all.
+ *
PerThread
+ *
The implementation maintains a context per thread.
+ *
Shared
+ *
The implementation maintains a single context shared by all threads.
+ *
+ * + * ImplicitContext also provides a number of operations to create, update or retrieve + * an entry in the underlying context without first retrieving a copy of the entire + * context. These operations correspond to a subset of the java.util.Map methods, + * with java.lang.Object replaced by string and null replaced by the empty-string. + * \headerfile Ice/Ice.h + */ +class ICE_API ImplicitContext : public virtual LocalObject +{ +public: + + typedef ImplicitContextPtr PointerType; + + virtual ~ImplicitContext(); + +#ifdef ICE_CPP11_COMPILER + ImplicitContext() = default; + ImplicitContext(const ImplicitContext&) = default; + ImplicitContext& operator=(const ImplicitContext&) = default; +#endif + + /** + * Get a copy of the underlying context. + * @return A copy of the underlying context. + */ + virtual Context getContext() const = 0; + + /** + * Set the underlying context. + * @param newContext The new context. + */ + virtual void setContext(const Context& newContext) = 0; + + /** + * Check if this key has an associated value in the underlying context. + * @param key The key. + * @return True if the key has an associated value, False otherwise. + */ + virtual bool containsKey(const ::std::string& key) const = 0; + + /** + * Get the value associated with the given key in the underlying context. + * Returns an empty string if no value is associated with the key. + * {@link #containsKey} allows you to distinguish between an empty-string value and + * no value at all. + * @param key The key. + * @return The value associated with the key. + */ + virtual ::std::string get(const ::std::string& key) const = 0; + + /** + * Create or update a key/value entry in the underlying context. + * @param key The key. + * @param value The value. + * @return The previous value associated with the key, if any. + */ + virtual ::std::string put(const ::std::string& key, const ::std::string& value) = 0; + + /** + * Remove the entry for the given key in the underlying context. + * @param key The key. + * @return The value associated with the key, if any. + */ + virtual ::std::string remove(const ::std::string& key) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ImplicitContext& lhs, const ImplicitContext& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ImplicitContext& lhs, const ImplicitContext& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ImplicitContextF.h b/Sources/IceCpp/include/Ice/ImplicitContextF.h new file mode 100644 index 0000000..1edb064 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ImplicitContextF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ImplicitContextF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ImplicitContextF_h__ +#define __Ice_ImplicitContextF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ImplicitContext; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ImplicitContextPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ImplicitContext; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ImplicitContext*); +/// \endcond +typedef ::IceInternal::Handle< ImplicitContext> ImplicitContextPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ImplicitContextI.h b/Sources/IceCpp/include/Ice/ImplicitContextI.h new file mode 100644 index 0000000..7b412a7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ImplicitContextI.h @@ -0,0 +1,48 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IMPLICIT_CONTEXT_I_H +#define ICE_IMPLICIT_CONTEXT_I_H + +#include + +namespace Ice +{ + +// +// The base class for all ImplicitContext implementations +// +class ImplicitContextI; +ICE_DEFINE_PTR(ImplicitContextIPtr,ImplicitContextI); + +class ImplicitContextI : public ImplicitContext +{ +public: + + static ImplicitContextIPtr create(const std::string&); + +#ifdef _WIN32 + static void cleanupThread(); +#endif + + // + // Marshals the underlying context plus the given context + // (entries in the given context overwrite entries in + // the underlying context) + // + virtual void write(const Context&, ::Ice::OutputStream*) const = 0; + + // + // Combines the underlying context plus the given context + // (entries in the given context overwrite entries in + // the underlying context) + // + virtual void combine(const Context&, Context&) const = 0; + +}; + +ICE_DEFINE_PTR(ImplicitContextIPtr, ImplicitContextI); + +} +#endif diff --git a/Sources/IceCpp/include/Ice/Incoming.h b/Sources/IceCpp/include/Ice/Incoming.h new file mode 100644 index 0000000..e7e78d6 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Incoming.h @@ -0,0 +1,225 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INCOMING_H +#define ICE_INCOMING_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef ICE_CPP11_MAPPING + +namespace Ice +{ + +/** + * Base class for marshaled result structures, which are generated for operations having the + * marshaled-result metadata tag. + * \headerfile Ice/Ice.h + */ +class ICE_API MarshaledResult +{ +public: + + /** + * The constructor requires the Current object that was passed to the servant. + */ + MarshaledResult(const Current& current); + + /** + * Obtains the output stream that is used to marshal the results. + * @return The output stream. + */ + std::shared_ptr getOutputStream() const + { + return ostr; + } + +protected: + + /** The output stream used to marshal the results. */ + std::shared_ptr ostr; +}; + +} + +#endif + +namespace IceInternal +{ + +class ICE_API IncomingBase : private IceUtil::noncopyable +{ +public: + + Ice::OutputStream* startWriteParams(); + void endWriteParams(); + void writeEmptyParams(); + void writeParamEncaps(const Ice::Byte*, Ice::Int, bool); + +#ifdef ICE_CPP11_MAPPING + void setMarshaledResult(const Ice::MarshaledResult&); +#endif + + void response(bool); + void exception(const std::exception&, bool); + void exception(const std::string&, bool); +#if defined(_MSC_VER) && (_MSC_VER == 1500) + // + // COMPILERFIX v90 get confused with overloads above + // when passing a const char* as first argument. + // + void exception(const char* msg, bool amd) + { + exception(std::string(msg), amd); + } +#endif + +protected: + + IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int); + IncomingBase(IncomingBase&); + + void warning(const Ice::Exception&) const; + void warning(const std::string&) const; + + bool servantLocatorFinished(bool); + + void handleException(const std::exception&, bool); + void handleException(const std::string&, bool); + +#if defined(_MSC_VER) && (_MSC_VER == 1500) + // + // COMPILERFIX v90 get confused with overloads above + // when passing a const char* as first argument. + // + void handleException(const char* msg, bool amd) + { + handleException(std::string(msg), amd); + } +#endif + + Ice::Current _current; + Ice::ObjectPtr _servant; + Ice::ServantLocatorPtr _locator; +#ifdef ICE_CPP11_MAPPING + ::std::shared_ptr _cookie; +#else + Ice::LocalObjectPtr _cookie; +#endif + DispatchObserver _observer; + bool _response; + Ice::Byte _compress; + Ice::FormatType _format; + Ice::OutputStream _os; + + // + // Optimization. The request handler may not be deleted while a + // stack-allocated Incoming still holds it. + // + ResponseHandler* _responseHandler; + +#ifdef ICE_CPP11_MAPPING + using DispatchInterceptorCallbacks = std::deque, + std::function>>; +#else + typedef std::deque DispatchInterceptorCallbacks; +#endif + DispatchInterceptorCallbacks _interceptorCBs; +}; + +// TODO: fix this warning +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API Incoming : public IncomingBase +{ +public: + + Incoming(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int); + + const Ice::Current& getCurrent() + { + return _current; + } + +#ifdef ICE_CPP11_MAPPING + void push(std::function, std::function); +#else + void push(const Ice::DispatchInterceptorAsyncCallbackPtr&); +#endif + void pop(); + + void setAsync(const IncomingAsyncPtr& in) + { + assert(!_inAsync); + _inAsync = in; + } + + void startOver(); + + void setFormat(Ice::FormatType format) + { + _format = format; + } + + void invoke(const ServantManagerPtr&, Ice::InputStream*); + + // Inlined for speed optimization. + void skipReadParams() + { + _current.encoding = _is->skipEncapsulation(); + } + Ice::InputStream* startReadParams() + { + // + // Remember the encoding used by the input parameters, we'll + // encode the response parameters with the same encoding. + // + _current.encoding = _is->startEncapsulation(); + return _is; + } + void endReadParams() const + { + _is->endEncapsulation(); + } + void readEmptyParams() + { + _current.encoding = _is->skipEmptyEncapsulation(); + } + void readParamEncaps(const Ice::Byte*& v, Ice::Int& sz) + { + _current.encoding = _is->readEncapsulation(v, sz); + } + +private: + + friend class IncomingAsync; + + Ice::InputStream* _is; + Ice::Byte* _inParamPos; + + IncomingAsyncPtr _inAsync; +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/IncomingAsync.h b/Sources/IceCpp/include/Ice/IncomingAsync.h new file mode 100644 index 0000000..451cc13 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IncomingAsync.h @@ -0,0 +1,186 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INCOMING_ASYNC_H +#define ICE_INCOMING_ASYNC_H + +#include +#include + +#ifndef ICE_CPP11_MAPPING +namespace Ice +{ + +/** + * Base class for generated AMD callback classes. + * \headerfile Ice/Ice.h + */ +class ICE_API AMDCallback : public Ice::LocalObject +{ +public: + + virtual ~AMDCallback(); + + /** + * Completes the asynchronous request with the given exception. + * @param ex The exception that completed the request. + */ + virtual void ice_exception(const ::std::exception& ex) = 0; + + /** + * Completes the asynchronous request with an UnknownException. + */ + virtual void ice_exception() = 0; +}; + +} +#endif + +namespace IceInternal +{ + +// TODO: fix this warning +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +// +// We need virtual inheritance from AMDCallback, because we use multiple +// inheritance from Ice::AMDCallback for generated AMD code. +// +class ICE_API IncomingAsync : public IncomingBase, +#ifdef ICE_CPP11_MAPPING + public ::std::enable_shared_from_this +#else + public virtual Ice::AMDCallback +#endif +{ +public: + + IncomingAsync(Incoming&); + +#ifdef ICE_CPP11_MAPPING + + static std::shared_ptr create(Incoming&); + + std::function response() + { + auto self = shared_from_this(); + return [self]() + { + self->writeEmptyParams(); + self->completed(); + }; + } + + template + std::function response() + { + auto self = shared_from_this(); + return [self](const T& marshaledResult) + { + self->setMarshaledResult(marshaledResult); + self->completed(); + }; + } + + std::function exception() + { + auto self = shared_from_this(); + return [self](std::exception_ptr ex) { self->completed(ex); }; + } + +#else + + virtual void ice_exception(const ::std::exception&); + virtual void ice_exception(); + +#endif + + void kill(Incoming&); + + void completed(); + +#ifdef ICE_CPP11_MAPPING + void completed(std::exception_ptr); +#endif + +private: + + void checkResponseSent(); + bool _responseSent; + + // + // We need a separate ConnectionIPtr, because IncomingBase only + // holds a ConnectionI* for optimization. + // + const ResponseHandlerPtr _responseHandlerCopy; +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +} + +#ifndef ICE_CPP11_MAPPING +namespace Ice +{ + +/** + * Base class for the AMD callback for BlobjectAsync::ice_invoke_async. + * \headerfile Ice/Ice.h + */ +class ICE_API AMD_Object_ice_invoke : public virtual Ice::AMDCallback +{ +public: + + virtual ~AMD_Object_ice_invoke(); + + /** + * Completes the request. + * @param ok True if the request completed successfully, in which case bytes contains an encapsulation + * of the marshaled results. False if the request completed with a user exception, in which case bytes + * contains an encapsulation of the marshaled user exception. + * @param bytes An encapsulation of the results or user exception. + */ + virtual void ice_response(bool ok, const std::vector& bytes) = 0; + + /** + * Completes the request. + * @param ok True if the request completed successfully, in which case bytes contains an encapsulation + * of the marshaled results. False if the request completed with a user exception, in which case bytes + * contains an encapsulation of the marshaled user exception. + * @param bytes An encapsulation of the results or user exception. + */ + virtual void ice_response(bool ok, const std::pair& bytes) = 0; +}; + +} + +/// \cond INTERNAL +namespace IceAsync +{ + +namespace Ice +{ + +class ICE_API AMD_Object_ice_invoke : public ::Ice::AMD_Object_ice_invoke, public IceInternal::IncomingAsync +{ +public: + + AMD_Object_ice_invoke(IceInternal::Incoming&); + + virtual void ice_response(bool, const std::vector< ::Ice::Byte>&); + virtual void ice_response(bool, const std::pair&); +}; + +} + +} +/// \endcond +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/IncomingAsyncF.h b/Sources/IceCpp/include/Ice/IncomingAsyncF.h new file mode 100644 index 0000000..269ab77 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IncomingAsyncF.h @@ -0,0 +1,36 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INCOMING_ASYNC_F_H +#define ICE_INCOMING_ASYNC_F_H + +#include + +#include + +namespace IceInternal +{ + +class IncomingAsync; +#ifdef ICE_CPP11_MAPPING +using IncomingAsyncPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(IncomingAsync*); +typedef IceInternal::Handle IncomingAsyncPtr; +#endif + +} + +#ifndef ICE_CPP11_MAPPING +namespace Ice +{ + +class AMD_Object_ice_invoke; +ICE_API IceUtil::Shared* upCast(::Ice::AMD_Object_ice_invoke*); +typedef IceInternal::Handle AMD_Object_ice_invokePtr; + +} +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/IncomingRequest.h b/Sources/IceCpp/include/Ice/IncomingRequest.h new file mode 100644 index 0000000..1d9aea4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/IncomingRequest.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INCOMING_REQUEST_H +#define ICE_INCOMING_REQUEST_H + +#include +#include + +namespace IceInternal +{ + +// +// Adapts Incoming to Ice::Request +// (the goal here is to avoid adding any virtual function to Incoming) +// +class ICE_API IncomingRequest : public Ice::Request +{ +public: + + IncomingRequest(Incoming& in) : _in(in) + { + } + + virtual const Ice::Current& getCurrent(); + + Incoming& _in; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Initialize.h b/Sources/IceCpp/include/Ice/Initialize.h new file mode 100644 index 0000000..44d2338 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Initialize.h @@ -0,0 +1,957 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INITIALIZE_H +#define ICE_INITIALIZE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING +# define ICE_CONFIG_FILE_STRING const std::string& +#else +# define ICE_CONFIG_FILE_STRING const char* +#endif + +namespace Ice +{ + +/** + * Converts an argument vector into a string sequence. + * @param argc The number of arguments in argv. + * @param argv The arguments. + * @return A string sequence containing the arguments. + */ +ICE_API StringSeq argsToStringSeq(int argc, const char* const argv[]); + +#ifdef _WIN32 +/** + * Converts an argument vector into a string sequence. + * @param argc The number of arguments in argv. + * @param argv The arguments. + * @return A string sequence containing the arguments. + */ +ICE_API StringSeq argsToStringSeq(int argc, const wchar_t* const argv[]); +#endif + +/** + * Updates the argument vector to match the contents of the string sequence. + * This function assumes that the string sequence only contains + * elements of the argument vector. The function shifts the + * the argument vector elements so that the vector matches the + * contents of the sequence. + * @param seq The string sequence returned from a call to argsToStringSeq. + * @param argc Updated to reflect the size of the sequence. + * @param argv Elements are shifted to match the sequence. + */ +ICE_API void stringSeqToArgs(const StringSeq& seq, int& argc, const char* argv[]); + +/** + * Updates the argument vector to match the contents of the string sequence. + * This function assumes that the string sequence only contains + * elements of the argument vector. The function shifts the + * the argument vector elements so that the vector matches the + * contents of the sequence. + * @param seq The string sequence returned from a call to argsToStringSeq. + * @param argc Updated to reflect the size of the sequence. + * @param argv Elements are shifted to match the sequence. + */ +inline void stringSeqToArgs(const StringSeq& seq, int& argc, char* argv[]) +{ + return stringSeqToArgs(seq, argc, const_cast(argv)); +} + +#ifdef _WIN32 +/** + * Updates the argument vector to match the contents of the string sequence. + * This function assumes that the string sequence only contains + * elements of the argument vector. The function shifts the + * the argument vector elements so that the vector matches the + * contents of the sequence. + * @param seq The string sequence returned from a call to argsToStringSeq. + */ +ICE_API void stringSeqToArgs(const StringSeq& seq, int& argc, const wchar_t* argv[]); + +/** + * Updates the argument vector to match the contents of the string sequence. + * This function assumes that the string sequence only contains + * elements of the argument vector. The function shifts the + * the argument vector elements so that the vector matches the + * contents of the sequence. + * @param seq The string sequence returned from a call to argsToStringSeq. + */ +inline void stringSeqToArgs(const StringSeq& seq, int& argc, wchar_t* argv[]) +{ + return stringSeqToArgs(seq, argc, const_cast(argv)); +} +#endif + +/** + * Creates a new empty property set. + * + * @return A new empty property set. + */ +ICE_API PropertiesPtr createProperties(); + +/** + * Creates a property set initialized from command-line arguments + * and a default property set. + * + * @param seq Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this container upon return. + * + * @param defaults Default values for the property set. Settings in + * configuration files and the arguments override these defaults. + * + * @return A new property set initialized with the property settings + * that were removed from the argument vector. + */ +ICE_API PropertiesPtr createProperties(StringSeq& seq, const PropertiesPtr& defaults = 0); + +/** + * Creates a property set initialized from command-line arguments + * and a default property set. + * + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * + * @param defaults Default values for the property set. Settings in + * configuration files and the arguments override these defaults. + * + * @return A new property set initialized with the property settings + * that were removed from the argument vector. + */ +ICE_API PropertiesPtr createProperties(int& argc, const char* argv[], const PropertiesPtr& defaults = 0); + +/** + * Creates a property set initialized from command-line arguments + * and a default property set. + * + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * + * @param defaults Default values for the property set. Settings in + * configuration files and the arguments override these defaults. + * + * @return A new property set initialized with the property settings + * that were removed from the argument vector. + */ +inline PropertiesPtr createProperties(int& argc, char* argv[], const PropertiesPtr& defaults = 0) +{ + return createProperties(argc, const_cast(argv), defaults); +} + +#ifdef _WIN32 +/** + * Creates a property set initialized from command-line arguments + * and a default property set. + * + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * + * @param defaults Default values for the property set. Settings in + * configuration files and the arguments override these defaults. + * + * @return A new property set initialized with the property settings + * that were removed from the argument vector. + */ +ICE_API PropertiesPtr createProperties(int& argc, const wchar_t* argv[], const PropertiesPtr& defaults = 0); + +/** + * Creates a property set initialized from command-line arguments + * and a default property set. + * + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * + * @param defaults Default values for the property set. Settings in + * configuration files and the arguments override these defaults. + * + * @return A new property set initialized with the property settings + * that were removed from the argument vector. + */ +inline PropertiesPtr createProperties(int& argc, wchar_t* argv[], const PropertiesPtr& defaults = 0) +{ + return createProperties(argc, const_cast(argv), defaults); +} +#endif + +/** + * Base class for a thread notification hook. An application can subclass this class, + * implement start and stop, and install an instance in InitializationData in order + * to receive notifications when Ice threads are started and stopped. + * \headerfile Ice/Ice.h + */ +class ICE_API ThreadNotification : public IceUtil::Shared +{ +public: + + /** + * Called from the new Ice thread at startup. + */ + virtual void start() = 0; + + /** + * Called from an Ice thread that is about to stop. + */ + virtual void stop() = 0; +}; + +typedef IceUtil::Handle ThreadNotificationPtr; + +/** + * A special plug-in that installs a thread hook during a communicator's initialization. + * Both initialize and destroy are no-op. See InitializationData. + * \headerfile Ice/Ice.h + */ +class ICE_API ThreadHookPlugin : public Ice::Plugin +{ +public: + +#ifdef ICE_CPP11_MAPPING + /** + * Installs the thread hooks. + * @param communicator The communicator in which to install the thread hooks. + * @param start The start callback. + * @param stop The stop callback. + */ + ThreadHookPlugin(const CommunicatorPtr& communicator, std::function start, std::function stop); +#else + /** + * Installs the thread hooks. + * @param communicator The communicator in which to install the thread hooks. + * @param hook The thread notification callback object. + */ + ThreadHookPlugin(const CommunicatorPtr& communicator, const ThreadNotificationPtr& hook); +#endif + + /** Not used. */ + virtual void initialize(); + + /** Not used. */ + virtual void destroy(); +}; + +/** + * Encapsulates data to initialize a communicator. + * \headerfile Ice/Ice.h + */ +struct InitializationData +{ + /** + * The properties for the communicator. + */ + PropertiesPtr properties; + + /** + * The logger for the communicator. + */ + LoggerPtr logger; + + /** + * The communicator observer used by the Ice run-time. + */ + Instrumentation::CommunicatorObserverPtr observer; + +#ifdef ICE_CPP11_MAPPING + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdocumentation" // param/return is not recognized for std::function data members +#endif + + /** + * Called whenever the communicator starts a new thread. + */ + std::function threadStart; + + /** + * Called whenever a thread created by the communicator is about to be destroyed. + */ + std::function threadStop; + + /** + * You can control which thread receives operation invocations and AMI + * callbacks by supplying a dispatcher. + * + * For example, you can use this dispatching facility to ensure that + * all invocations and callbacks are dispatched in a GUI event loop + * thread so that it is safe to invoke directly on GUI objects. + * + * The dispatcher is responsible for running (dispatching) the + * invocation or AMI callback on its favorite thread. + * @param call Represents the invocation. The dispatcher must eventually invoke this function. + * @param con The connection associated with this dispatch, or nil if no connection is + * associated with it. + */ + std::function call, const std::shared_ptr& con)> dispatcher; + + /** + * Applications that make use of compact type IDs to conserve space + * when marshaling class instances, and also use the streaming API to + * extract such classes, can intercept the translation between compact + * type IDs and their corresponding string type IDs by installing a + * compact ID resolver. + * @param id The compact ID. + * @return The fully-scoped type ID such as "::Module::Class", or an empty string if + * the compact ID is unknown. + */ + std::function compactIdResolver; + + /** + * The batch request interceptor, which is called by the Ice run time to enqueue a batch request. + * @param req An object representing the batch request. + * @param count The number of requests currently in the queue. + * @param size The number of bytes consumed by the requests currently in the queue. + */ + std::function batchRequestInterceptor; + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#else + /** + * The thread hook for the communicator. + */ + ThreadNotificationPtr threadHook; + + /** + * You can control which thread receives operation invocations and AMI + * callbacks by supplying a dispatcher. + * + * For example, you can use this dispatching facility to ensure that + * all invocations and callbacks are dispatched in a GUI event loop + * thread so that it is safe to invoke directly on GUI objects. + * + * The dispatcher is responsible for running (dispatching) the + * invocation or AMI callback on its favorite thread. It must eventually + * execute the provided call. + */ + DispatcherPtr dispatcher; + + /** + * Applications that make use of compact type IDs to conserve space + * when marshaling class instances, and also use the streaming API to + * extract such classes, can intercept the translation between compact + * type IDs and their corresponding string type IDs by installing a + * compact ID resolver. + */ + CompactIdResolverPtr compactIdResolver; + + /** + * The batch request interceptor. + */ + BatchRequestInterceptorPtr batchRequestInterceptor; +#endif + + /** + * The value factory manager. + */ + ValueFactoryManagerPtr valueFactoryManager; +}; + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(int& argc, const char* argv[], + const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +inline CommunicatorPtr initialize(int& argc, char* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION) +{ + return initialize(argc, const_cast(argv), initData, version); +} + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(int& argc, const char* argv[], ICE_CONFIG_FILE_STRING configFile, + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +inline CommunicatorPtr initialize(int& argc, char* argv[], ICE_CONFIG_FILE_STRING configFile, + int version = ICE_INT_VERSION) +{ + return initialize(argc, const_cast(argv), configFile, version); +} + +#ifdef _WIN32 +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(int& argc, const wchar_t* argv[], + const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +inline CommunicatorPtr initialize(int& argc, wchar_t* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION) +{ + return initialize(argc, const_cast(argv), initData, version); +} + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(int& argc, const wchar_t* argv[], ICE_CONFIG_FILE_STRING configFile, + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +inline CommunicatorPtr initialize(int& argc, wchar_t* argv[], ICE_CONFIG_FILE_STRING configFile, + int version = ICE_INT_VERSION) +{ + return initialize(argc, const_cast(argv), configFile, version); +} +#endif + +/** + * Initializes a new communicator. + * @param seq Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this container upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(StringSeq& seq, const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param seq Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this container upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(StringSeq& seq, ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +/** + * Initializes a new communicator. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator. + */ +ICE_API CommunicatorPtr initialize(ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); + +/** + * Obtains the per-process logger. This logger is used by all communicators that do not have their + * own specific logger established at the time a communicator is created. + * @return The current per-process logger instance. + */ +ICE_API LoggerPtr getProcessLogger(); + +/** + * Sets the per-process logger. This logger is used by all communicators that do not have their + * own specific logger established at the time a communicator is created. + * @param logger The new per-process logger instance. + */ +ICE_API void setProcessLogger(const LoggerPtr& logger); + +/** + * A plug-in factory function is responsible for creating an Ice plug-in. + * @param communicator The communicator in which the plug-in will be installed. + * @param name The name assigned to the plug-in. + * @param args Additional arguments included in the plug-in's configuration. + * @return The new plug-in object. Returning nil will cause the run time to raise PluginInitializationException. + */ +typedef Ice::Plugin* (*PluginFactory)(const ::Ice::CommunicatorPtr& communicator, const std::string& name, + const ::Ice::StringSeq& args); + +/** + * Manually registers a plug-in factory function. + * @param name The name assigned to the plug-in. + * @param factory The factory function. + * @param loadOnInit If true, the plug-in is always loaded (created) during communicator initialization, + * even if Ice.Plugin.name is not set. When false, the plug-in is loaded (created) during communication + * initialization only if Ice.Plugin.name is set to a non-empty value (e.g.: Ice.Plugin.IceSSL=1). + */ +ICE_API void registerPluginFactory(const std::string& name, PluginFactory factory, bool loadOnInit); + +/** + * A helper class that uses Resource Acquisition Is Initialization (RAII) to initialize and hold a + * communicator instance, and automatically destroy the communicator when the holder goes out of scope. + * \headerfile Ice/Ice.h + */ +class ICE_API CommunicatorHolder +{ +public: + + /** + * The holder's initial state is empty. + */ + CommunicatorHolder(); + +#ifdef ICE_CPP11_MAPPING + + /** + * Calls initialize to create a communicator with the provided arguments. + * This constructor accepts all of the same overloaded argument styles as + * initialize. + */ + template + explicit CommunicatorHolder(T&&... args) : + _communicator(std::move(initialize(std::forward(args)...))) + { + } + + /** + * Adopts the given communicator. + * @param communicator The new communicator instance to hold. + */ + CommunicatorHolder(std::shared_ptr communicator); + + /** + * Adopts the given communicator. If this holder currently holds a communicator, + * it will be destroyed. + * @param communicator The new communicator instance to hold. + */ + CommunicatorHolder& operator=(std::shared_ptr communicator); + + CommunicatorHolder(const CommunicatorHolder&) = delete; + CommunicatorHolder(CommunicatorHolder&&) = default; + + /** + * Adopts the communicator in the given holder. If this holder currently holds a communicator, + * it will be destroyed. + * @param holder The holder from which to adopt a communicator. + */ + CommunicatorHolder& operator=(CommunicatorHolder&& holder) noexcept; + + /** + * Determines whether the holder contains an instance. + * @return True if the holder currently holds an instance, false otherwise. + */ + explicit operator bool() const; + +#else // C++98 mapping + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, const char* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, char* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, const char* argv[], const char* configFile, int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, char* argv[], const char* configFile, int version = ICE_INT_VERSION); + +# ifdef _WIN32 + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, const wchar_t* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, wchar_t* argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, const wchar_t* argv[], const char* configFile, int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param argc The number of arguments in argv. Upon return, this argument + * is updated to reflect the arguments still remaining in argv. + * @param argv Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this vector upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(int& argc, wchar_t* argv[], const char* configFile, int version = ICE_INT_VERSION); +# endif + + /** + * Initializes a new communicator. + * @param seq Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this container upon return. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + explicit CommunicatorHolder(StringSeq& seq, const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param seq Command-line arguments, possibly containing + * options to set properties. If the arguments include + * a --Ice.Config option, the corresponding configuration + * files are parsed. If the same property is set in a configuration + * file and in the arguments, the arguments take precedence. + * Recognized options are removed from this container upon return. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + CommunicatorHolder(StringSeq& seq, const char* configFile, int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + explicit CommunicatorHolder(const InitializationData& initData, int version = ICE_INT_VERSION); + + /** + * Initializes a new communicator. + * @param configFile The name of an Ice configuration file. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + */ + explicit CommunicatorHolder(const char* configFile, int version = ICE_INT_VERSION); + + /** + * Adopts the given communicator. + * @param communicator The new communicator instance to hold. + */ + CommunicatorHolder(const CommunicatorPtr& communicator); + + /** + * Adopts the given communicator. If this holder currently holds a communicator, + * it will be destroyed. + * @param communicator The new communicator instance to hold. + */ + CommunicatorHolder& operator=(const CommunicatorPtr& communicator); + + /** + * Determines whether the holder contains an instance. + * @return True if the holder currently holds an instance, false otherwise. + */ + operator bool() const; + + /// \cond INTERNAL + // + // Required for successful copy-initialization, but not + // defined as it should always be elided by the compiler. + CommunicatorHolder(const CommunicatorHolder&); + /// \endcond + +#endif + + ~CommunicatorHolder(); + + /** + * Obtains the communicator instance. + * @return The communicator held by this holder, or nil if the holder is empty. + */ + const CommunicatorPtr& communicator() const; + + /** + * Obtains the communicator instance. + * @return The communicator held by this holder, or nil if the holder is empty. + */ + const CommunicatorPtr& operator->() const; + + /** + * Obtains the communicator instance and clears the reference held by the holder. + * @return The communicator held by this holder, or nil if the holder is empty. + */ + CommunicatorPtr release(); + +private: + + CommunicatorPtr _communicator; +}; + +/** + * Converts a stringified identity into an Identity. + * @param str The stringified identity. + * @return An Identity structure containing the name and category components. + */ +ICE_API Identity stringToIdentity(const std::string& str); + +/** + * Converts an Identity structure into a string using the specified mode. + * @param id The identity structure. + * @param mode Affects the handling of non-ASCII characters and non-printable ASCII characters. + * @return The stringified identity. + */ +ICE_API std::string identityToString(const Identity& id, ToStringMode mode = ICE_ENUM(ToStringMode, Unicode)); + +} + +namespace IceInternal +{ + +// +// Some Ice extensions need access to the Ice internal instance. Do +// not use this operation for regular application code! It is intended +// to be used by modules such as Freeze. +// +ICE_API InstancePtr getInstance(const ::Ice::CommunicatorPtr&); +ICE_API IceUtil::TimerPtr getInstanceTimer(const ::Ice::CommunicatorPtr&); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/InputStream.h b/Sources/IceCpp/include/Ice/InputStream.h new file mode 100644 index 0000000..4c00ef0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/InputStream.h @@ -0,0 +1,1514 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INPUT_STREAM_H +#define ICE_INPUT_STREAM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class UserException; + +/// \cond INTERNAL +template inline void +patchHandle(void* addr, const ValuePtr& v) +{ +#ifdef ICE_CPP11_MAPPING + ::std::shared_ptr* handle = static_cast<::std::shared_ptr*>(addr); + *handle = ::std::dynamic_pointer_cast(v); + if(v && !(*handle)) + { + IceInternal::Ex::throwUOE(T::ice_staticId(), v); + } +#else + IceInternal::Handle* p = static_cast*>(addr); + _icePatchObjectPtr(*p, v); // Generated _icePatchObjectPtr function, necessary for forward declarations. +#endif +} +/// \endcond + +/** + * Interface for input streams used to extract Slice types from a sequence of bytes. + * \headerfile Ice/Ice.h + */ +class ICE_API InputStream : public IceInternal::Buffer +{ +public: + + typedef size_t size_type; + + /** + * Signature for a patch function, used to receive an unmarshaled value. + * @param addr The target address. + * @param v The unmarshaled value. + */ + typedef void (*PatchFunc)(void* addr, const ValuePtr& v); + + /** + * Constructs a stream using the latest encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + */ + InputStream(); + + /** + * Constructs a stream using the latest encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + * @param bytes The encoded data. + */ + InputStream(const std::vector& bytes); + + /** + * Constructs a stream using the latest encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + * @param bytes The encoded data. + */ + InputStream(const std::pair& bytes); + + /// \cond INTERNAL + InputStream(IceInternal::Buffer&, bool = false); + /// \endcond + + /** + * Constructs a stream using the communicator's default encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + */ + InputStream(const CommunicatorPtr& communicator); + + /** + * Constructs a stream using the communicator's default encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + * @param bytes The encoded data. + */ + InputStream(const CommunicatorPtr& communicator, const std::vector& bytes); + + /** + * Constructs a stream using the communicator's default encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + * @param bytes The encoded data. + */ + InputStream(const CommunicatorPtr& communicator, const std::pair& bytes); + + /// \cond INTERNAL + InputStream(const CommunicatorPtr& communicator, IceInternal::Buffer&, bool = false); + /// \endcond + + /** + * Constructs a stream using the given encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + * @param version The encoding version used to encode the data to be unmarshaled. + */ + InputStream(const EncodingVersion& version); + + /** + * Constructs a stream using the given encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + * @param version The encoding version used to encode the data to be unmarshaled. + * @param bytes The encoded data. + */ + InputStream(const EncodingVersion& version, const std::vector& bytes); + + /** + * Constructs a stream using the given encoding version but without a communicator. + * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks, + * you can provide Helpers for objects that are normally provided by a communicator. + * You can supply a communicator later by calling initialize(). + * @param version The encoding version used to encode the data to be unmarshaled. + * @param bytes The encoded data. + */ + InputStream(const EncodingVersion& version, const std::pair& bytes); + + /// \cond INTERNAL + InputStream(const EncodingVersion&, IceInternal::Buffer&, bool = false); + /// \endcond + + /** + * Constructs a stream using the given communicator and encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + * @param version The encoding version used to encode the data to be unmarshaled. + */ + InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version); + + /** + * Constructs a stream using the given communicator and encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + * @param version The encoding version used to encode the data to be unmarshaled. + * @param bytes The encoded data. + */ + InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version, const std::vector& bytes); + + /** + * Constructs a stream using the given communicator and encoding version. + * @param communicator The communicator to use for unmarshaling tasks. + * @param version The encoding version used to encode the data to be unmarshaled. + * @param bytes The encoded data. + */ + InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version, + const std::pair& bytes); + + /// \cond INTERNAL + InputStream(const CommunicatorPtr&, const EncodingVersion&, IceInternal::Buffer&, bool = false); + /// \endcond + + ~InputStream() + { + // Inlined for performance reasons. + + if(_currentEncaps != &_preAllocatedEncaps) + { + clear(); // Not inlined. + } + +#ifdef ICE_CPP11_MAPPING + + for(auto d: _deleters) + { + d(); + } +#endif + } + + /** + * Initializes the stream to use the communicator's default encoding version. + * Use initialize() if you originally constructed the stream without a communicator. + * @param communicator The communicator to use for unmarshaling tasks. + */ + void initialize(const CommunicatorPtr& communicator); + + /** + * Initializes the stream to use the given communicator and encoding version. + * Use initialize() if you originally constructed the stream without a communicator. + * @param communicator The communicator to use for unmarshaling tasks. + * @param version The encoding version used to encode the data to be unmarshaled. + */ + void initialize(const CommunicatorPtr& communicator, const EncodingVersion& version); + + /** + * Releases any data retained by encapsulations. + */ + void clear(); + + /// \cond INTERNAL + // + // Must return Instance*, because we don't hold an InstancePtr for + // optimization reasons (see comments below). + // + IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons. + /// \endcond + + /** + * Sets the value factory manager to use when unmarshaling value instances. If the stream + * was initialized with a communicator, the communicator's value factory manager will + * be used by default. + * + * @param vfm The value factory manager. + */ + void setValueFactoryManager(const ValueFactoryManagerPtr& vfm); + + /** + * Sets the logger to use when logging trace messages. If the stream + * was initialized with a communicator, the communicator's logger will + * be used by default. + * + * @param logger The logger to use for logging trace messages. + */ + void setLogger(const LoggerPtr& logger); + + /** + * Sets the compact ID resolver to use when unmarshaling value and exception + * instances. If the stream was initialized with a communicator, the communicator's + * resolver will be used by default. + * + * @param r The compact ID resolver. + */ +#ifdef ICE_CPP11_MAPPING + void setCompactIdResolver(std::function r); +#else + void setCompactIdResolver(const CompactIdResolverPtr& r); +#endif + +#ifndef ICE_CPP11_MAPPING + /** + * Indicates whether to mark instances of Slice classes as collectable. If the stream is + * initialized with a communicator, this setting defaults to the value of the + * Ice.CollectObjects property, otherwise the setting defaults to false. + * @param b True to mark instances as collectable, false otherwise. + */ + void setCollectObjects(bool b); +#endif + + /** + * Indicates whether to slice instances of Slice classes to a known Slice type when a more + * derived type is unknown. An instance is "sliced" when no static information is available + * for a Slice type ID and no factory can be found for that type, resulting in the creation + * of an instance of a less-derived type. If slicing is disabled in this situation, the + * stream raises the exception NoValueFactoryException. The default behavior is to allow slicing. + * @param b True to enable slicing, false otherwise. + */ + void setSliceValues(bool b); + + /** + * Indicates whether to log messages when instances of Slice classes are sliced. If the stream + * is initialized with a communicator, this setting defaults to the value of the Ice.Trace.Slicing + * property, otherwise the setting defaults to false. + * @param b True to enable logging, false otherwise. + */ + void setTraceSlicing(bool b); + + /** + * Sets an upper limit on the depth of a class graph. If this limit is exceeded during + * unmarshaling, the stream raises MarshalException. + * @param n The maximum depth. + */ + void setClassGraphDepthMax(size_t n); + + /** + * Obtains the closure data associated with this stream. + * @return The data as a void pointer. + */ + void* getClosure() const; + + /** + * Associates closure data with this stream. + * @param p The data as a void pointer. + * @return The previous closure data, or nil. + */ + void* setClosure(void* p); + + /** + * Swaps the contents of one stream with another. + * + * @param other The other stream. + */ + void swap(InputStream& other); + + /// \cond INTERNAL + void resetEncapsulation(); + /// \endcond + + /** + * Resizes the stream to a new size. + * + * @param sz The new size. + */ + void resize(Container::size_type sz) + { + b.resize(sz); + i = b.end(); + } + + /** + * Marks the start of a class instance. + */ + void startValue() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->startInstance(ValueSlice); + } + + /** + * Marks the end of a class instance. + * + * @param preserve Pass true and the stream will preserve the unknown slices of the instance, or false + * to discard the unknown slices. + * @return An object that encapsulates the unknown slice data. + */ + SlicedDataPtr endValue(bool preserve) + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->endInstance(preserve); + } + + /** + * Marks the start of a user exception. + */ + void startException() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->startInstance(ExceptionSlice); + } + + /** + * Marks the end of a user exception. + * + * @param preserve Pass true and the stream will preserve the unknown slices of the exception, or false + * to discard the unknown slices. + * @return An object that encapsulates the unknown slice data. + */ + SlicedDataPtr endException(bool preserve) + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->endInstance(preserve); + } + + /** + * Reads the start of an encapsulation. + * + * @return The encoding version used by the encapsulation. + */ + const EncodingVersion& startEncapsulation() + { + Encaps* oldEncaps = _currentEncaps; + if(!oldEncaps) // First allocated encaps? + { + _currentEncaps = &_preAllocatedEncaps; + } + else + { + _currentEncaps = new Encaps(); + _currentEncaps->previous = oldEncaps; + } + _currentEncaps->start = static_cast(i - b.begin()); + + // + // I don't use readSize() and writeSize() for encapsulations, + // because when creating an encapsulation, I must know in advance + // how many bytes the size information will require in the data + // stream. If I use an Int, it is always 4 bytes. For + // readSize()/writeSize(), it could be 1 or 5 bytes. + // + Int sz; + read(sz); + if(sz < 6) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + if(i - sizeof(Int) + sz > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + _currentEncaps->sz = sz; + + read(_currentEncaps->encoding); + IceInternal::checkSupportedEncoding(_currentEncaps->encoding); // Make sure the encoding is supported + + return _currentEncaps->encoding; + } + + /** + * Ends the current encapsulation. + */ + void endEncapsulation() + { + assert(_currentEncaps); + + if(_currentEncaps->encoding != Encoding_1_0) + { + skipOptionals(); + if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + throwEncapsulationException(__FILE__, __LINE__); + } + } + else if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + if(i + 1 != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + throwEncapsulationException(__FILE__, __LINE__); + } + + // + // Ice version < 3.3 had a bug where user exceptions with + // class members could be encoded with a trailing byte + // when dispatched with AMD. So we tolerate an extra byte + // in the encapsulation. + // + ++i; + } + + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + if(oldEncaps == &_preAllocatedEncaps) + { + oldEncaps->reset(); + } + else + { + delete oldEncaps; + } + } + + /** + * Skips an empty encapsulation. + * + * @return The encapsulation's encoding version. + */ + EncodingVersion skipEmptyEncapsulation() + { + Ice::Int sz; + read(sz); + if(sz < 6) + { + throwEncapsulationException(__FILE__, __LINE__); + } + if(i - sizeof(Ice::Int) + sz > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + Ice::EncodingVersion encoding; + read(encoding); + IceInternal::checkSupportedEncoding(encoding); // Make sure the encoding is supported + + if(encoding == Ice::Encoding_1_0) + { + if(sz != static_cast(sizeof(Ice::Int)) + 2) + { + throwEncapsulationException(__FILE__, __LINE__); + } + } + else + { + // Skip the optional content of the encapsulation if we are expecting an + // empty encapsulation. + i += static_cast(sz) - sizeof(Ice::Int) - 2; + } + return encoding; + } + + /** + * Returns a blob of bytes representing an encapsulation. + * + * @param v A pointer into the internal marshaling buffer representing the start of the encoded encapsulation. + * @param sz The number of bytes in the encapsulation. + * @return encoding The encapsulation's encoding version. + */ + EncodingVersion readEncapsulation(const Byte*& v, Int& sz) + { + EncodingVersion encoding; + v = i; + read(sz); + if(sz < 6) + { + throwEncapsulationException(__FILE__, __LINE__); + } + if(i - sizeof(Int) + sz > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + read(encoding); + i += static_cast(sz) - sizeof(Int) - 2; + return encoding; + } + + /** + * Determines the current encoding version. + * + * @return The encoding version. + */ + const EncodingVersion& getEncoding() const + { + return _currentEncaps ? _currentEncaps->encoding : _encoding; + } + + /** + * Determines the size of the current encapsulation, excluding the encapsulation header. + * + * @return The size of the encapsulated data. + */ + Int getEncapsulationSize(); + + /** + * Skips over an encapsulation. + * + * @return The encoding version of the skipped encapsulation. + */ + EncodingVersion skipEncapsulation(); + + /** + * Reads the start of a value or exception slice. + * + * @return The Slice type ID for this slice. + */ + std::string startSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->startSlice(); + } + + /** + * Indicates that the end of a value or exception slice has been reached. + */ + void endSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->endSlice(); + } + + /** + * Skips over a value or exception slice. + */ + void skipSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->skipSlice(); + } + + /** + * Indicates that unmarshaling is complete, except for any class instances. The application must call this method + * only if the stream actually contains class instances. Calling readPendingValues triggers the + * patch callbacks to inform the application that unmarshaling of an instance is complete. + */ + void readPendingValues(); + + /** + * Extracts a size from the stream. + * + * @return The extracted size. + */ + Int readSize() // Inlined for performance reasons. + { + Byte byte; + read(byte); + unsigned char val = static_cast(byte); + if(val == 255) + { + Int v; + read(v); + if(v < 0) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + return v; + } + else + { + return static_cast(static_cast(byte)); + } + } + + /** + * Reads and validates a sequence size. + * + * @param minSize The minimum size required by the sequence type. + * @return The extracted size. + */ + Int readAndCheckSeqSize(int minSize); + + /** + * Reads a blob of bytes from the stream. + * + * @param bytes The vector to hold a copy of the bytes from the marshaling buffer. + * @param sz The number of bytes to read. + */ + void readBlob(std::vector& bytes, Int sz); + + /** + * Reads a blob of bytes from the stream. + * + * @param v A pointer into the internal marshaling buffer representing the start of the blob. + * @param sz The number of bytes to read. + */ + void readBlob(const Byte*& v, Container::size_type sz) + { + if(sz > 0) + { + v = i; + if(static_cast(b.end() - i) < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + i += sz; + } + else + { + v = i; + } + } + + /** + * Reads a data value from the stream. + * @param v Holds the extracted data. + */ + template void read(T& v) + { + StreamHelper::helper>::read(this, v); + } + + /** + * Reads an optional data value from the stream. + * @param tag The tag ID. + * @param v Holds the extracted data (if any). + */ + template void read(Int tag, IceUtil::Optional& v) + { + if(readOptional(tag, StreamOptionalHelper::helper, + StreamableTraits::fixedLength>::optionalFormat)) + { +#ifdef ICE_CPP11_MAPPING + v.emplace(); +#else + v.__setIsSet(); +#endif + StreamOptionalHelper::helper, + StreamableTraits::fixedLength>::read(this, *v); + } + else + { + v = IceUtil::None; + } + } + +#ifdef ICE_CPP11_MAPPING + + /** + * Extracts a sequence of data values from the stream. + * @param v A pair of pointers representing the beginning and end of the sequence elements. + */ + template void read(std::pair& v) + { + auto holder = new std::vector; + _deleters.push_back([holder] { delete holder; }); + read(*holder); + if(holder->size() > 0) + { + v.first = holder->data(); + v.second = holder->data() + holder->size(); + } + else + { + v.first = 0; + v.second = 0; + } + } + + /** + * Reads a list of mandatory data values. + */ + template void readAll(T& v) + { + read(v); + } + + /** + * Reads a list of mandatory data values. + */ + template void readAll(T& v, Te&... ve) + { + read(v); + readAll(ve...); + } + + /** + * Reads a list of optional data values. + */ + template + void readAll(std::initializer_list tags, IceUtil::Optional& v) + { + read(*(tags.begin() + tags.size() - 1), v); + } + + /** + * Reads a list of optional data values. + */ + template + void readAll(std::initializer_list tags, IceUtil::Optional& v, IceUtil::Optional&... ve) + { + size_t index = tags.size() - sizeof...(ve) - 1; + read(*(tags.begin() + index), v); + readAll(tags, ve...); + } + +#endif + + /** + * Determine if an optional value is available for reading. + * + * @param tag The tag associated with the value. + * @param expectedFormat The optional format for the value. + * @return True if the value is present, false otherwise. + */ + bool readOptional(Int tag, OptionalFormat expectedFormat) + { + assert(_currentEncaps); + if(_currentEncaps->decoder) + { + return _currentEncaps->decoder->readOptional(tag, expectedFormat); + } + else + { + return readOptImpl(tag, expectedFormat); + } + } + + /** + * Reads a byte from the stream. + * @param v The extracted byte. + */ + void read(Byte& v) + { + if(i >= b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = *i++; + } + + /** + * Reads a sequence of bytes from the stream. + * @param v A vector to hold a copy of the bytes. + */ + void read(std::vector& v); + + /** + * Reads a sequence of bytes from the stream. + * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the + * sequence elements. + */ + void read(std::pair& v); + +#ifndef ICE_CPP11_MAPPING + /** + * Reads a sequence of bytes from the stream. + * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the + * sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr) + { + arr.reset(); + read(v); + } +#endif + + /** + * Reads a bool from the stream. + * @param v The extracted bool. + */ + void read(bool& v) + { + if(i >= b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = (0 != *i++); + } + + /** + * Reads a sequence of boolean values from the stream. + * @param v A vector to hold a copy of the boolean values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of boolean values from the stream. + * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the + * sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of boolean values from the stream. + * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the + * sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads a short from the stream. + * @param v The extracted short. + */ + void read(Short& v); + + /** + * Reads a sequence of shorts from the stream. + * @param v A vector to hold a copy of the short values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of boolean values from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of shorts from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads an int from the stream. + * @param v The extracted int. + */ + void read(Int& v) // Inlined for performance reasons. + { + if(b.end() - i < static_cast(sizeof(Int))) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Int); +#ifdef ICE_BIG_ENDIAN + Byte* dest = reinterpret_cast(&v) + sizeof(Int) - 1; + *dest-- = *src++; + *dest-- = *src++; + *dest-- = *src++; + *dest = *src; +#else + Byte* dest = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif + } + + /** + * Reads a sequence of ints from the stream. + * @param v A vector to hold a copy of the int values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of ints from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of ints from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads a long from the stream. + * @param v The extracted long. + */ + void read(Long& v); + + /** + * Reads a sequence of longs from the stream. + * @param v A vector to hold a copy of the long values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of longs from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of longs from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads a float from the stream. + * @param v The extracted float. + */ + void read(Float& v); + + /** + * Reads a sequence of floats from the stream. + * @param v A vector to hold a copy of the float values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of floats from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of floats from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads a double from the stream. + * @param v The extracted double. + */ + void read(Double& v); + + /** + * Reads a sequence of doubles from the stream. + * @param v A vector to hold a copy of the double values. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a sequence of doubles from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + */ + void read(std::pair& v); +#else + /** + * Reads a sequence of doubles from the stream. + * @param v A pair of pointers representing the start and end of the sequence elements. + * @param arr A scoped array. + */ + void read(std::pair& v, ::IceUtil::ScopedArray& arr); +#endif + + /** + * Reads a string from the stream. + * @param v The extracted string. + * @param convert Determines whether the string is processed by the string converter, if one + * is installed. The default behavior is to convert strings. + */ + void read(std::string& v, bool convert = true); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a string from the stream. + * @param vdata A pointer to the beginning of the string. + * @param vsize The number of bytes in the string. + * @param convert Determines whether the string is processed by the string converter, if one + * is installed. The default behavior is to convert strings. + */ + void read(const char*& vdata, size_t& vsize, bool convert = true); +#else + // For custom strings, convert = false + /** + * Reads a string from the stream. String conversion is disabled. + * @param vdata A pointer to the beginning of the string. + * @param vsize The number of bytes in the string. + */ + void read(const char*& vdata, size_t& vsize); + + // For custom strings, convert = true + /** + * Reads a string from the stream. String conversion is enabled. + * @param vdata A pointer to the beginning of the string. + * @param vsize The number of bytes in the string. + * @param holder Holds the string contents. + */ + void read(const char*& vdata, size_t& vsize, std::string& holder); +#endif + + /** + * Reads a sequence of strings from the stream. + * @param v The extracted string sequence. + * @param convert Determines whether strings are processed by the string converter, if one + * is installed. The default behavior is to convert the strings. + */ + void read(std::vector& v, bool convert = true); + + /** + * Reads a wide string from the stream. + * @param v The extracted string. + */ + void read(std::wstring& v); + + /** + * Reads a sequence of wide strings from the stream. + * @param v The extracted sequence. + */ + void read(std::vector& v); + +#ifdef ICE_CPP11_MAPPING + /** + * Reads a proxy from the stream. + * @return The proxy as the base ObjectPrx type. + */ + std::shared_ptr readProxy(); + + /** + * Reads a typed proxy from the stream. + * @param v The proxy as a user-defined type. + */ + template::value>::type* = nullptr> + void read(::std::shared_ptr& v) + { + ::std::shared_ptr proxy(readProxy()); + if(!proxy) + { + v = 0; + } + else + { + v = ::IceInternal::createProxy(); + v->_copyFrom(proxy); + } + } +#else + /** + * Reads a proxy from the stream. + * @param v The proxy as the base ObjectPrx type. + */ + void read(ObjectPrx& v); + + /** + * Reads a typed proxy from the stream. + * @param v The proxy as a user-defined type. + */ + template void read(IceInternal::ProxyHandle& v) + { + _readProxy(this, v); // Generated _readProxy method, necessary for forward declarations. + } +#endif + + /** + * Reads a value (instance of a Slice class) from the stream. + * @param v The instance. + */ +#ifdef ICE_CPP11_MAPPING // C++11 mapping + template::value>::type* = nullptr> + void read(::std::shared_ptr& v) + { + read(&patchHandle, &v); + } +#else // C++98 mapping + template void read(IceInternal::Handle& v) + { + read(&patchHandle, &v); + } +#endif + + /** + * Reads a value (instance of a Slice class) from the stream. + * @param patchFunc The patch callback function. + * @param patchAddr Closure data passed to the callback. + */ + void read(PatchFunc patchFunc, void* patchAddr) + { + initEncaps(); + _currentEncaps->decoder->read(patchFunc, patchAddr); + } + + /** + * Reads an enumerator from the stream. + * @param maxValue The maximum enumerator value in the definition. + * @return The enumerator value. + */ + Int readEnum(Int maxValue); + + /** + * Extracts a user exception from the stream and throws it. + * @param factory If provided, this factory is given the first opportunity to instantiate + * the exception. If not provided, or if the factory does not throw an exception when invoked, + * the stream will attempt to instantiate the exception using static type information. + * @throws UserException The user exception that was unmarshaled. + */ + void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory = ICE_NULLPTR); + + /** + * Skips one optional value with the given format. + * @param format The expected format of the optional, if present. + */ + void skipOptional(OptionalFormat format); + + /** + * Skips all remaining optional values. + */ + void skipOptionals(); + + /** + * Advances the current stream position by the given number of bytes. + * @param size The number of bytes to skip. + */ + void skip(size_type size) + { + if(i + size > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + i += size; + } + + /** + * Reads a size at the current position and skips that number of bytes. + */ + void skipSize() + { + Byte bt; + read(bt); + if(static_cast(bt) == 255) + { + skip(4); + } + } + + /** + * Obtains the current position of the stream. + * @return The current position. + */ + size_type pos() + { + return static_cast(i - b.begin()); + } + + /** + * Sets a new position for the stream. + * @param p The new position. + */ + void pos(size_type p) + { + i = b.begin() + p; + } + + /// \cond INTERNAL + InputStream(IceInternal::Instance*, const EncodingVersion&); + InputStream(IceInternal::Instance*, const EncodingVersion&, IceInternal::Buffer&, bool = false); + + void initialize(IceInternal::Instance*, const EncodingVersion&); + + bool readOptImpl(Int, OptionalFormat); + /// \endcond + +private: + + void initialize(const EncodingVersion&); + + // + // String + // + bool readConverted(std::string&, Int); + + // + // We can't throw these exception from inline functions from within + // this file, because we cannot include the header with the + // exceptions. Doing so would screw up the whole include file + // ordering. + // + void throwUnmarshalOutOfBoundsException(const char*, int); + void throwEncapsulationException(const char*, int); + + std::string resolveCompactId(int) const; + + void postUnmarshal(const ValuePtr&) const; + + class Encaps; + enum SliceType { NoSlice, ValueSlice, ExceptionSlice }; + + void traceSkipSlice(const std::string&, SliceType) const; + + ValueFactoryManagerPtr valueFactoryManager() const; + + LoggerPtr logger() const; + +#ifdef ICE_CPP11_MAPPING + std::function compactIdResolver() const; +#else + CompactIdResolverPtr compactIdResolver() const; +#endif + + typedef std::vector ValueList; + + class ICE_API EncapsDecoder : private ::IceUtil::noncopyable + { + public: + + virtual ~EncapsDecoder(); + + virtual void read(PatchFunc, void*) = 0; + virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory))) = 0; + + virtual void startInstance(SliceType) = 0; + virtual SlicedDataPtr endInstance(bool) = 0; + virtual const std::string& startSlice() = 0; + virtual void endSlice() = 0; + virtual void skipSlice() = 0; + + virtual bool readOptional(Int, OptionalFormat) + { + return false; + } + + virtual void readPendingValues() + { + } + + protected: + + EncapsDecoder(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + _stream(stream), _encaps(encaps), _sliceValues(sliceValues), _classGraphDepthMax(classGraphDepthMax), + _classGraphDepth(0), _valueFactoryManager(f), _typeIdIndex(0) + { + } + + std::string readTypeId(bool); + ValuePtr newInstance(const std::string&); + + void addPatchEntry(Int, PatchFunc, void*); + void unmarshal(Int, const ValuePtr&); + + typedef std::map IndexToPtrMap; + typedef std::map TypeIdMap; + + struct PatchEntry + { + PatchFunc patchFunc; + void* patchAddr; + size_t classGraphDepth; + }; + typedef std::vector PatchList; + typedef std::map PatchMap; + + InputStream* _stream; + Encaps* _encaps; + const bool _sliceValues; + const size_t _classGraphDepthMax; + size_t _classGraphDepth; + Ice::ValueFactoryManagerPtr _valueFactoryManager; + + // Encapsulation attributes for object un-marshalling + PatchMap _patchMap; + + private: + + // Encapsulation attributes for object un-marshalling + IndexToPtrMap _unmarshaledMap; + TypeIdMap _typeIdMap; + Int _typeIdIndex; + ValueList _valueList; + }; + + class ICE_API EncapsDecoder10 : public EncapsDecoder + { + public: + + EncapsDecoder10(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f), + _sliceType(NoSlice) + { + } + + virtual void read(PatchFunc, void*); + virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory))); + + virtual void startInstance(SliceType); + virtual SlicedDataPtr endInstance(bool); + virtual const std::string& startSlice(); + virtual void endSlice(); + virtual void skipSlice(); + + virtual void readPendingValues(); + + private: + + void readInstance(); + + // Instance attributes + SliceType _sliceType; + bool _skipFirstSlice; + + // Slice attributes + Int _sliceSize; + std::string _typeId; + }; + + class ICE_API EncapsDecoder11 : public EncapsDecoder + { + public: + + EncapsDecoder11(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f), + _preAllocatedInstanceData(0), _current(0), _valueIdIndex(1) + { + } + + virtual void read(PatchFunc, void*); + virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory))); + + virtual void startInstance(SliceType); + virtual SlicedDataPtr endInstance(bool); + virtual const std::string& startSlice(); + virtual void endSlice(); + virtual void skipSlice(); + + virtual bool readOptional(Int, OptionalFormat); + + private: + + Int readInstance(Int, PatchFunc, void*); + SlicedDataPtr readSlicedData(); + + struct IndirectPatchEntry + { + Int index; + PatchFunc patchFunc; + void* patchAddr; + }; + typedef std::vector IndirectPatchList; + + typedef std::vector IndexList; + typedef std::vector IndexListList; + + struct InstanceData + { + InstanceData(InstanceData* p) : previous(p), next(0) + { + if(previous) + { + previous->next = this; + } + } + + ~InstanceData() + { + if(next) + { + delete next; + } + } + + // Instance attributes + SliceType sliceType; + bool skipFirstSlice; + SliceInfoSeq slices; // Preserved slices. + IndexListList indirectionTables; + + // Slice attributes + Byte sliceFlags; + Int sliceSize; + std::string typeId; + int compactId; + IndirectPatchList indirectPatchList; + + InstanceData* previous; + InstanceData* next; + }; + InstanceData _preAllocatedInstanceData; + InstanceData* _current; + + void push(SliceType sliceType) + { + if(!_current) + { + _current = &_preAllocatedInstanceData; + } + else + { + _current = _current->next ? _current->next : new InstanceData(_current); + } + _current->sliceType = sliceType; + _current->skipFirstSlice = false; + } + + Int _valueIdIndex; // The ID of the next value to unmarshal. + }; + + class Encaps : private ::IceUtil::noncopyable + { + public: + + Encaps() : start(0), decoder(0), previous(0) + { + // Inlined for performance reasons. + } + ~Encaps() + { + // Inlined for performance reasons. + delete decoder; + } + void reset() + { + // Inlined for performance reasons. + delete decoder; + decoder = 0; + + previous = 0; + } + + Container::size_type start; + Int sz; + EncodingVersion encoding; + + EncapsDecoder* decoder; + + Encaps* previous; + }; + + // + // Optimization. The instance may not be deleted while a + // stack-allocated stream still holds it. + // + IceInternal::Instance* _instance; + + // + // The encoding version to use when there's no encapsulation to + // read from. This is for example used to read message headers. + // + EncodingVersion _encoding; + + Encaps* _currentEncaps; + + void initEncaps(); + + Encaps _preAllocatedEncaps; + +#ifndef ICE_CPP11_MAPPING + bool _collectObjects; +#endif + + bool _traceSlicing; + + size_t _classGraphDepthMax; + + void* _closure; + + bool _sliceValues; + + int _startSeq; + int _minSeqSize; + + ValueFactoryManagerPtr _valueFactoryManager; + LoggerPtr _logger; +#ifdef ICE_CPP11_MAPPING + std::function _compactIdResolver; +#else + CompactIdResolverPtr _compactIdResolver; +#endif + +#ifdef ICE_CPP11_MAPPING + std::vector> _deleters; +#endif + +}; + +} // End namespace Ice + +#endif diff --git a/Sources/IceCpp/include/Ice/Instance.h b/Sources/IceCpp/include/Ice/Instance.h new file mode 100644 index 0000000..1501671 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Instance.h @@ -0,0 +1,235 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INSTANCE_H +#define ICE_INSTANCE_H + +#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 + +namespace Ice +{ + +class CommunicatorI; + +} + +namespace IceInternal +{ + +class Timer; +typedef IceUtil::Handle TimerPtr; + +class MetricsAdminI; +ICE_DEFINE_PTR(MetricsAdminIPtr, MetricsAdminI); + +class RequestHandlerFactory; +typedef IceUtil::Handle RequestHandlerFactoryPtr; + +// +// Structure to track warnings for attempts to set socket buffer sizes +// +struct BufSizeWarnInfo +{ + // Whether send size warning has been emitted + bool sndWarn; + + // The send size for which the warning wwas emitted + int sndSize; + + // Whether receive size warning has been emitted + bool rcvWarn; + + // The receive size for which the warning wwas emitted + int rcvSize; +}; + +class Instance : public IceUtil::Shared, public IceUtil::Monitor +{ +public: + + bool destroyed() const; + const Ice::InitializationData& initializationData() const { return _initData; } + TraceLevelsPtr traceLevels() const; + DefaultsAndOverridesPtr defaultsAndOverrides() const; + RouterManagerPtr routerManager() const; + LocatorManagerPtr locatorManager() const; + ReferenceFactoryPtr referenceFactory() const; + RequestHandlerFactoryPtr requestHandlerFactory() const; + ProxyFactoryPtr proxyFactory() const; + OutgoingConnectionFactoryPtr outgoingConnectionFactory() const; + ObjectAdapterFactoryPtr objectAdapterFactory() const; + ProtocolSupport protocolSupport() const; + bool preferIPv6() const; + NetworkProxyPtr networkProxy() const; + ThreadPoolPtr clientThreadPool(); + ThreadPoolPtr serverThreadPool(); + EndpointHostResolverPtr endpointHostResolver(); + RetryQueuePtr retryQueue(); + IceUtil::TimerPtr timer(); + EndpointFactoryManagerPtr endpointFactoryManager() const; + DynamicLibraryListPtr dynamicLibraryList() const; + Ice::PluginManagerPtr pluginManager() const; + size_t messageSizeMax() const { return _messageSizeMax; } + size_t batchAutoFlushSize() const { return _batchAutoFlushSize; } + size_t classGraphDepthMax() const { return _classGraphDepthMax; } + bool collectObjects() const { return _collectObjects; } + Ice::ToStringMode toStringMode() const { return _toStringMode; } + bool acceptClassCycles() const { return _acceptClassCycles; } + const ACMConfig& clientACM() const; + const ACMConfig& serverACM() const; + + Ice::ObjectPrxPtr createAdmin(const Ice::ObjectAdapterPtr&, const Ice::Identity&); + Ice::ObjectPrxPtr getAdmin(); + void addAdminFacet(const Ice::ObjectPtr&, const std::string&); + Ice::ObjectPtr removeAdminFacet(const std::string&); + Ice::ObjectPtr findAdminFacet(const std::string&); + Ice::FacetMap findAllAdminFacets(); + + const Ice::ImplicitContextIPtr& getImplicitContext() const + { + return _implicitContext; + } + + void setDefaultLocator(const Ice::LocatorPrxPtr&); + void setDefaultRouter(const Ice::RouterPrxPtr&); + + void setLogger(const Ice::LoggerPtr&); +#ifdef ICE_CPP11_MAPPING + void setThreadHook(std::function, std::function); +#else + void setThreadHook(const Ice::ThreadNotificationPtr&); +#endif + + const Ice::StringConverterPtr& getStringConverter() const { return _stringConverter; } + const Ice::WstringConverterPtr& getWstringConverter() const { return _wstringConverter; } + + BufSizeWarnInfo getBufSizeWarn(Ice::Short type); + void setSndBufSizeWarn(Ice::Short type, int size); + void setRcvBufSizeWarn(Ice::Short type, int size); + + void addObjectFactory(const Ice::ObjectFactoryPtr&, const std::string&); + Ice::ObjectFactoryPtr findObjectFactory(const std::string&) const; + + typedef std::map ObjectFactoryMap; + +private: + + Instance(const Ice::CommunicatorPtr&, const Ice::InitializationData&); + virtual ~Instance(); + void finishSetup(int&, const char*[], const Ice::CommunicatorPtr&); + void destroy(); + friend class Ice::CommunicatorI; + + void updateConnectionObservers(); + void updateThreadObservers(); + friend class ObserverUpdaterI; + + void addAllAdminFacets(); + void setServerProcessProxy(const Ice::ObjectAdapterPtr&, const Ice::Identity&); + + BufSizeWarnInfo getBufSizeWarnInternal(Ice::Short type); + + enum State + { + StateActive, + StateDestroyInProgress, + StateDestroyed + }; + State _state; + Ice::InitializationData _initData; + const TraceLevelsPtr _traceLevels; // Immutable, not reset by destroy(). + const DefaultsAndOverridesPtr _defaultsAndOverrides; // Immutable, not reset by destroy(). + const size_t _messageSizeMax; // Immutable, not reset by destroy(). + const size_t _batchAutoFlushSize; // Immutable, not reset by destroy(). + const size_t _classGraphDepthMax; // Immutable, not reset by destroy(). + const bool _collectObjects; // Immutable, not reset by destroy(). + const Ice::ToStringMode _toStringMode; // Immutable, not reset by destroy() + const bool _acceptClassCycles; // Immutable, not reset by destroy() + ACMConfig _clientACM; + ACMConfig _serverACM; + RouterManagerPtr _routerManager; + LocatorManagerPtr _locatorManager; + ReferenceFactoryPtr _referenceFactory; + RequestHandlerFactoryPtr _requestHandlerFactory; + ProxyFactoryPtr _proxyFactory; + OutgoingConnectionFactoryPtr _outgoingConnectionFactory; + ObjectAdapterFactoryPtr _objectAdapterFactory; + ProtocolSupport _protocolSupport; + bool _preferIPv6; + NetworkProxyPtr _networkProxy; + ThreadPoolPtr _clientThreadPool; + ThreadPoolPtr _serverThreadPool; + EndpointHostResolverPtr _endpointHostResolver; + RetryQueuePtr _retryQueue; + TimerPtr _timer; + EndpointFactoryManagerPtr _endpointFactoryManager; + DynamicLibraryListPtr _dynamicLibraryList; + Ice::PluginManagerPtr _pluginManager; + const Ice::ImplicitContextIPtr _implicitContext; + Ice::StringConverterPtr _stringConverter; + Ice::WstringConverterPtr _wstringConverter; + bool _adminEnabled; + Ice::ObjectAdapterPtr _adminAdapter; + Ice::FacetMap _adminFacets; + Ice::Identity _adminIdentity; + std::set _adminFacetFilter; + IceInternal::MetricsAdminIPtr _metricsAdmin; + std::map _setBufSizeWarn; + IceUtil::Mutex _setBufSizeWarnMutex; + ObjectFactoryMap _objectFactoryMap; + mutable ObjectFactoryMap::iterator _objectFactoryMapHint; +}; + +class ProcessI : public Ice::Process +{ +public: + + ProcessI(const Ice::CommunicatorPtr&); + + virtual void shutdown(const Ice::Current&); +#ifdef ICE_CPP11_MAPPING + virtual void writeMessage(std::string, Ice::Int, const Ice::Current&); +#else + virtual void writeMessage(const std::string&, Ice::Int, const Ice::Current&); +#endif + +private: + + const Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/InstanceF.h b/Sources/IceCpp/include/Ice/InstanceF.h new file mode 100644 index 0000000..bf5a48f --- /dev/null +++ b/Sources/IceCpp/include/Ice/InstanceF.h @@ -0,0 +1,20 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INSTANCE_F_H +#define ICE_INSTANCE_F_H + +#include + +#include + +namespace IceInternal +{ + +class Instance; +ICE_API IceUtil::Shared* upCast(Instance*); +typedef IceInternal::Handle InstancePtr; +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Instrumentation.h b/Sources/IceCpp/include/Ice/Instrumentation.h new file mode 100644 index 0000000..e33880c --- /dev/null +++ b/Sources/IceCpp/include/Ice/Instrumentation.h @@ -0,0 +1,1203 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Instrumentation.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Instrumentation_h__ +#define __Ice_Instrumentation_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + + +namespace Instrumentation +{ + +class Observer; +class ThreadObserver; +class ConnectionObserver; +class DispatchObserver; +class ChildInvocationObserver; +class RemoteObserver; +class CollocatedObserver; +class InvocationObserver; +class ObserverUpdater; +class CommunicatorObserver; + +} + +} + +namespace Ice +{ + +namespace Instrumentation +{ + +/** + * The thread state enumeration keeps track of the different possible + * states of Ice threads. + */ +enum class ThreadState : unsigned char +{ + /** + * The thread is idle. + */ + ThreadStateIdle, + /** + * The thread is in use performing reads or writes for Ice + * connections. This state is only for threads from an Ice thread + * pool. + */ + ThreadStateInUseForIO, + /** + * The thread is calling user code (servant implementation, AMI + * callbacks). This state is only for threads from an Ice thread + * pool. + */ + ThreadStateInUseForUser, + /** + * The thread is performing other internal activities (DNS + * lookups, timer callbacks, etc). + */ + ThreadStateInUseForOther +}; + +/** + * The state of an Ice connection. + */ +enum class ConnectionState : unsigned char +{ + /** + * The connection is being validated. + */ + ConnectionStateValidating, + /** + * The connection is holding the reception of new messages. + */ + ConnectionStateHolding, + /** + * The connection is active and can send and receive messages. + */ + ConnectionStateActive, + /** + * The connection is being gracefully shutdown and waits for the + * peer to close its end of the connection. + */ + ConnectionStateClosing, + /** + * The connection is closed and waits for potential dispatch to be + * finished before being destroyed and detached from the observer. + */ + ConnectionStateClosed +}; + +} + +} + +namespace Ice +{ + +namespace Instrumentation +{ + +/** + * The object observer interface used by instrumented objects to + * notify the observer of their existence. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Observer(); + + /** + * This method is called when the instrumented object is created + * or when the observer is attached to an existing object. + */ + virtual void attach() = 0; + + /** + * This method is called when the instrumented object is destroyed + * and as a result the observer detached from the object. + */ + virtual void detach() = 0; + + /** + * Notification of a failure. + * @param exceptionName The name of the exception. + */ + virtual void failed(const ::std::string& exceptionName) = 0; +}; + +/** + * The thread observer interface to instrument Ice threads. This can + * be threads from the Ice thread pool or utility threads used by the + * Ice core. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ThreadObserver : public virtual ::Ice::Instrumentation::Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ThreadObserver(); + + /** + * Notification of thread state change. + * @param oldState The previous thread state. + * @param newState The new thread state. + */ + virtual void stateChanged(ThreadState oldState, ThreadState newState) = 0; +}; + +/** + * The connection observer interface to instrument Ice connections. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionObserver : public virtual ::Ice::Instrumentation::Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionObserver(); + + /** + * Notification of sent bytes over the connection. + * @param num The number of bytes sent. + */ + virtual void sentBytes(int num) = 0; + + /** + * Notification of received bytes over the connection. + * @param num The number of bytes received. + */ + virtual void receivedBytes(int num) = 0; +}; + +/** + * The dispatch observer to instrument servant dispatch. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) DispatchObserver : public virtual ::Ice::Instrumentation::Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~DispatchObserver(); + + /** + * Notification of a user exception. + */ + virtual void userException() = 0; + + /** + * Reply notification. + * @param size The size of the reply. + */ + virtual void reply(int size) = 0; +}; + +/** + * The child invocation observer to instrument remote or collocated + * invocations. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ChildInvocationObserver : public virtual ::Ice::Instrumentation::Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ChildInvocationObserver(); + + /** + * Reply notification. + * @param size The size of the reply. + */ + virtual void reply(int size) = 0; +}; + +/** + * The remote observer to instrument invocations that are sent over + * the wire. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RemoteObserver : public virtual ::Ice::Instrumentation::ChildInvocationObserver +{ +public: + + ICE_MEMBER(ICE_API) virtual ~RemoteObserver(); +}; + +/** + * The collocated observer to instrument invocations that are + * collocated. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CollocatedObserver : public virtual ::Ice::Instrumentation::ChildInvocationObserver +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CollocatedObserver(); +}; + +/** + * The invocation observer to instrument invocations on proxies. A + * proxy invocation can either result in a collocated or remote + * invocation. If it results in a remote invocation, a sub-observer is + * requested for the remote invocation. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InvocationObserver : public virtual ::Ice::Instrumentation::Observer +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InvocationObserver(); + + /** + * Notification of the invocation being retried. + */ + virtual void retried() = 0; + + /** + * Notification of a user exception. + */ + virtual void userException() = 0; + + /** + * Get a remote observer for this invocation. + * @param con The connection information. + * @param endpt The connection endpoint. + * @param requestId The ID of the invocation. + * @param size The size of the invocation. + * @return The observer to instrument the remote invocation. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::RemoteObserver> getRemoteObserver(const ::std::shared_ptr<::Ice::ConnectionInfo>& con, const ::std::shared_ptr<::Ice::Endpoint>& endpt, int requestId, int size) = 0; + + /** + * Get a collocated observer for this invocation. + * @param adapter The object adapter hosting the collocated Ice object. + * @param requestId The ID of the invocation. + * @param size The size of the invocation. + * @return The observer to instrument the collocated invocation. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::CollocatedObserver> getCollocatedObserver(const ::std::shared_ptr<::Ice::ObjectAdapter>& adapter, int requestId, int size) = 0; +}; + +/** + * The observer updater interface. This interface is implemented by + * the Ice run-time and an instance of this interface is provided by + * the Ice communicator on initialization to the + * {@link CommunicatorObserver} object set with the communicator + * initialization data. The Ice communicator calls + * {@link CommunicatorObserver#setObserverUpdater} to provide the observer + * updater. + * + * This interface can be used by add-ins implementing the + * {@link CommunicatorObserver} interface to update the observers of + * connections and threads. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObserverUpdater +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObserverUpdater(); + + /** + * Update connection observers associated with each of the Ice + * connection from the communicator and its object adapters. + * + * When called, this method goes through all the connections and + * for each connection {@link CommunicatorObserver#getConnectionObserver} + * is called. The implementation of getConnectionObserver has the + * possibility to return an updated observer if necessary. + */ + virtual void updateConnectionObservers() = 0; + + /** + * Update thread observers associated with each of the Ice thread + * from the communicator and its object adapters. + * + * When called, this method goes through all the threads and for + * each thread {@link CommunicatorObserver#getThreadObserver} is + * called. The implementation of getThreadObserver has the + * possibility to return an updated observer if necessary. + */ + virtual void updateThreadObservers() = 0; +}; + +/** + * The communicator observer interface used by the Ice run-time to + * obtain and update observers for its observable objects. This + * interface should be implemented by add-ins that wish to observe Ice + * objects in order to collect statistics. An instance of this + * interface can be provided to the Ice run-time through the Ice + * communicator initialization data. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CommunicatorObserver +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CommunicatorObserver(); + + /** + * This method should return an observer for the given endpoint + * information and connector. The Ice run-time calls this method + * for each connection establishment attempt. + * @param endpt The endpoint. + * @param connector The description of the connector. For IP + * transports, this is typically the IP address to connect to. + * @return The observer to instrument the connection establishment. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::Observer> getConnectionEstablishmentObserver(const ::std::shared_ptr<::Ice::Endpoint>& endpt, const ::std::string& connector) = 0; + + /** + * This method should return an observer for the given endpoint + * information. The Ice run-time calls this method to resolve an + * endpoint and obtain the list of connectors. + * + * For IP endpoints, this typically involves doing a DNS lookup to + * obtain the IP addresses associated with the DNS name. + * @param endpt The endpoint. + * @return The observer to instrument the endpoint lookup. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::Observer> getEndpointLookupObserver(const ::std::shared_ptr<::Ice::Endpoint>& endpt) = 0; + + /** + * This method should return a connection observer for the given + * connection. The Ice run-time calls this method for each new + * connection and for all the Ice communicator connections when + * {@link ObserverUpdater#updateConnectionObservers} is called. + * @param c The connection information. + * @param e The connection endpoint. + * @param s The state of the connection. + * @param o The old connection observer if one is already set or a + * null reference otherwise. + * @return The connection observer to instrument the connection. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::ConnectionObserver> getConnectionObserver(const ::std::shared_ptr<::Ice::ConnectionInfo>& c, const ::std::shared_ptr<::Ice::Endpoint>& e, ConnectionState s, const ::std::shared_ptr& o) = 0; + + /** + * This method should return a thread observer for the given + * thread. The Ice run-time calls this method for each new thread + * and for all the Ice communicator threads when + * {@link ObserverUpdater#updateThreadObservers} is called. + * @param parent The parent of the thread. + * @param id The ID of the thread to observe. + * @param s The state of the thread. + * @param o The old thread observer if one is already set or a + * null reference otherwise. + * @return The thread observer to instrument the thread. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::ThreadObserver> getThreadObserver(const ::std::string& parent, const ::std::string& id, ThreadState s, const ::std::shared_ptr& o) = 0; + + /** + * This method should return an invocation observer for the given + * invocation. The Ice run-time calls this method for each new + * invocation on a proxy. + * @param prx The proxy used for the invocation. + * @param operation The name of the invocation. + * @param ctx The context specified by the user. + * @return The invocation observer to instrument the invocation. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::InvocationObserver> getInvocationObserver(const ::std::shared_ptr<::Ice::ObjectPrx>& prx, const ::std::string& operation, const ::Ice::Context& ctx) = 0; + + /** + * This method should return a dispatch observer for the given + * dispatch. The Ice run-time calls this method each time it + * receives an incoming invocation to be dispatched for an Ice + * object. + * @param c The current object as provided to the Ice servant + * dispatching the invocation. + * @param size The size of the dispatch. + * @return The dispatch observer to instrument the dispatch. + */ + virtual ::std::shared_ptr<::Ice::Instrumentation::DispatchObserver> getDispatchObserver(const ::Ice::Current& c, int size) = 0; + + /** + * The Ice run-time calls this method when the communicator is + * initialized. The add-in implementing this interface can use + * this object to get the Ice run-time to re-obtain observers for + * observed objects. + * @param updater The observer updater object. + */ + virtual void setObserverUpdater(const ::std::shared_ptr& updater) = 0; +}; + +} + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +/// \cond INTERNAL +namespace Instrumentation +{ + +using ObserverPtr = ::std::shared_ptr; + +using ThreadObserverPtr = ::std::shared_ptr; + +using ConnectionObserverPtr = ::std::shared_ptr; + +using DispatchObserverPtr = ::std::shared_ptr; + +using ChildInvocationObserverPtr = ::std::shared_ptr; + +using RemoteObserverPtr = ::std::shared_ptr; + +using CollocatedObserverPtr = ::std::shared_ptr; + +using InvocationObserverPtr = ::std::shared_ptr; + +using ObserverUpdaterPtr = ::std::shared_ptr; + +using CommunicatorObserverPtr = ::std::shared_ptr; + +} +/// \endcond + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +namespace Instrumentation +{ + +class Observer; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(Observer*); +/// \endcond +typedef ::IceInternal::Handle< Observer> ObserverPtr; + +class ThreadObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(ThreadObserver*); +/// \endcond +typedef ::IceInternal::Handle< ThreadObserver> ThreadObserverPtr; + +class ConnectionObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(ConnectionObserver*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionObserver> ConnectionObserverPtr; + +class DispatchObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(DispatchObserver*); +/// \endcond +typedef ::IceInternal::Handle< DispatchObserver> DispatchObserverPtr; + +class ChildInvocationObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(ChildInvocationObserver*); +/// \endcond +typedef ::IceInternal::Handle< ChildInvocationObserver> ChildInvocationObserverPtr; + +class RemoteObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(RemoteObserver*); +/// \endcond +typedef ::IceInternal::Handle< RemoteObserver> RemoteObserverPtr; + +class CollocatedObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(CollocatedObserver*); +/// \endcond +typedef ::IceInternal::Handle< CollocatedObserver> CollocatedObserverPtr; + +class InvocationObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(InvocationObserver*); +/// \endcond +typedef ::IceInternal::Handle< InvocationObserver> InvocationObserverPtr; + +class ObserverUpdater; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(ObserverUpdater*); +/// \endcond +typedef ::IceInternal::Handle< ObserverUpdater> ObserverUpdaterPtr; + +class CommunicatorObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(CommunicatorObserver*); +/// \endcond +typedef ::IceInternal::Handle< CommunicatorObserver> CommunicatorObserverPtr; + +} + +} + +namespace Ice +{ + +namespace Instrumentation +{ + +/** + * The thread state enumeration keeps track of the different possible + * states of Ice threads. + */ +enum ThreadState +{ + /** + * The thread is idle. + */ + ThreadStateIdle, + /** + * The thread is in use performing reads or writes for Ice + * connections. This state is only for threads from an Ice thread + * pool. + */ + ThreadStateInUseForIO, + /** + * The thread is calling user code (servant implementation, AMI + * callbacks). This state is only for threads from an Ice thread + * pool. + */ + ThreadStateInUseForUser, + /** + * The thread is performing other internal activities (DNS + * lookups, timer callbacks, etc). + */ + ThreadStateInUseForOther +}; + +/** + * The state of an Ice connection. + */ +enum ConnectionState +{ + /** + * The connection is being validated. + */ + ConnectionStateValidating, + /** + * The connection is holding the reception of new messages. + */ + ConnectionStateHolding, + /** + * The connection is active and can send and receive messages. + */ + ConnectionStateActive, + /** + * The connection is being gracefully shutdown and waits for the + * peer to close its end of the connection. + */ + ConnectionStateClosing, + /** + * The connection is closed and waits for potential dispatch to be + * finished before being destroyed and detached from the observer. + */ + ConnectionStateClosed +}; + +} + +} + +namespace Ice +{ + +namespace Instrumentation +{ + +/** + * The object observer interface used by instrumented objects to + * notify the observer of their existence. + * \headerfile Ice/Ice.h + */ +class ICE_API Observer : public virtual ::Ice::LocalObject +{ +public: + + typedef ObserverPtr PointerType; + + virtual ~Observer(); + +#ifdef ICE_CPP11_COMPILER + Observer() = default; + Observer(const Observer&) = default; + Observer& operator=(const Observer&) = default; +#endif + + /** + * This method is called when the instrumented object is created + * or when the observer is attached to an existing object. + */ + virtual void attach() = 0; + + /** + * This method is called when the instrumented object is destroyed + * and as a result the observer detached from the object. + */ + virtual void detach() = 0; + + /** + * Notification of a failure. + * @param exceptionName The name of the exception. + */ + virtual void failed(const ::std::string& exceptionName) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Observer& lhs, const Observer& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Observer& lhs, const Observer& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The thread observer interface to instrument Ice threads. This can + * be threads from the Ice thread pool or utility threads used by the + * Ice core. + * \headerfile Ice/Ice.h + */ +class ICE_API ThreadObserver : virtual public Observer +{ +public: + + typedef ThreadObserverPtr PointerType; + + virtual ~ThreadObserver(); + +#ifdef ICE_CPP11_COMPILER + ThreadObserver() = default; + ThreadObserver(const ThreadObserver&) = default; + ThreadObserver& operator=(const ThreadObserver&) = default; +#endif + + /** + * Notification of thread state change. + * @param oldState The previous thread state. + * @param newState The new thread state. + */ + virtual void stateChanged(ThreadState oldState, ThreadState newState) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ThreadObserver& lhs, const ThreadObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ThreadObserver& lhs, const ThreadObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The connection observer interface to instrument Ice connections. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionObserver : virtual public Observer +{ +public: + + typedef ConnectionObserverPtr PointerType; + + virtual ~ConnectionObserver(); + +#ifdef ICE_CPP11_COMPILER + ConnectionObserver() = default; + ConnectionObserver(const ConnectionObserver&) = default; + ConnectionObserver& operator=(const ConnectionObserver&) = default; +#endif + + /** + * Notification of sent bytes over the connection. + * @param num The number of bytes sent. + */ + virtual void sentBytes(::Ice::Int num) = 0; + + /** + * Notification of received bytes over the connection. + * @param num The number of bytes received. + */ + virtual void receivedBytes(::Ice::Int num) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ConnectionObserver& lhs, const ConnectionObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ConnectionObserver& lhs, const ConnectionObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The dispatch observer to instrument servant dispatch. + * \headerfile Ice/Ice.h + */ +class ICE_API DispatchObserver : virtual public Observer +{ +public: + + typedef DispatchObserverPtr PointerType; + + virtual ~DispatchObserver(); + +#ifdef ICE_CPP11_COMPILER + DispatchObserver() = default; + DispatchObserver(const DispatchObserver&) = default; + DispatchObserver& operator=(const DispatchObserver&) = default; +#endif + + /** + * Notification of a user exception. + */ + virtual void userException() = 0; + + /** + * Reply notification. + * @param size The size of the reply. + */ + virtual void reply(::Ice::Int size) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const DispatchObserver& lhs, const DispatchObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const DispatchObserver& lhs, const DispatchObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The child invocation observer to instrument remote or collocated + * invocations. + * \headerfile Ice/Ice.h + */ +class ICE_API ChildInvocationObserver : virtual public Observer +{ +public: + + typedef ChildInvocationObserverPtr PointerType; + + virtual ~ChildInvocationObserver(); + +#ifdef ICE_CPP11_COMPILER + ChildInvocationObserver() = default; + ChildInvocationObserver(const ChildInvocationObserver&) = default; + ChildInvocationObserver& operator=(const ChildInvocationObserver&) = default; +#endif + + /** + * Reply notification. + * @param size The size of the reply. + */ + virtual void reply(::Ice::Int size) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ChildInvocationObserver& lhs, const ChildInvocationObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ChildInvocationObserver& lhs, const ChildInvocationObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The remote observer to instrument invocations that are sent over + * the wire. + * \headerfile Ice/Ice.h + */ +class ICE_API RemoteObserver : virtual public ChildInvocationObserver +{ +public: + + typedef RemoteObserverPtr PointerType; + + virtual ~RemoteObserver(); + +#ifdef ICE_CPP11_COMPILER + RemoteObserver() = default; + RemoteObserver(const RemoteObserver&) = default; + RemoteObserver& operator=(const RemoteObserver&) = default; +#endif +}; + +/// \cond INTERNAL +inline bool operator==(const RemoteObserver& lhs, const RemoteObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const RemoteObserver& lhs, const RemoteObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The collocated observer to instrument invocations that are + * collocated. + * \headerfile Ice/Ice.h + */ +class ICE_API CollocatedObserver : virtual public ChildInvocationObserver +{ +public: + + typedef CollocatedObserverPtr PointerType; + + virtual ~CollocatedObserver(); + +#ifdef ICE_CPP11_COMPILER + CollocatedObserver() = default; + CollocatedObserver(const CollocatedObserver&) = default; + CollocatedObserver& operator=(const CollocatedObserver&) = default; +#endif +}; + +/// \cond INTERNAL +inline bool operator==(const CollocatedObserver& lhs, const CollocatedObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const CollocatedObserver& lhs, const CollocatedObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The invocation observer to instrument invocations on proxies. A + * proxy invocation can either result in a collocated or remote + * invocation. If it results in a remote invocation, a sub-observer is + * requested for the remote invocation. + * \headerfile Ice/Ice.h + */ +class ICE_API InvocationObserver : virtual public Observer +{ +public: + + typedef InvocationObserverPtr PointerType; + + virtual ~InvocationObserver(); + +#ifdef ICE_CPP11_COMPILER + InvocationObserver() = default; + InvocationObserver(const InvocationObserver&) = default; + InvocationObserver& operator=(const InvocationObserver&) = default; +#endif + + /** + * Notification of the invocation being retried. + */ + virtual void retried() = 0; + + /** + * Notification of a user exception. + */ + virtual void userException() = 0; + + /** + * Get a remote observer for this invocation. + * @param con The connection information. + * @param endpt The connection endpoint. + * @param requestId The ID of the invocation. + * @param size The size of the invocation. + * @return The observer to instrument the remote invocation. + */ + virtual RemoteObserverPtr getRemoteObserver(const ::Ice::ConnectionInfoPtr& con, const ::Ice::EndpointPtr& endpt, ::Ice::Int requestId, ::Ice::Int size) = 0; + + /** + * Get a collocated observer for this invocation. + * @param adapter The object adapter hosting the collocated Ice object. + * @param requestId The ID of the invocation. + * @param size The size of the invocation. + * @return The observer to instrument the collocated invocation. + */ + virtual CollocatedObserverPtr getCollocatedObserver(const ::Ice::ObjectAdapterPtr& adapter, ::Ice::Int requestId, ::Ice::Int size) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const InvocationObserver& lhs, const InvocationObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const InvocationObserver& lhs, const InvocationObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The observer updater interface. This interface is implemented by + * the Ice run-time and an instance of this interface is provided by + * the Ice communicator on initialization to the + * {@link CommunicatorObserver} object set with the communicator + * initialization data. The Ice communicator calls + * {@link CommunicatorObserver#setObserverUpdater} to provide the observer + * updater. + * + * This interface can be used by add-ins implementing the + * {@link CommunicatorObserver} interface to update the observers of + * connections and threads. + * \headerfile Ice/Ice.h + */ +class ICE_API ObserverUpdater : public virtual ::Ice::LocalObject +{ +public: + + typedef ObserverUpdaterPtr PointerType; + + virtual ~ObserverUpdater(); + +#ifdef ICE_CPP11_COMPILER + ObserverUpdater() = default; + ObserverUpdater(const ObserverUpdater&) = default; + ObserverUpdater& operator=(const ObserverUpdater&) = default; +#endif + + /** + * Update connection observers associated with each of the Ice + * connection from the communicator and its object adapters. + * + * When called, this method goes through all the connections and + * for each connection {@link CommunicatorObserver#getConnectionObserver} + * is called. The implementation of getConnectionObserver has the + * possibility to return an updated observer if necessary. + */ + virtual void updateConnectionObservers() = 0; + + /** + * Update thread observers associated with each of the Ice thread + * from the communicator and its object adapters. + * + * When called, this method goes through all the threads and for + * each thread {@link CommunicatorObserver#getThreadObserver} is + * called. The implementation of getThreadObserver has the + * possibility to return an updated observer if necessary. + */ + virtual void updateThreadObservers() = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ObserverUpdater& lhs, const ObserverUpdater& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ObserverUpdater& lhs, const ObserverUpdater& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The communicator observer interface used by the Ice run-time to + * obtain and update observers for its observable objects. This + * interface should be implemented by add-ins that wish to observe Ice + * objects in order to collect statistics. An instance of this + * interface can be provided to the Ice run-time through the Ice + * communicator initialization data. + * \headerfile Ice/Ice.h + */ +class ICE_API CommunicatorObserver : public virtual ::Ice::LocalObject +{ +public: + + typedef CommunicatorObserverPtr PointerType; + + virtual ~CommunicatorObserver(); + +#ifdef ICE_CPP11_COMPILER + CommunicatorObserver() = default; + CommunicatorObserver(const CommunicatorObserver&) = default; + CommunicatorObserver& operator=(const CommunicatorObserver&) = default; +#endif + + /** + * This method should return an observer for the given endpoint + * information and connector. The Ice run-time calls this method + * for each connection establishment attempt. + * @param endpt The endpoint. + * @param connector The description of the connector. For IP + * transports, this is typically the IP address to connect to. + * @return The observer to instrument the connection establishment. + */ + virtual ObserverPtr getConnectionEstablishmentObserver(const ::Ice::EndpointPtr& endpt, const ::std::string& connector) = 0; + + /** + * This method should return an observer for the given endpoint + * information. The Ice run-time calls this method to resolve an + * endpoint and obtain the list of connectors. + * + * For IP endpoints, this typically involves doing a DNS lookup to + * obtain the IP addresses associated with the DNS name. + * @param endpt The endpoint. + * @return The observer to instrument the endpoint lookup. + */ + virtual ObserverPtr getEndpointLookupObserver(const ::Ice::EndpointPtr& endpt) = 0; + + /** + * This method should return a connection observer for the given + * connection. The Ice run-time calls this method for each new + * connection and for all the Ice communicator connections when + * {@link ObserverUpdater#updateConnectionObservers} is called. + * @param c The connection information. + * @param e The connection endpoint. + * @param s The state of the connection. + * @param o The old connection observer if one is already set or a + * null reference otherwise. + * @return The connection observer to instrument the connection. + */ + virtual ConnectionObserverPtr getConnectionObserver(const ::Ice::ConnectionInfoPtr& c, const ::Ice::EndpointPtr& e, ConnectionState s, const ConnectionObserverPtr& o) = 0; + + /** + * This method should return a thread observer for the given + * thread. The Ice run-time calls this method for each new thread + * and for all the Ice communicator threads when + * {@link ObserverUpdater#updateThreadObservers} is called. + * @param parent The parent of the thread. + * @param id The ID of the thread to observe. + * @param s The state of the thread. + * @param o The old thread observer if one is already set or a + * null reference otherwise. + * @return The thread observer to instrument the thread. + */ + virtual ThreadObserverPtr getThreadObserver(const ::std::string& parent, const ::std::string& id, ThreadState s, const ThreadObserverPtr& o) = 0; + + /** + * This method should return an invocation observer for the given + * invocation. The Ice run-time calls this method for each new + * invocation on a proxy. + * @param prx The proxy used for the invocation. + * @param operation The name of the invocation. + * @param ctx The context specified by the user. + * @return The invocation observer to instrument the invocation. + */ + virtual InvocationObserverPtr getInvocationObserver(const ::Ice::ObjectPrx& prx, const ::std::string& operation, const ::Ice::Context& ctx) = 0; + + /** + * This method should return a dispatch observer for the given + * dispatch. The Ice run-time calls this method each time it + * receives an incoming invocation to be dispatched for an Ice + * object. + * @param c The current object as provided to the Ice servant + * dispatching the invocation. + * @param size The size of the dispatch. + * @return The dispatch observer to instrument the dispatch. + */ + virtual DispatchObserverPtr getDispatchObserver(const ::Ice::Current& c, ::Ice::Int size) = 0; + + /** + * The Ice run-time calls this method when the communicator is + * initialized. The add-in implementing this interface can use + * this object to get the Ice run-time to re-obtain observers for + * observed objects. + * @param updater The observer updater object. + */ + virtual void setObserverUpdater(const ObserverUpdaterPtr& updater) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const CommunicatorObserver& lhs, const CommunicatorObserver& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const CommunicatorObserver& lhs, const CommunicatorObserver& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/InstrumentationF.h b/Sources/IceCpp/include/Ice/InstrumentationF.h new file mode 100644 index 0000000..7321b2a --- /dev/null +++ b/Sources/IceCpp/include/Ice/InstrumentationF.h @@ -0,0 +1,128 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `InstrumentationF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_InstrumentationF_h__ +#define __Ice_InstrumentationF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + + +namespace Instrumentation +{ + +class Observer; +class CommunicatorObserver; + +} + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +/// \cond INTERNAL +namespace Instrumentation +{ + +using ObserverPtr = ::std::shared_ptr; + +using CommunicatorObserverPtr = ::std::shared_ptr; + +} +/// \endcond + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +namespace Instrumentation +{ + +class Observer; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(Observer*); +/// \endcond +typedef ::IceInternal::Handle< Observer> ObserverPtr; + +class CommunicatorObserver; +/// \cond INTERNAL +ICE_API ::Ice::LocalObject* upCast(CommunicatorObserver*); +/// \endcond +typedef ::IceInternal::Handle< CommunicatorObserver> CommunicatorObserverPtr; + +} + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/InstrumentationI.h b/Sources/IceCpp/include/Ice/InstrumentationI.h new file mode 100644 index 0000000..da155ae --- /dev/null +++ b/Sources/IceCpp/include/Ice/InstrumentationI.h @@ -0,0 +1,256 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INSTRUMENTATION_I_H +#define ICE_INSTRUMENTATION_I_H + +#include +#include + +namespace IceInternal +{ + +template class ObserverWithDelegateT : public IceMX::ObserverT, public virtual O +{ +public: + + typedef O ObserverType; + typedef typename ICE_INTERNAL_HANDLE ObserverPtrType; + virtual void + attach() + { + IceMX::ObserverT::attach(); + if(_delegate) + { + _delegate->attach(); + } + } + + virtual void + detach() + { + IceMX::ObserverT::detach(); + if(_delegate) + { + _delegate->detach(); + } + } + + virtual void + failed(const std::string& exceptionName) + { + IceMX::ObserverT::failed(exceptionName); + if(_delegate) + { + _delegate->failed(exceptionName); + } + } + + ObserverPtrType + getDelegate() const + { + return _delegate; + } + + void + setDelegate(ObserverPtrType delegate) + { + _delegate = delegate; + } + + template ObserverPtrType + getObserverWithDelegate(const std::string& mapName, const IceMX::MetricsHelperT& helper, + const ObserverPtrType& del) + { + ICE_INTERNAL_HANDLE obsv = IceMX::ObserverT::template getObserver(mapName, + helper); + if(obsv) + { + obsv->setDelegate(del); + return obsv; + } + return del; + } + +protected: + + ObserverPtrType _delegate; +}; + +template class ObserverFactoryWithDelegateT : public IceMX::ObserverFactoryT +{ +public: + + ObserverFactoryWithDelegateT(const IceInternal::MetricsAdminIPtr& metrics, const std::string& name) : + IceMX::ObserverFactoryT(metrics, name) + { + } + + template ObserverPtrType + getObserverWithDelegate(const IceMX::MetricsHelperT& helper, const ObserverPtrType& del) + { + ICE_INTERNAL_HANDLE obsv = IceMX::ObserverFactoryT::getObserver(helper); + if(obsv) + { + obsv->setDelegate(del); + return obsv; + } + return del; + } + + template ObserverPtrType + getObserverWithDelegate(const IceMX::MetricsHelperT& helper, const ObserverPtrType& del, + const ObserverPtrType& old) + { + ICE_INTERNAL_HANDLE obsv = IceMX::ObserverFactoryT::getObserver(helper, old); + if(obsv) + { + obsv->setDelegate(del); + return obsv; + } + return del; + } +}; + +template +void addEndpointAttributes(typename Helper::Attributes& attrs) +{ + attrs.add("endpoint", &Helper::getEndpoint); + + attrs.add("endpointType", &Helper::getEndpointInfo, &Ice::EndpointInfo::type); + attrs.add("endpointIsDatagram", &Helper::getEndpointInfo, &Ice::EndpointInfo::datagram); + attrs.add("endpointIsSecure", &Helper::getEndpointInfo, &Ice::EndpointInfo::secure); + attrs.add("endpointTimeout", &Helper::getEndpointInfo, &Ice::EndpointInfo::timeout); + attrs.add("endpointCompress", &Helper::getEndpointInfo, &Ice::EndpointInfo::compress); + + attrs.add("endpointHost", &Helper::getEndpointInfo, &Ice::IPEndpointInfo::host); + attrs.add("endpointPort", &Helper::getEndpointInfo, &Ice::IPEndpointInfo::port); +} + +template +void addConnectionAttributes(typename Helper::Attributes& attrs) +{ + attrs.add("incoming", &Helper::getConnectionInfo, &Ice::ConnectionInfo::incoming); + attrs.add("adapterName", &Helper::getConnectionInfo, &Ice::ConnectionInfo::adapterName); + attrs.add("connectionId", &Helper::getConnectionInfo, &Ice::ConnectionInfo::connectionId); + + attrs.add("localHost", &Helper::getConnectionInfo, &Ice::IPConnectionInfo::localAddress); + attrs.add("localPort", &Helper::getConnectionInfo, &Ice::IPConnectionInfo::localPort); + attrs.add("remoteHost", &Helper::getConnectionInfo, &Ice::IPConnectionInfo::remoteAddress); + attrs.add("remotePort", &Helper::getConnectionInfo, &Ice::IPConnectionInfo::remotePort); + + attrs.add("mcastHost", &Helper::getConnectionInfo, &Ice::UDPConnectionInfo::mcastAddress); + attrs.add("mcastPort", &Helper::getConnectionInfo, &Ice::UDPConnectionInfo::mcastPort); + + addEndpointAttributes(attrs); +} + +class ConnectionObserverI : public ObserverWithDelegateT +{ +public: + + virtual void sentBytes(Ice::Int); + virtual void receivedBytes(Ice::Int); +}; + +class ThreadObserverI : public ObserverWithDelegateT +{ +public: + + virtual void stateChanged(Ice::Instrumentation::ThreadState, Ice::Instrumentation::ThreadState); +}; + +class DispatchObserverI : public ObserverWithDelegateT +{ +public: + + virtual void userException(); + + virtual void reply(Ice::Int); +}; + +class RemoteObserverI : public ObserverWithDelegateT +{ +public: + + virtual void reply(Ice::Int); +}; + +class CollocatedObserverI : public ObserverWithDelegateT +{ +public: + + virtual void reply(Ice::Int); +}; + +class InvocationObserverI : public ObserverWithDelegateT +{ +public: + + virtual void retried(); + + virtual void userException(); + + virtual Ice::Instrumentation::RemoteObserverPtr + getRemoteObserver(const Ice::ConnectionInfoPtr&, const Ice::EndpointPtr&, Ice::Int, Ice::Int); + + virtual Ice::Instrumentation::CollocatedObserverPtr + getCollocatedObserver(const Ice::ObjectAdapterPtr&, Ice::Int, Ice::Int); +}; + +typedef ObserverWithDelegateT ObserverI; + +class ICE_API CommunicatorObserverI : public Ice::Instrumentation::CommunicatorObserver +{ +public: + + CommunicatorObserverI(const Ice::InitializationData&); + + virtual void setObserverUpdater(const Ice::Instrumentation::ObserverUpdaterPtr&); + + virtual Ice::Instrumentation::ObserverPtr getConnectionEstablishmentObserver(const Ice::EndpointPtr&, + const std::string&); + + virtual Ice::Instrumentation::ObserverPtr getEndpointLookupObserver(const Ice::EndpointPtr&); + + virtual Ice::Instrumentation::ConnectionObserverPtr + getConnectionObserver(const Ice::ConnectionInfoPtr&, + const Ice::EndpointPtr&, + Ice::Instrumentation::ConnectionState, + const Ice::Instrumentation::ConnectionObserverPtr&); + + virtual Ice::Instrumentation::ThreadObserverPtr getThreadObserver(const std::string&, const std::string&, + Ice::Instrumentation::ThreadState, + const Ice::Instrumentation::ThreadObserverPtr&); + + virtual Ice::Instrumentation::InvocationObserverPtr getInvocationObserver(const Ice::ObjectPrxPtr&, + const std::string&, + const Ice::Context&); + + virtual Ice::Instrumentation::DispatchObserverPtr getDispatchObserver(const Ice::Current&, Ice::Int); + + const IceInternal::MetricsAdminIPtr& getFacet() const; + + void destroy(); + +private: + + IceInternal::MetricsAdminIPtr _metrics; + const Ice::Instrumentation::CommunicatorObserverPtr _delegate; + + ObserverFactoryWithDelegateT _connections; + ObserverFactoryWithDelegateT _dispatch; + ObserverFactoryWithDelegateT _invocations; + ObserverFactoryWithDelegateT _threads; + ObserverFactoryWithDelegateT _connects; + ObserverFactoryWithDelegateT _endpointLookups; +}; +ICE_DEFINE_PTR(CommunicatorObserverIPtr, CommunicatorObserverI); + +}; + +#endif diff --git a/Sources/IceCpp/include/Ice/InterfaceByValue.h b/Sources/IceCpp/include/Ice/InterfaceByValue.h new file mode 100644 index 0000000..56901a6 --- /dev/null +++ b/Sources/IceCpp/include/Ice/InterfaceByValue.h @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_INTERFACE_BY_VALUE_H +#define ICE_INTERFACE_BY_VALUE_H + +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING + +namespace Ice +{ + +/** + * Represents an instance of a Slice interface that was marshaled by value. + * \headerfile Ice/Ice.h + */ +template +class InterfaceByValue : public ValueHelper, Value> +{ +public: + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual std::string ice_id() const + { + return T::ice_staticId(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + static const std::string& ice_staticId() + { + return T::ice_staticId(); + } + + /** + * Returns an empty tuple. + * @return The empty tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/LocalException.h b/Sources/IceCpp/include/Ice/LocalException.h new file mode 100644 index 0000000..b2b0cfb --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocalException.h @@ -0,0 +1,7437 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocalException.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_LocalException_h__ +#define __Ice_LocalException_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * This exception is raised when a failure occurs during initialization. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InitializationException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InitializationException(); + + InitializationException(const InitializationException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InitializationException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + InitializationException(const char* file, int line, const ::std::string& reason) : LocalExceptionHelper(file, line), + reason(reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that a failure occurred while initializing + * a plug-in. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) PluginInitializationException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~PluginInitializationException(); + + PluginInitializationException(const PluginInitializationException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + PluginInitializationException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + PluginInitializationException(const char* file, int line, const ::std::string& reason) : LocalExceptionHelper(file, line), + reason(reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception is raised if a feature is requested that is not + * supported with collocation optimization. + * + * @deprecated This exception is no longer used by the Ice run time + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CollocationOptimizationException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CollocationOptimizationException(); + + CollocationOptimizationException(const CollocationOptimizationException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CollocationOptimizationException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * An attempt was made to register something more than once with + * the Ice run time. + * + * This exception is raised if an attempt is made to register a + * servant, servant locator, facet, value factory, plug-in, object + * adapter, object, or user exception factory more than once for the + * same ID. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) AlreadyRegisteredException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~AlreadyRegisteredException(); + + AlreadyRegisteredException(const AlreadyRegisteredException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + AlreadyRegisteredException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param kindOfObject The kind of object that could not be removed: "servant", "facet", "object", "default servant", "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + * @param id The ID (or name) of the object that is registered already. + */ + AlreadyRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id) : LocalExceptionHelper(file, line), + kindOfObject(kindOfObject), + id(id) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(kindOfObject, id); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The kind of object that could not be removed: "servant", "facet", + * "object", "default servant", "servant locator", "value factory", "plugin", + * "object adapter", "object adapter with router", "replica group". + */ + ::std::string kindOfObject; + /** + * The ID (or name) of the object that is registered already. + */ + ::std::string id; +}; + +/** + * An attempt was made to find or deregister something that is not + * registered with the Ice run time or Ice locator. + * + * This exception is raised if an attempt is made to remove a servant, + * servant locator, facet, value factory, plug-in, object adapter, + * object, or user exception factory that is not currently registered. + * + * It's also raised if the Ice locator can't find an object or object + * adapter when resolving an indirect proxy or when an object adapter + * is activated. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) NotRegisteredException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~NotRegisteredException(); + + NotRegisteredException(const NotRegisteredException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NotRegisteredException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param kindOfObject The kind of object that could not be removed: "servant", "facet", "object", "default servant", "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + * @param id The ID (or name) of the object that could not be removed. + */ + NotRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id) : LocalExceptionHelper(file, line), + kindOfObject(kindOfObject), + id(id) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(kindOfObject, id); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The kind of object that could not be removed: "servant", "facet", + * "object", "default servant", "servant locator", "value factory", "plugin", + * "object adapter", "object adapter with router", "replica group". + */ + ::std::string kindOfObject; + /** + * The ID (or name) of the object that could not be removed. + */ + ::std::string id; +}; + +/** + * The operation can only be invoked with a twoway request. + * + * This exception is raised if an attempt is made to invoke an + * operation with ice_oneway, ice_batchOneway, ice_datagram, + * or ice_batchDatagram and the operation has a return value, + * out-parameters, or an exception specification. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) TwowayOnlyException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~TwowayOnlyException(); + + TwowayOnlyException(const TwowayOnlyException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + TwowayOnlyException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param operation The name of the operation that was invoked. + */ + TwowayOnlyException(const char* file, int line, const ::std::string& operation) : LocalExceptionHelper(file, line), + operation(operation) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(operation); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The name of the operation that was invoked. + */ + ::std::string operation; +}; + +/** + * An attempt was made to clone a class that does not support + * cloning. + * + * This exception is raised if ice_clone is called on + * a class that is derived from an abstract Slice class (that is, + * a class containing operations), and the derived class does not + * provide an implementation of the ice_clone operation (C++ only). + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CloneNotImplementedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CloneNotImplementedException(); + + CloneNotImplementedException(const CloneNotImplementedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloneNotImplementedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if an operation call on a server raises an + * unknown exception. For example, for C++, this exception is raised + * if the server throws a C++ exception that is not directly or + * indirectly derived from Ice::LocalException or + * Ice::UserException. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownException(); + + UnknownException(const UnknownException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownException(const char* file, int line, const ::std::string& unknown) : LocalExceptionHelper(file, line), + unknown(unknown) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(unknown); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * This field is set to the textual representation of the unknown + * exception if available. + */ + ::std::string unknown; +}; + +/** + * This exception is raised if an operation call on a server raises a + * local exception. Because local exceptions are not transmitted by + * the Ice protocol, the client receives all local exceptions raised + * by the server as {@link UnknownLocalException}. The only exception to this + * rule are all exceptions derived from {@link RequestFailedException}, + * which are transmitted by the Ice protocol even though they are + * declared local. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownLocalException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownLocalException(); + + UnknownLocalException(const UnknownLocalException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownLocalException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownLocalException(const char* file, int line, const ::std::string& unknown) : + LocalExceptionHelper(file, line, unknown) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(unknown); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * An operation raised an incorrect user exception. + * + * This exception is raised if an operation raises a + * user exception that is not declared in the exception's + * throws clause. Such undeclared exceptions are + * not transmitted from the server to the client by the Ice + * protocol, but instead the client just gets an + * {@link UnknownUserException}. This is necessary in order to not violate + * the contract established by an operation's signature: Only local + * exceptions and user exceptions declared in the + * throws clause can be raised. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownUserException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownUserException(); + + UnknownUserException(const UnknownUserException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownUserException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownUserException(const char* file, int line, const ::std::string& unknown) : + LocalExceptionHelper(file, line, unknown) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(unknown); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if the Ice library version does not match + * the version in the Ice header files. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) VersionMismatchException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~VersionMismatchException(); + + VersionMismatchException(const VersionMismatchException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + VersionMismatchException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if the {@link Communicator} has been destroyed. + * @see Communicator#destroy + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CommunicatorDestroyedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CommunicatorDestroyedException(); + + CommunicatorDestroyedException(const CommunicatorDestroyedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CommunicatorDestroyedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if an attempt is made to use a deactivated + * {@link ObjectAdapter}. + * @see ObjectAdapter#deactivate + * @see Communicator#shutdown + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectAdapterDeactivatedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectAdapterDeactivatedException(); + + ObjectAdapterDeactivatedException(const ObjectAdapterDeactivatedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectAdapterDeactivatedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param name Name of the adapter. + */ + ObjectAdapterDeactivatedException(const char* file, int line, const ::std::string& name) : LocalExceptionHelper(file, line), + name(name) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(name); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Name of the adapter. + */ + ::std::string name; +}; + +/** + * This exception is raised if an {@link ObjectAdapter} cannot be activated. + * + * This happens if the {@link Locator} detects another active {@link ObjectAdapter} with + * the same adapter id. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectAdapterIdInUseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectAdapterIdInUseException(); + + ObjectAdapterIdInUseException(const ObjectAdapterIdInUseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectAdapterIdInUseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id Adapter ID. + */ + ObjectAdapterIdInUseException(const char* file, int line, const ::std::string& id) : LocalExceptionHelper(file, line), + id(id) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Adapter ID. + */ + ::std::string id; +}; + +/** + * This exception is raised if no suitable endpoint is available. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) NoEndpointException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~NoEndpointException(); + + NoEndpointException(const NoEndpointException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NoEndpointException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param proxy The stringified proxy for which no suitable endpoint is available. + */ + NoEndpointException(const char* file, int line, const ::std::string& proxy) : LocalExceptionHelper(file, line), + proxy(proxy) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(proxy); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The stringified proxy for which no suitable endpoint is + * available. + */ + ::std::string proxy; +}; + +/** + * This exception is raised if there was an error while parsing an + * endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) EndpointParseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~EndpointParseException(); + + EndpointParseException(const EndpointParseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EndpointParseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + EndpointParseException(const char* file, int line, const ::std::string& str) : LocalExceptionHelper(file, line), + str(str) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(str); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing an + * endpoint selection type. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) EndpointSelectionTypeParseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~EndpointSelectionTypeParseException(); + + EndpointSelectionTypeParseException(const EndpointSelectionTypeParseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EndpointSelectionTypeParseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + EndpointSelectionTypeParseException(const char* file, int line, const ::std::string& str) : LocalExceptionHelper(file, line), + str(str) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(str); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * version. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) VersionParseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~VersionParseException(); + + VersionParseException(const VersionParseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + VersionParseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + VersionParseException(const char* file, int line, const ::std::string& str) : LocalExceptionHelper(file, line), + str(str) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(str); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * stringified identity. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IdentityParseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IdentityParseException(); + + IdentityParseException(const IdentityParseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IdentityParseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + IdentityParseException(const char* file, int line, const ::std::string& str) : LocalExceptionHelper(file, line), + str(str) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(str); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * stringified proxy. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ProxyParseException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ProxyParseException(); + + ProxyParseException(const ProxyParseException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProxyParseException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + ProxyParseException(const char* file, int line, const ::std::string& str) : LocalExceptionHelper(file, line), + str(str) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(str); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if an illegal identity is encountered. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IllegalIdentityException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IllegalIdentityException(); + + IllegalIdentityException(const IllegalIdentityException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalIdentityException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The illegal identity. + */ + IllegalIdentityException(const char* file, int line, const Identity& id) : LocalExceptionHelper(file, line), + id(id) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The illegal identity. + */ + ::Ice::Identity id; +}; + +/** + * This exception is raised to reject an illegal servant (typically + * a null servant) + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IllegalServantException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IllegalServantException(); + + IllegalServantException(const IllegalServantException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalServantException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason Describes why this servant is illegal. + */ + IllegalServantException(const char* file, int line, const ::std::string& reason) : LocalExceptionHelper(file, line), + reason(reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * Describes why this servant is illegal. + */ + ::std::string reason; +}; + +/** + * This exception is raised if a request failed. This exception, and + * all exceptions derived from {@link RequestFailedException}, are + * transmitted by the Ice protocol, even though they are declared + * local. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RequestFailedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~RequestFailedException(); + + RequestFailedException(const RequestFailedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + RequestFailedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + RequestFailedException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : LocalExceptionHelper(file, line), + id(id), + facet(facet), + operation(operation) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, facet, operation); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The identity of the Ice Object to which the request was sent. + */ + ::Ice::Identity id; + /** + * The facet to which the request was sent. + */ + ::std::string facet; + /** + * The operation name of the request. + */ + ::std::string operation; +}; + +/** + * This exception is raised if an object does not exist on the server, + * that is, if no facets with the given identity exist. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectNotExistException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectNotExistException(); + + ObjectNotExistException(const ObjectNotExistException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectNotExistException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + ObjectNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + LocalExceptionHelper(file, line, id, facet, operation) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, facet, operation); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if no facet with the given name exists, + * but at least one facet with the given identity exists. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) FacetNotExistException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~FacetNotExistException(); + + FacetNotExistException(const FacetNotExistException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FacetNotExistException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + FacetNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + LocalExceptionHelper(file, line, id, facet, operation) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, facet, operation); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if an operation for a given object does + * not exist on the server. Typically this is caused by either the + * client or the server using an outdated Slice specification. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) OperationNotExistException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~OperationNotExistException(); + + OperationNotExistException(const OperationNotExistException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + OperationNotExistException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + OperationNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation) : + LocalExceptionHelper(file, line, id, facet, operation) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, facet, operation); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if a system error occurred in the server + * or client process. There are many possible causes for such a system + * exception. For details on the cause, {@link SyscallException#error} + * should be inspected. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) SyscallException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~SyscallException(); + + SyscallException(const SyscallException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SyscallException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + SyscallException(const char* file, int line, int error) : LocalExceptionHelper(file, line), + error(error) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The error number describing the system exception. For C++ and + * Unix, this is equivalent to errno. For C++ + * and Windows, this is the value returned by + * GetLastError() or + * WSAGetLastError(). + */ + int error = 0; +}; + +/** + * This exception indicates socket errors. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) SocketException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~SocketException(); + + SocketException(const SocketException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SocketException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + SocketException(const char* file, int line, int error) : + LocalExceptionHelper(file, line, error) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates CFNetwork errors. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CFNetworkException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CFNetworkException(); + + CFNetworkException(const CFNetworkException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CFNetworkException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + * @param domain The domain of the error. + */ + CFNetworkException(const char* file, int line, int error, const ::std::string& domain) : + LocalExceptionHelper(file, line, error), + domain(domain) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error, domain); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The domain of the error. + */ + ::std::string domain; +}; + +/** + * This exception indicates file errors. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) FileException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~FileException(); + + FileException(const FileException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FileException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + * @param path The path of the file responsible for the error. + */ + FileException(const char* file, int line, int error, const ::std::string& path) : + LocalExceptionHelper(file, line, error), + path(path) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error, path); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The path of the file responsible for the error. + */ + ::std::string path; +}; + +/** + * This exception indicates connection failures. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectFailedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectFailedException(); + + ConnectFailedException(const ConnectFailedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectFailedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectFailedException(const char* file, int line, int error) : + LocalExceptionHelper(file, line, error) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a connection failure for which + * the server host actively refuses a connection. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionRefusedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionRefusedException(); + + ConnectionRefusedException(const ConnectionRefusedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionRefusedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectionRefusedException(const char* file, int line, int error) : + LocalExceptionHelper(file, line, error) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a lost connection. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionLostException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionLostException(); + + ConnectionLostException(const ConnectionLostException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionLostException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectionLostException(const char* file, int line, int error) : + LocalExceptionHelper(file, line, error) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a DNS problem. For details on the cause, + * {@link DNSException#error} should be inspected. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) DNSException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~DNSException(); + + DNSException(const DNSException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + DNSException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the DNS problem. + * @param host The host name that could not be resolved. + */ + DNSException(const char* file, int line, int error, const ::std::string& host) : LocalExceptionHelper(file, line), + error(error), + host(host) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(error, host); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The error number describing the DNS problem. For C++ and Unix, + * this is equivalent to h_errno. For C++ and + * Windows, this is the value returned by + * WSAGetLastError(). + */ + int error = 0; + /** + * The host name that could not be resolved. + */ + ::std::string host; +}; + +/** + * This exception indicates a request was interrupted. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) OperationInterruptedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~OperationInterruptedException(); + + OperationInterruptedException(const OperationInterruptedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + OperationInterruptedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) TimeoutException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~TimeoutException(); + + TimeoutException(const TimeoutException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + TimeoutException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a connection establishment timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectTimeoutException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectTimeoutException(); + + ConnectTimeoutException(const ConnectTimeoutException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectTimeoutException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a connection closure timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CloseTimeoutException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CloseTimeoutException(); + + CloseTimeoutException(const CloseTimeoutException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloseTimeoutException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that a connection has been shut down because it has been + * idle for some time. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionTimeoutException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionTimeoutException(); + + ConnectionTimeoutException(const ConnectionTimeoutException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionTimeoutException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that an invocation failed because it timed + * out. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InvocationTimeoutException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InvocationTimeoutException(); + + InvocationTimeoutException(const InvocationTimeoutException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InvocationTimeoutException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that an asynchronous invocation failed + * because it was canceled explicitly by the user. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InvocationCanceledException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InvocationCanceledException(); + + InvocationCanceledException(const InvocationCanceledException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InvocationCanceledException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * A generic exception base for all kinds of protocol error + * conditions. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ProtocolException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ProtocolException(); + + ProtocolException(const ProtocolException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProtocolException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ProtocolException(const char* file, int line, const ::std::string& reason) : LocalExceptionHelper(file, line), + reason(reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that a message did not start with the expected + * magic number ('I', 'c', 'e', 'P'). + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) BadMagicException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~BadMagicException(); + + BadMagicException(const BadMagicException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + BadMagicException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param badMagic A sequence containing the first four bytes of the incorrect message. + */ + BadMagicException(const char* file, int line, const ::std::string& reason, const ByteSeq& badMagic) : + LocalExceptionHelper(file, line, reason), + badMagic(badMagic) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason, badMagic); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * A sequence containing the first four bytes of the incorrect message. + */ + ::Ice::ByteSeq badMagic; +}; + +/** + * This exception indicates an unsupported protocol version. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnsupportedProtocolException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnsupportedProtocolException(); + + UnsupportedProtocolException(const UnsupportedProtocolException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnsupportedProtocolException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param bad The version of the unsupported protocol. + * @param supported The version of the protocol that is supported. + */ + UnsupportedProtocolException(const char* file, int line, const ::std::string& reason, const ProtocolVersion& bad, const ProtocolVersion& supported) : + LocalExceptionHelper(file, line, reason), + bad(bad), + supported(supported) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason, bad, supported); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The version of the unsupported protocol. + */ + ::Ice::ProtocolVersion bad; + /** + * The version of the protocol that is supported. + */ + ::Ice::ProtocolVersion supported; +}; + +/** + * This exception indicates an unsupported data encoding version. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnsupportedEncodingException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnsupportedEncodingException(); + + UnsupportedEncodingException(const UnsupportedEncodingException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnsupportedEncodingException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param bad The version of the unsupported encoding. + * @param supported The version of the encoding that is supported. + */ + UnsupportedEncodingException(const char* file, int line, const ::std::string& reason, const EncodingVersion& bad, const EncodingVersion& supported) : + LocalExceptionHelper(file, line, reason), + bad(bad), + supported(supported) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason, bad, supported); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The version of the unsupported encoding. + */ + ::Ice::EncodingVersion bad; + /** + * The version of the encoding that is supported. + */ + ::Ice::EncodingVersion supported; +}; + +/** + * This exception indicates that an unknown protocol message has been received. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownMessageException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownMessageException(); + + UnknownMessageException(const UnknownMessageException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownMessageException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownMessageException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if a message is received over a connection + * that is not yet validated. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionNotValidatedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionNotValidatedException(); + + ConnectionNotValidatedException(const ConnectionNotValidatedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionNotValidatedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ConnectionNotValidatedException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that a response for an unknown request ID has been + * received. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownRequestIdException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownRequestIdException(); + + UnknownRequestIdException(const UnknownRequestIdException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownRequestIdException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownRequestIdException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that an unknown reply status has been received. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownReplyStatusException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownReplyStatusException(); + + UnknownReplyStatusException(const UnknownReplyStatusException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownReplyStatusException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownReplyStatusException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates that the connection has been gracefully shut down by the + * server. The operation call that caused this exception has not been + * executed by the server. In most cases you will not get this + * exception, because the client will automatically retry the + * operation call in case the server shut down the connection. However, + * if upon retry the server shuts down the connection again, and the + * retry limit has been reached, then this exception is propagated to + * the application code. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CloseConnectionException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CloseConnectionException(); + + CloseConnectionException(const CloseConnectionException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloseConnectionException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + CloseConnectionException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised by an operation call if the application + * closes the connection locally using {@link Connection#close}. + * @see Connection#close + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionManuallyClosedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionManuallyClosedException(); + + ConnectionManuallyClosedException(const ConnectionManuallyClosedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionManuallyClosedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param graceful True if the connection was closed gracefully, false otherwise. + */ + ConnectionManuallyClosedException(const char* file, int line, bool graceful) : LocalExceptionHelper(file, line), + graceful(graceful) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(graceful); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * True if the connection was closed gracefully, false otherwise. + */ + bool graceful; +}; + +/** + * This exception indicates that a message size is less + * than the minimum required size. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) IllegalMessageSizeException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~IllegalMessageSizeException(); + + IllegalMessageSizeException(const IllegalMessageSizeException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalMessageSizeException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + IllegalMessageSizeException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a problem with compressing or uncompressing data. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CompressionException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CompressionException(); + + CompressionException(const CompressionException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CompressionException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + CompressionException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * A datagram exceeds the configured size. + * + * This exception is raised if a datagram exceeds the configured send or receive buffer + * size, or exceeds the maximum payload size of a UDP packet (65507 bytes). + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) DatagramLimitException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~DatagramLimitException(); + + DatagramLimitException(const DatagramLimitException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + DatagramLimitException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + DatagramLimitException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised for errors during marshaling or unmarshaling data. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) MarshalException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~MarshalException(); + + MarshalException(const MarshalException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + MarshalException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + MarshalException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if inconsistent data is received while unmarshaling a proxy. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ProxyUnmarshalException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ProxyUnmarshalException(); + + ProxyUnmarshalException(const ProxyUnmarshalException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProxyUnmarshalException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ProxyUnmarshalException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if an out-of-bounds condition occurs during unmarshaling. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnmarshalOutOfBoundsException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnmarshalOutOfBoundsException(); + + UnmarshalOutOfBoundsException(const UnmarshalOutOfBoundsException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnmarshalOutOfBoundsException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnmarshalOutOfBoundsException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if no suitable value factory was found during + * unmarshaling of a Slice class instance. + * @see ValueFactory + * @see Communicator#getValueFactoryManager + * @see ValueFactoryManager#add + * @see ValueFactoryManager#find + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) NoValueFactoryException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~NoValueFactoryException(); + + NoValueFactoryException(const NoValueFactoryException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NoValueFactoryException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param type The Slice type ID of the class instance for which no no factory could be found. + */ + NoValueFactoryException(const char* file, int line, const ::std::string& reason, const ::std::string& type) : + LocalExceptionHelper(file, line, reason), + type(type) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason, type); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The Slice type ID of the class instance for which no + * no factory could be found. + */ + ::std::string type; +}; + +/** + * This exception is raised if the type of an unmarshaled Slice class instance does + * not match its expected type. + * This can happen if client and server are compiled with mismatched Slice + * definitions or if a class of the wrong type is passed as a parameter + * or return value using dynamic invocation. This exception can also be + * raised if IceStorm is used to send Slice class instances and + * an operation is subscribed to the wrong topic. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnexpectedObjectException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnexpectedObjectException(); + + UnexpectedObjectException(const UnexpectedObjectException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnexpectedObjectException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param type The Slice type ID of the class instance that was unmarshaled. + * @param expectedType The Slice type ID that was expected by the receiving operation. + */ + UnexpectedObjectException(const char* file, int line, const ::std::string& reason, const ::std::string& type, const ::std::string& expectedType) : + LocalExceptionHelper(file, line, reason), + type(type), + expectedType(expectedType) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason, type, expectedType); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The Slice type ID of the class instance that was unmarshaled. + */ + ::std::string type; + /** + * The Slice type ID that was expected by the receiving operation. + */ + ::std::string expectedType; +}; + +/** + * This exception is raised when Ice receives a request or reply + * message whose size exceeds the limit specified by the + * Ice.MessageSizeMax property. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) MemoryLimitException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~MemoryLimitException(); + + MemoryLimitException(const MemoryLimitException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + MemoryLimitException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + MemoryLimitException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised when a string conversion to or from UTF-8 + * fails during marshaling or unmarshaling. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) StringConversionException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~StringConversionException(); + + StringConversionException(const StringConversionException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + StringConversionException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + StringConversionException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception indicates a malformed data encapsulation. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) EncapsulationException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~EncapsulationException(); + + EncapsulationException(const EncapsulationException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EncapsulationException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + EncapsulationException(const char* file, int line, const ::std::string& reason) : + LocalExceptionHelper(file, line, reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * This exception is raised if an unsupported feature is used. The + * unsupported feature string contains the name of the unsupported + * feature + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) FeatureNotSupportedException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~FeatureNotSupportedException(); + + FeatureNotSupportedException(const FeatureNotSupportedException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FeatureNotSupportedException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unsupportedFeature The name of the unsupported feature. + */ + FeatureNotSupportedException(const char* file, int line, const ::std::string& unsupportedFeature) : LocalExceptionHelper(file, line), + unsupportedFeature(unsupportedFeature) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(unsupportedFeature); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The name of the unsupported feature. + */ + ::std::string unsupportedFeature; +}; + +/** + * This exception indicates a failure in a security subsystem, + * such as the IceSSL plug-in. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) SecurityException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~SecurityException(); + + SecurityException(const SecurityException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SecurityException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + SecurityException(const char* file, int line, const ::std::string& reason) : LocalExceptionHelper(file, line), + reason(reason) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(reason); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that an attempt has been made to + * change the connection properties of a fixed proxy. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) FixedProxyException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~FixedProxyException(); + + FixedProxyException(const FixedProxyException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FixedProxyException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +/** + * Indicates that the response to a request has already been sent; + * re-dispatching such a request is not possible. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ResponseSentException : public LocalExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ResponseSentException(); + + ResponseSentException(const ResponseSentException&) = default; + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ResponseSentException(const char* file, int line) : LocalExceptionHelper(file, line) + { + } + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + ICE_MEMBER(ICE_API) virtual void ice_print(::std::ostream& stream) const override; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +/** + * This exception is raised when a failure occurs during initialization. + * \headerfile Ice/Ice.h + */ +class ICE_API InitializationException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InitializationException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + InitializationException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + InitializationException(const InitializationException&) = default; + virtual ~InitializationException(); +#else + virtual ~InitializationException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual InitializationException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that a failure occurred while initializing + * a plug-in. + * \headerfile Ice/Ice.h + */ +class ICE_API PluginInitializationException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + PluginInitializationException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + PluginInitializationException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + PluginInitializationException(const PluginInitializationException&) = default; + virtual ~PluginInitializationException(); +#else + virtual ~PluginInitializationException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual PluginInitializationException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception is raised if a feature is requested that is not + * supported with collocation optimization. + * + * @deprecated This exception is no longer used by the Ice run time + * \headerfile Ice/Ice.h + */ +class ICE_API CollocationOptimizationException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CollocationOptimizationException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + CollocationOptimizationException(const CollocationOptimizationException&) = default; + virtual ~CollocationOptimizationException(); +#else + virtual ~CollocationOptimizationException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CollocationOptimizationException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * An attempt was made to register something more than once with + * the Ice run time. + * + * This exception is raised if an attempt is made to register a + * servant, servant locator, facet, value factory, plug-in, object + * adapter, object, or user exception factory more than once for the + * same ID. + * \headerfile Ice/Ice.h + */ +class ICE_API AlreadyRegisteredException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + AlreadyRegisteredException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param kindOfObject The kind of object that could not be removed: "servant", "facet", "object", "default servant", "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + * @param id The ID (or name) of the object that is registered already. + */ + AlreadyRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id); + +#ifdef ICE_CPP11_COMPILER + AlreadyRegisteredException(const AlreadyRegisteredException&) = default; + virtual ~AlreadyRegisteredException(); +#else + virtual ~AlreadyRegisteredException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual AlreadyRegisteredException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The kind of object that could not be removed: "servant", "facet", + * "object", "default servant", "servant locator", "value factory", "plugin", + * "object adapter", "object adapter with router", "replica group". + */ + ::std::string kindOfObject; + /** + * The ID (or name) of the object that is registered already. + */ + ::std::string id; +}; + +/** + * An attempt was made to find or deregister something that is not + * registered with the Ice run time or Ice locator. + * + * This exception is raised if an attempt is made to remove a servant, + * servant locator, facet, value factory, plug-in, object adapter, + * object, or user exception factory that is not currently registered. + * + * It's also raised if the Ice locator can't find an object or object + * adapter when resolving an indirect proxy or when an object adapter + * is activated. + * \headerfile Ice/Ice.h + */ +class ICE_API NotRegisteredException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NotRegisteredException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param kindOfObject The kind of object that could not be removed: "servant", "facet", "object", "default servant", "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + * @param id The ID (or name) of the object that could not be removed. + */ + NotRegisteredException(const char* file, int line, const ::std::string& kindOfObject, const ::std::string& id); + +#ifdef ICE_CPP11_COMPILER + NotRegisteredException(const NotRegisteredException&) = default; + virtual ~NotRegisteredException(); +#else + virtual ~NotRegisteredException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual NotRegisteredException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The kind of object that could not be removed: "servant", "facet", + * "object", "default servant", "servant locator", "value factory", "plugin", + * "object adapter", "object adapter with router", "replica group". + */ + ::std::string kindOfObject; + /** + * The ID (or name) of the object that could not be removed. + */ + ::std::string id; +}; + +/** + * The operation can only be invoked with a twoway request. + * + * This exception is raised if an attempt is made to invoke an + * operation with ice_oneway, ice_batchOneway, ice_datagram, + * or ice_batchDatagram and the operation has a return value, + * out-parameters, or an exception specification. + * \headerfile Ice/Ice.h + */ +class ICE_API TwowayOnlyException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + TwowayOnlyException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param operation The name of the operation that was invoked. + */ + TwowayOnlyException(const char* file, int line, const ::std::string& operation); + +#ifdef ICE_CPP11_COMPILER + TwowayOnlyException(const TwowayOnlyException&) = default; + virtual ~TwowayOnlyException(); +#else + virtual ~TwowayOnlyException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual TwowayOnlyException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The name of the operation that was invoked. + */ + ::std::string operation; +}; + +/** + * An attempt was made to clone a class that does not support + * cloning. + * + * This exception is raised if ice_clone is called on + * a class that is derived from an abstract Slice class (that is, + * a class containing operations), and the derived class does not + * provide an implementation of the ice_clone operation (C++ only). + * \headerfile Ice/Ice.h + */ +class ICE_API CloneNotImplementedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloneNotImplementedException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + CloneNotImplementedException(const CloneNotImplementedException&) = default; + virtual ~CloneNotImplementedException(); +#else + virtual ~CloneNotImplementedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CloneNotImplementedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if an operation call on a server raises an + * unknown exception. For example, for C++, this exception is raised + * if the server throws a C++ exception that is not directly or + * indirectly derived from Ice::LocalException or + * Ice::UserException. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownException(const char* file, int line, const ::std::string& unknown); + +#ifdef ICE_CPP11_COMPILER + UnknownException(const UnknownException&) = default; + virtual ~UnknownException(); +#else + virtual ~UnknownException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * This field is set to the textual representation of the unknown + * exception if available. + */ + ::std::string unknown; +}; + +/** + * This exception is raised if an operation call on a server raises a + * local exception. Because local exceptions are not transmitted by + * the Ice protocol, the client receives all local exceptions raised + * by the server as {@link UnknownLocalException}. The only exception to this + * rule are all exceptions derived from {@link RequestFailedException}, + * which are transmitted by the Ice protocol even though they are + * declared local. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownLocalException : public UnknownException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownLocalException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownLocalException(const char* file, int line, const ::std::string& unknown); + +#ifdef ICE_CPP11_COMPILER + UnknownLocalException(const UnknownLocalException&) = default; + virtual ~UnknownLocalException(); +#else + virtual ~UnknownLocalException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownLocalException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * An operation raised an incorrect user exception. + * + * This exception is raised if an operation raises a + * user exception that is not declared in the exception's + * throws clause. Such undeclared exceptions are + * not transmitted from the server to the client by the Ice + * protocol, but instead the client just gets an + * {@link UnknownUserException}. This is necessary in order to not violate + * the contract established by an operation's signature: Only local + * exceptions and user exceptions declared in the + * throws clause can be raised. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownUserException : public UnknownException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownUserException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unknown This field is set to the textual representation of the unknown exception if available. + */ + UnknownUserException(const char* file, int line, const ::std::string& unknown); + +#ifdef ICE_CPP11_COMPILER + UnknownUserException(const UnknownUserException&) = default; + virtual ~UnknownUserException(); +#else + virtual ~UnknownUserException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownUserException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if the Ice library version does not match + * the version in the Ice header files. + * \headerfile Ice/Ice.h + */ +class ICE_API VersionMismatchException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + VersionMismatchException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + VersionMismatchException(const VersionMismatchException&) = default; + virtual ~VersionMismatchException(); +#else + virtual ~VersionMismatchException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual VersionMismatchException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if the {@link Communicator} has been destroyed. + * @see Communicator#destroy + * \headerfile Ice/Ice.h + */ +class ICE_API CommunicatorDestroyedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CommunicatorDestroyedException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + CommunicatorDestroyedException(const CommunicatorDestroyedException&) = default; + virtual ~CommunicatorDestroyedException(); +#else + virtual ~CommunicatorDestroyedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CommunicatorDestroyedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if an attempt is made to use a deactivated + * {@link ObjectAdapter}. + * @see ObjectAdapter#deactivate + * @see Communicator#shutdown + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectAdapterDeactivatedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectAdapterDeactivatedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param name Name of the adapter. + */ + ObjectAdapterDeactivatedException(const char* file, int line, const ::std::string& name); + +#ifdef ICE_CPP11_COMPILER + ObjectAdapterDeactivatedException(const ObjectAdapterDeactivatedException&) = default; + virtual ~ObjectAdapterDeactivatedException(); +#else + virtual ~ObjectAdapterDeactivatedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ObjectAdapterDeactivatedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Name of the adapter. + */ + ::std::string name; +}; + +/** + * This exception is raised if an {@link ObjectAdapter} cannot be activated. + * + * This happens if the {@link Locator} detects another active {@link ObjectAdapter} with + * the same adapter id. + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectAdapterIdInUseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectAdapterIdInUseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id Adapter ID. + */ + ObjectAdapterIdInUseException(const char* file, int line, const ::std::string& id); + +#ifdef ICE_CPP11_COMPILER + ObjectAdapterIdInUseException(const ObjectAdapterIdInUseException&) = default; + virtual ~ObjectAdapterIdInUseException(); +#else + virtual ~ObjectAdapterIdInUseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ObjectAdapterIdInUseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Adapter ID. + */ + ::std::string id; +}; + +/** + * This exception is raised if no suitable endpoint is available. + * \headerfile Ice/Ice.h + */ +class ICE_API NoEndpointException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NoEndpointException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param proxy The stringified proxy for which no suitable endpoint is available. + */ + NoEndpointException(const char* file, int line, const ::std::string& proxy); + +#ifdef ICE_CPP11_COMPILER + NoEndpointException(const NoEndpointException&) = default; + virtual ~NoEndpointException(); +#else + virtual ~NoEndpointException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual NoEndpointException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The stringified proxy for which no suitable endpoint is + * available. + */ + ::std::string proxy; +}; + +/** + * This exception is raised if there was an error while parsing an + * endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_API EndpointParseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EndpointParseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + EndpointParseException(const char* file, int line, const ::std::string& str); + +#ifdef ICE_CPP11_COMPILER + EndpointParseException(const EndpointParseException&) = default; + virtual ~EndpointParseException(); +#else + virtual ~EndpointParseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual EndpointParseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing an + * endpoint selection type. + * \headerfile Ice/Ice.h + */ +class ICE_API EndpointSelectionTypeParseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EndpointSelectionTypeParseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + EndpointSelectionTypeParseException(const char* file, int line, const ::std::string& str); + +#ifdef ICE_CPP11_COMPILER + EndpointSelectionTypeParseException(const EndpointSelectionTypeParseException&) = default; + virtual ~EndpointSelectionTypeParseException(); +#else + virtual ~EndpointSelectionTypeParseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual EndpointSelectionTypeParseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * version. + * \headerfile Ice/Ice.h + */ +class ICE_API VersionParseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + VersionParseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + VersionParseException(const char* file, int line, const ::std::string& str); + +#ifdef ICE_CPP11_COMPILER + VersionParseException(const VersionParseException&) = default; + virtual ~VersionParseException(); +#else + virtual ~VersionParseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual VersionParseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * stringified identity. + * \headerfile Ice/Ice.h + */ +class ICE_API IdentityParseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IdentityParseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + IdentityParseException(const char* file, int line, const ::std::string& str); + +#ifdef ICE_CPP11_COMPILER + IdentityParseException(const IdentityParseException&) = default; + virtual ~IdentityParseException(); +#else + virtual ~IdentityParseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual IdentityParseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if there was an error while parsing a + * stringified proxy. + * \headerfile Ice/Ice.h + */ +class ICE_API ProxyParseException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProxyParseException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param str Describes the failure and includes the string that could not be parsed. + */ + ProxyParseException(const char* file, int line, const ::std::string& str); + +#ifdef ICE_CPP11_COMPILER + ProxyParseException(const ProxyParseException&) = default; + virtual ~ProxyParseException(); +#else + virtual ~ProxyParseException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ProxyParseException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes the failure and includes the string that could not be parsed. + */ + ::std::string str; +}; + +/** + * This exception is raised if an illegal identity is encountered. + * \headerfile Ice/Ice.h + */ +class ICE_API IllegalIdentityException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalIdentityException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The illegal identity. + */ + IllegalIdentityException(const char* file, int line, const Identity& id); + +#ifdef ICE_CPP11_COMPILER + IllegalIdentityException(const IllegalIdentityException&) = default; + virtual ~IllegalIdentityException(); +#else + virtual ~IllegalIdentityException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual IllegalIdentityException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The illegal identity. + */ + ::Ice::Identity id; +}; + +/** + * This exception is raised to reject an illegal servant (typically + * a null servant) + * \headerfile Ice/Ice.h + */ +class ICE_API IllegalServantException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalServantException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason Describes why this servant is illegal. + */ + IllegalServantException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + IllegalServantException(const IllegalServantException&) = default; + virtual ~IllegalServantException(); +#else + virtual ~IllegalServantException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual IllegalServantException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * Describes why this servant is illegal. + */ + ::std::string reason; +}; + +/** + * This exception is raised if a request failed. This exception, and + * all exceptions derived from {@link RequestFailedException}, are + * transmitted by the Ice protocol, even though they are declared + * local. + * \headerfile Ice/Ice.h + */ +class ICE_API RequestFailedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + RequestFailedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + RequestFailedException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation); + +#ifdef ICE_CPP11_COMPILER + RequestFailedException(const RequestFailedException&) = default; + virtual ~RequestFailedException(); +#else + virtual ~RequestFailedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual RequestFailedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The identity of the Ice Object to which the request was sent. + */ + ::Ice::Identity id; + /** + * The facet to which the request was sent. + */ + ::std::string facet; + /** + * The operation name of the request. + */ + ::std::string operation; +}; + +/** + * This exception is raised if an object does not exist on the server, + * that is, if no facets with the given identity exist. + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectNotExistException : public RequestFailedException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ObjectNotExistException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + ObjectNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation); + +#ifdef ICE_CPP11_COMPILER + ObjectNotExistException(const ObjectNotExistException&) = default; + virtual ~ObjectNotExistException(); +#else + virtual ~ObjectNotExistException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ObjectNotExistException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if no facet with the given name exists, + * but at least one facet with the given identity exists. + * \headerfile Ice/Ice.h + */ +class ICE_API FacetNotExistException : public RequestFailedException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FacetNotExistException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + FacetNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation); + +#ifdef ICE_CPP11_COMPILER + FacetNotExistException(const FacetNotExistException&) = default; + virtual ~FacetNotExistException(); +#else + virtual ~FacetNotExistException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual FacetNotExistException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if an operation for a given object does + * not exist on the server. Typically this is caused by either the + * client or the server using an outdated Slice specification. + * \headerfile Ice/Ice.h + */ +class ICE_API OperationNotExistException : public RequestFailedException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + OperationNotExistException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param id The identity of the Ice Object to which the request was sent. + * @param facet The facet to which the request was sent. + * @param operation The operation name of the request. + */ + OperationNotExistException(const char* file, int line, const Identity& id, const ::std::string& facet, const ::std::string& operation); + +#ifdef ICE_CPP11_COMPILER + OperationNotExistException(const OperationNotExistException&) = default; + virtual ~OperationNotExistException(); +#else + virtual ~OperationNotExistException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual OperationNotExistException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if a system error occurred in the server + * or client process. There are many possible causes for such a system + * exception. For details on the cause, {@link SyscallException#error} + * should be inspected. + * \headerfile Ice/Ice.h + */ +class ICE_API SyscallException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SyscallException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + SyscallException(const char* file, int line, Int error); + +#ifdef ICE_CPP11_COMPILER + SyscallException(const SyscallException&) = default; + virtual ~SyscallException(); +#else + virtual ~SyscallException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual SyscallException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The error number describing the system exception. For C++ and + * Unix, this is equivalent to errno. For C++ + * and Windows, this is the value returned by + * GetLastError() or + * WSAGetLastError(). + */ + ::Ice::Int error; +}; + +/** + * This exception indicates socket errors. + * \headerfile Ice/Ice.h + */ +class ICE_API SocketException : public SyscallException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SocketException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + SocketException(const char* file, int line, Int error); + +#ifdef ICE_CPP11_COMPILER + SocketException(const SocketException&) = default; + virtual ~SocketException(); +#else + virtual ~SocketException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual SocketException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates CFNetwork errors. + * \headerfile Ice/Ice.h + */ +class ICE_API CFNetworkException : public SocketException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CFNetworkException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + * @param domain The domain of the error. + */ + CFNetworkException(const char* file, int line, Int error, const ::std::string& domain); + +#ifdef ICE_CPP11_COMPILER + CFNetworkException(const CFNetworkException&) = default; + virtual ~CFNetworkException(); +#else + virtual ~CFNetworkException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CFNetworkException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The domain of the error. + */ + ::std::string domain; +}; + +/** + * This exception indicates file errors. + * \headerfile Ice/Ice.h + */ +class ICE_API FileException : public SyscallException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FileException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + * @param path The path of the file responsible for the error. + */ + FileException(const char* file, int line, Int error, const ::std::string& path); + +#ifdef ICE_CPP11_COMPILER + FileException(const FileException&) = default; + virtual ~FileException(); +#else + virtual ~FileException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual FileException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The path of the file responsible for the error. + */ + ::std::string path; +}; + +/** + * This exception indicates connection failures. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectFailedException : public SocketException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectFailedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectFailedException(const char* file, int line, Int error); + +#ifdef ICE_CPP11_COMPILER + ConnectFailedException(const ConnectFailedException&) = default; + virtual ~ConnectFailedException(); +#else + virtual ~ConnectFailedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectFailedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a connection failure for which + * the server host actively refuses a connection. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionRefusedException : public ConnectFailedException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionRefusedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectionRefusedException(const char* file, int line, Int error); + +#ifdef ICE_CPP11_COMPILER + ConnectionRefusedException(const ConnectionRefusedException&) = default; + virtual ~ConnectionRefusedException(); +#else + virtual ~ConnectionRefusedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectionRefusedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a lost connection. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionLostException : public SocketException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionLostException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the system exception. + */ + ConnectionLostException(const char* file, int line, Int error); + +#ifdef ICE_CPP11_COMPILER + ConnectionLostException(const ConnectionLostException&) = default; + virtual ~ConnectionLostException(); +#else + virtual ~ConnectionLostException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectionLostException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a DNS problem. For details on the cause, + * {@link DNSException#error} should be inspected. + * \headerfile Ice/Ice.h + */ +class ICE_API DNSException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + DNSException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param error The error number describing the DNS problem. + * @param host The host name that could not be resolved. + */ + DNSException(const char* file, int line, Int error, const ::std::string& host); + +#ifdef ICE_CPP11_COMPILER + DNSException(const DNSException&) = default; + virtual ~DNSException(); +#else + virtual ~DNSException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual DNSException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The error number describing the DNS problem. For C++ and Unix, + * this is equivalent to h_errno. For C++ and + * Windows, this is the value returned by + * WSAGetLastError(). + */ + ::Ice::Int error; + /** + * The host name that could not be resolved. + */ + ::std::string host; +}; + +/** + * This exception indicates a request was interrupted. + * \headerfile Ice/Ice.h + */ +class ICE_API OperationInterruptedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + OperationInterruptedException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + OperationInterruptedException(const OperationInterruptedException&) = default; + virtual ~OperationInterruptedException(); +#else + virtual ~OperationInterruptedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual OperationInterruptedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_API TimeoutException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + TimeoutException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + TimeoutException(const TimeoutException&) = default; + virtual ~TimeoutException(); +#else + virtual ~TimeoutException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual TimeoutException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a connection establishment timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectTimeoutException : public TimeoutException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectTimeoutException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + ConnectTimeoutException(const ConnectTimeoutException&) = default; + virtual ~ConnectTimeoutException(); +#else + virtual ~ConnectTimeoutException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectTimeoutException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a connection closure timeout condition. + * \headerfile Ice/Ice.h + */ +class ICE_API CloseTimeoutException : public TimeoutException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloseTimeoutException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + CloseTimeoutException(const CloseTimeoutException&) = default; + virtual ~CloseTimeoutException(); +#else + virtual ~CloseTimeoutException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CloseTimeoutException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that a connection has been shut down because it has been + * idle for some time. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionTimeoutException : public TimeoutException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionTimeoutException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + ConnectionTimeoutException(const ConnectionTimeoutException&) = default; + virtual ~ConnectionTimeoutException(); +#else + virtual ~ConnectionTimeoutException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectionTimeoutException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that an invocation failed because it timed + * out. + * \headerfile Ice/Ice.h + */ +class ICE_API InvocationTimeoutException : public TimeoutException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InvocationTimeoutException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + InvocationTimeoutException(const InvocationTimeoutException&) = default; + virtual ~InvocationTimeoutException(); +#else + virtual ~InvocationTimeoutException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual InvocationTimeoutException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that an asynchronous invocation failed + * because it was canceled explicitly by the user. + * \headerfile Ice/Ice.h + */ +class ICE_API InvocationCanceledException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + InvocationCanceledException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + InvocationCanceledException(const InvocationCanceledException&) = default; + virtual ~InvocationCanceledException(); +#else + virtual ~InvocationCanceledException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual InvocationCanceledException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * A generic exception base for all kinds of protocol error + * conditions. + * \headerfile Ice/Ice.h + */ +class ICE_API ProtocolException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProtocolException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ProtocolException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + ProtocolException(const ProtocolException&) = default; + virtual ~ProtocolException(); +#else + virtual ~ProtocolException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ProtocolException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that a message did not start with the expected + * magic number ('I', 'c', 'e', 'P'). + * \headerfile Ice/Ice.h + */ +class ICE_API BadMagicException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + BadMagicException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param badMagic A sequence containing the first four bytes of the incorrect message. + */ + BadMagicException(const char* file, int line, const ::std::string& reason, const ByteSeq& badMagic); + +#ifdef ICE_CPP11_COMPILER + BadMagicException(const BadMagicException&) = default; + virtual ~BadMagicException(); +#else + virtual ~BadMagicException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual BadMagicException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * A sequence containing the first four bytes of the incorrect message. + */ + ::Ice::ByteSeq badMagic; +}; + +/** + * This exception indicates an unsupported protocol version. + * \headerfile Ice/Ice.h + */ +class ICE_API UnsupportedProtocolException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnsupportedProtocolException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param bad The version of the unsupported protocol. + * @param supported The version of the protocol that is supported. + */ + UnsupportedProtocolException(const char* file, int line, const ::std::string& reason, const ProtocolVersion& bad, const ProtocolVersion& supported); + +#ifdef ICE_CPP11_COMPILER + UnsupportedProtocolException(const UnsupportedProtocolException&) = default; + virtual ~UnsupportedProtocolException(); +#else + virtual ~UnsupportedProtocolException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnsupportedProtocolException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The version of the unsupported protocol. + */ + ::Ice::ProtocolVersion bad; + /** + * The version of the protocol that is supported. + */ + ::Ice::ProtocolVersion supported; +}; + +/** + * This exception indicates an unsupported data encoding version. + * \headerfile Ice/Ice.h + */ +class ICE_API UnsupportedEncodingException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnsupportedEncodingException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param bad The version of the unsupported encoding. + * @param supported The version of the encoding that is supported. + */ + UnsupportedEncodingException(const char* file, int line, const ::std::string& reason, const EncodingVersion& bad, const EncodingVersion& supported); + +#ifdef ICE_CPP11_COMPILER + UnsupportedEncodingException(const UnsupportedEncodingException&) = default; + virtual ~UnsupportedEncodingException(); +#else + virtual ~UnsupportedEncodingException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnsupportedEncodingException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The version of the unsupported encoding. + */ + ::Ice::EncodingVersion bad; + /** + * The version of the encoding that is supported. + */ + ::Ice::EncodingVersion supported; +}; + +/** + * This exception indicates that an unknown protocol message has been received. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownMessageException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownMessageException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownMessageException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + UnknownMessageException(const UnknownMessageException&) = default; + virtual ~UnknownMessageException(); +#else + virtual ~UnknownMessageException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownMessageException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if a message is received over a connection + * that is not yet validated. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionNotValidatedException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionNotValidatedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ConnectionNotValidatedException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + ConnectionNotValidatedException(const ConnectionNotValidatedException&) = default; + virtual ~ConnectionNotValidatedException(); +#else + virtual ~ConnectionNotValidatedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectionNotValidatedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that a response for an unknown request ID has been + * received. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownRequestIdException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownRequestIdException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownRequestIdException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + UnknownRequestIdException(const UnknownRequestIdException&) = default; + virtual ~UnknownRequestIdException(); +#else + virtual ~UnknownRequestIdException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownRequestIdException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that an unknown reply status has been received. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownReplyStatusException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnknownReplyStatusException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnknownReplyStatusException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + UnknownReplyStatusException(const UnknownReplyStatusException&) = default; + virtual ~UnknownReplyStatusException(); +#else + virtual ~UnknownReplyStatusException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownReplyStatusException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates that the connection has been gracefully shut down by the + * server. The operation call that caused this exception has not been + * executed by the server. In most cases you will not get this + * exception, because the client will automatically retry the + * operation call in case the server shut down the connection. However, + * if upon retry the server shuts down the connection again, and the + * retry limit has been reached, then this exception is propagated to + * the application code. + * \headerfile Ice/Ice.h + */ +class ICE_API CloseConnectionException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CloseConnectionException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + CloseConnectionException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + CloseConnectionException(const CloseConnectionException&) = default; + virtual ~CloseConnectionException(); +#else + virtual ~CloseConnectionException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CloseConnectionException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised by an operation call if the application + * closes the connection locally using {@link Connection#close}. + * @see Connection#close + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionManuallyClosedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ConnectionManuallyClosedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param graceful True if the connection was closed gracefully, false otherwise. + */ + ConnectionManuallyClosedException(const char* file, int line, bool graceful); + +#ifdef ICE_CPP11_COMPILER + ConnectionManuallyClosedException(const ConnectionManuallyClosedException&) = default; + virtual ~ConnectionManuallyClosedException(); +#else + virtual ~ConnectionManuallyClosedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ConnectionManuallyClosedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * True if the connection was closed gracefully, false otherwise. + */ + bool graceful; +}; + +/** + * This exception indicates that a message size is less + * than the minimum required size. + * \headerfile Ice/Ice.h + */ +class ICE_API IllegalMessageSizeException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + IllegalMessageSizeException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + IllegalMessageSizeException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + IllegalMessageSizeException(const IllegalMessageSizeException&) = default; + virtual ~IllegalMessageSizeException(); +#else + virtual ~IllegalMessageSizeException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual IllegalMessageSizeException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a problem with compressing or uncompressing data. + * \headerfile Ice/Ice.h + */ +class ICE_API CompressionException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + CompressionException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + CompressionException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + CompressionException(const CompressionException&) = default; + virtual ~CompressionException(); +#else + virtual ~CompressionException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual CompressionException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * A datagram exceeds the configured size. + * + * This exception is raised if a datagram exceeds the configured send or receive buffer + * size, or exceeds the maximum payload size of a UDP packet (65507 bytes). + * \headerfile Ice/Ice.h + */ +class ICE_API DatagramLimitException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + DatagramLimitException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + DatagramLimitException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + DatagramLimitException(const DatagramLimitException&) = default; + virtual ~DatagramLimitException(); +#else + virtual ~DatagramLimitException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual DatagramLimitException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised for errors during marshaling or unmarshaling data. + * \headerfile Ice/Ice.h + */ +class ICE_API MarshalException : public ProtocolException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + MarshalException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + MarshalException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + MarshalException(const MarshalException&) = default; + virtual ~MarshalException(); +#else + virtual ~MarshalException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual MarshalException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if inconsistent data is received while unmarshaling a proxy. + * \headerfile Ice/Ice.h + */ +class ICE_API ProxyUnmarshalException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ProxyUnmarshalException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + ProxyUnmarshalException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + ProxyUnmarshalException(const ProxyUnmarshalException&) = default; + virtual ~ProxyUnmarshalException(); +#else + virtual ~ProxyUnmarshalException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ProxyUnmarshalException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if an out-of-bounds condition occurs during unmarshaling. + * \headerfile Ice/Ice.h + */ +class ICE_API UnmarshalOutOfBoundsException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnmarshalOutOfBoundsException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + UnmarshalOutOfBoundsException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + UnmarshalOutOfBoundsException(const UnmarshalOutOfBoundsException&) = default; + virtual ~UnmarshalOutOfBoundsException(); +#else + virtual ~UnmarshalOutOfBoundsException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnmarshalOutOfBoundsException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if no suitable value factory was found during + * unmarshaling of a Slice class instance. + * @see ValueFactory + * @see Communicator#getValueFactoryManager + * @see ValueFactoryManager#add + * @see ValueFactoryManager#find + * \headerfile Ice/Ice.h + */ +class ICE_API NoValueFactoryException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + NoValueFactoryException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param type The Slice type ID of the class instance for which no no factory could be found. + */ + NoValueFactoryException(const char* file, int line, const ::std::string& reason, const ::std::string& type); + +#ifdef ICE_CPP11_COMPILER + NoValueFactoryException(const NoValueFactoryException&) = default; + virtual ~NoValueFactoryException(); +#else + virtual ~NoValueFactoryException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual NoValueFactoryException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The Slice type ID of the class instance for which no + * no factory could be found. + */ + ::std::string type; +}; + +/** + * This exception is raised if the type of an unmarshaled Slice class instance does + * not match its expected type. + * This can happen if client and server are compiled with mismatched Slice + * definitions or if a class of the wrong type is passed as a parameter + * or return value using dynamic invocation. This exception can also be + * raised if IceStorm is used to send Slice class instances and + * an operation is subscribed to the wrong topic. + * \headerfile Ice/Ice.h + */ +class ICE_API UnexpectedObjectException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + UnexpectedObjectException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + * @param type The Slice type ID of the class instance that was unmarshaled. + * @param expectedType The Slice type ID that was expected by the receiving operation. + */ + UnexpectedObjectException(const char* file, int line, const ::std::string& reason, const ::std::string& type, const ::std::string& expectedType); + +#ifdef ICE_CPP11_COMPILER + UnexpectedObjectException(const UnexpectedObjectException&) = default; + virtual ~UnexpectedObjectException(); +#else + virtual ~UnexpectedObjectException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnexpectedObjectException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The Slice type ID of the class instance that was unmarshaled. + */ + ::std::string type; + /** + * The Slice type ID that was expected by the receiving operation. + */ + ::std::string expectedType; +}; + +/** + * This exception is raised when Ice receives a request or reply + * message whose size exceeds the limit specified by the + * Ice.MessageSizeMax property. + * \headerfile Ice/Ice.h + */ +class ICE_API MemoryLimitException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + MemoryLimitException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + MemoryLimitException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + MemoryLimitException(const MemoryLimitException&) = default; + virtual ~MemoryLimitException(); +#else + virtual ~MemoryLimitException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual MemoryLimitException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised when a string conversion to or from UTF-8 + * fails during marshaling or unmarshaling. + * \headerfile Ice/Ice.h + */ +class ICE_API StringConversionException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + StringConversionException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + StringConversionException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + StringConversionException(const StringConversionException&) = default; + virtual ~StringConversionException(); +#else + virtual ~StringConversionException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual StringConversionException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception indicates a malformed data encapsulation. + * \headerfile Ice/Ice.h + */ +class ICE_API EncapsulationException : public MarshalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + EncapsulationException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + EncapsulationException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + EncapsulationException(const EncapsulationException&) = default; + virtual ~EncapsulationException(); +#else + virtual ~EncapsulationException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual EncapsulationException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * This exception is raised if an unsupported feature is used. The + * unsupported feature string contains the name of the unsupported + * feature + * \headerfile Ice/Ice.h + */ +class ICE_API FeatureNotSupportedException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FeatureNotSupportedException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param unsupportedFeature The name of the unsupported feature. + */ + FeatureNotSupportedException(const char* file, int line, const ::std::string& unsupportedFeature); + +#ifdef ICE_CPP11_COMPILER + FeatureNotSupportedException(const FeatureNotSupportedException&) = default; + virtual ~FeatureNotSupportedException(); +#else + virtual ~FeatureNotSupportedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual FeatureNotSupportedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The name of the unsupported feature. + */ + ::std::string unsupportedFeature; +}; + +/** + * This exception indicates a failure in a security subsystem, + * such as the IceSSL plug-in. + * \headerfile Ice/Ice.h + */ +class ICE_API SecurityException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + SecurityException(const char* file, int line); + /** + * One-shot constructor to initialize all data members. + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + * @param reason The reason for the failure. + */ + SecurityException(const char* file, int line, const ::std::string& reason); + +#ifdef ICE_CPP11_COMPILER + SecurityException(const SecurityException&) = default; + virtual ~SecurityException(); +#else + virtual ~SecurityException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual SecurityException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + + /** + * The reason for the failure. + */ + ::std::string reason; +}; + +/** + * This exception indicates that an attempt has been made to + * change the connection properties of a fixed proxy. + * \headerfile Ice/Ice.h + */ +class ICE_API FixedProxyException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + FixedProxyException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + FixedProxyException(const FixedProxyException&) = default; + virtual ~FixedProxyException(); +#else + virtual ~FixedProxyException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual FixedProxyException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +/** + * Indicates that the response to a request has already been sent; + * re-dispatching such a request is not possible. + * \headerfile Ice/Ice.h + */ +class ICE_API ResponseSentException : public LocalException +{ +public: + + /** + * The file and line number are required for all local exceptions. + * @param file The file name in which the exception was raised, typically __FILE__. + * @param line The line number at which the exception was raised, typically __LINE__. + */ + ResponseSentException(const char* file, int line); + +#ifdef ICE_CPP11_COMPILER + ResponseSentException(const ResponseSentException&) = default; + virtual ~ResponseSentException(); +#else + virtual ~ResponseSentException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Prints this exception to the given stream. + * @param stream The target stream. + */ + virtual void ice_print(::std::ostream& stream) const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ResponseSentException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/LocalObject.h b/Sources/IceCpp/include/Ice/LocalObject.h new file mode 100644 index 0000000..75d03da --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocalObject.h @@ -0,0 +1,35 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOCAL_OBJECT_H +#define ICE_LOCAL_OBJECT_H + +#if !defined(ICE_CPP11_MAPPING) || defined(ICE_BUILDING_SRC) +// +// Part of the C++98 mapping, and "internal" definitions when building Ice +// with the C++11 mapping +// + +#include +#include + +namespace Ice +{ + +/** + * Base class for local Slice classes and interfaces. + * \headerfile Ice/Ice.h + */ +class ICE_API LocalObject : public virtual ::IceUtil::Shared +{ +public: + + virtual bool operator==(const LocalObject&) const; + virtual bool operator<(const LocalObject&) const; +}; + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/LocalObjectF.h b/Sources/IceCpp/include/Ice/LocalObjectF.h new file mode 100644 index 0000000..8037a06 --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocalObjectF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOCAL_OBJECT_F_H +#define ICE_LOCAL_OBJECT_F_H + +#include + +#include + +namespace Ice +{ + +class LocalObject; +ICE_API IceUtil::Shared* upCast(::Ice::LocalObject*); +typedef IceInternal::Handle< LocalObject > LocalObjectPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Locator.h b/Sources/IceCpp/include/Ice/Locator.h new file mode 100644 index 0000000..8035733 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Locator.h @@ -0,0 +1,3898 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Locator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Locator_h__ +#define __Ice_Locator_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class LocatorRegistry; +class LocatorRegistryPrx; +class Locator; +class LocatorPrx; +class LocatorFinder; +class LocatorFinderPrx; + +} + +namespace Ice +{ + +/** + * This exception is raised if an adapter cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) AdapterNotFoundException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~AdapterNotFoundException(); + + AdapterNotFoundException(const AdapterNotFoundException&) = default; + + AdapterNotFoundException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/// \cond INTERNAL +static AdapterNotFoundException _iceS_AdapterNotFoundException_init; +/// \endcond + +/** + * This exception is raised if the replica group provided by the + * server is invalid. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InvalidReplicaGroupIdException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InvalidReplicaGroupIdException(); + + InvalidReplicaGroupIdException(const InvalidReplicaGroupIdException&) = default; + + InvalidReplicaGroupIdException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/** + * This exception is raised if a server tries to set endpoints for + * an adapter that is already active. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) AdapterAlreadyActiveException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~AdapterAlreadyActiveException(); + + AdapterAlreadyActiveException(const AdapterAlreadyActiveException&) = default; + + AdapterAlreadyActiveException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/** + * This exception is raised if an object cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectNotFoundException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectNotFoundException(); + + ObjectNotFoundException(const ObjectNotFoundException&) = default; + + ObjectNotFoundException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/** + * This exception is raised if a server cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ServerNotFoundException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ServerNotFoundException(); + + ServerNotFoundException(const ServerNotFoundException&) = default; + + ServerNotFoundException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +} + +namespace Ice +{ + +/** + * The Ice locator interface. This interface is used by clients to + * lookup adapters and objects. It is also used by servers to get the + * locator registry proxy. + * + *

The {@link Locator} interface is intended to be used by + * Ice internals and by locator implementations. Regular user code + * should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_API Locator : public virtual Object +{ +public: + + using ProxyType = LocatorPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param response The response callback. + * @param exception The exception callback. + * @param current The Current object for the invocation. + * @throws Ice::ObjectNotFoundException Raised if the object cannot + * be found. + */ + virtual void findObjectByIdAsync(Identity id, ::std::function& returnValue)> response, ::std::function exception, const Current& current) const = 0; + /// \cond INTERNAL + bool _iceD_findObjectById(::IceInternal::Incoming&, const Current&) const; + /// \endcond + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param response The response callback. + * @param exception The exception callback. + * @param current The Current object for the invocation. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot be + * found. + */ + virtual void findAdapterByIdAsync(::std::string id, ::std::function& returnValue)> response, ::std::function exception, const Current& current) const = 0; + /// \cond INTERNAL + bool _iceD_findAdapterById(::IceInternal::Incoming&, const Current&) const; + /// \endcond + + /** + * Get the locator registry. + * @param current The Current object for the invocation. + * @return The locator registry. + */ + virtual ::std::shared_ptr getRegistry(const Current& current) const = 0; + /// \cond INTERNAL + bool _iceD_getRegistry(::IceInternal::Incoming&, const Current&) const; + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +/** + * The Ice locator registry interface. This interface is used by + * servers to register adapter endpoints with the locator. + * + *

The {@link LocatorRegistry} interface is intended to be used + * by Ice internals and by locator implementations. Regular user + * code should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_API LocatorRegistry : public virtual Object +{ +public: + + using ProxyType = LocatorRegistryPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param response The response callback. + * @param exception The exception callback. + * @param current The Current object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows + * registered adapters to set their active proxy and the + * adapter is not registered with the locator. + */ + virtual void setAdapterDirectProxyAsync(::std::string id, ::std::shared_ptr proxy, ::std::function response, ::std::function exception, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_setAdapterDirectProxy(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param response The response callback. + * @param exception The exception callback. + * @param current The Current object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows registered adapters to + * set their active proxy and the adapter is not registered with + * the locator. + * @throws Ice::InvalidReplicaGroupIdException Raised if the given + * replica group doesn't match the one registered with the + * locator registry for this object adapter. + */ + virtual void setReplicatedAdapterDirectProxyAsync(::std::string adapterId, ::std::string replicaGroupId, ::std::shared_ptr p, ::std::function response, ::std::function exception, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_setReplicatedAdapterDirectProxy(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param response The response callback. + * @param exception The exception callback. + * @param current The Current object for the invocation. + * @throws Ice::ServerNotFoundException Raised if the server cannot + * be found. + */ + virtual void setServerProcessProxyAsync(::std::string id, ::std::shared_ptr proxy, ::std::function response, ::std::function exception, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_setServerProcessProxy(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +/** + * This inferface should be implemented by services implementing the + * Ice::Locator interface. It should be advertised through an Ice + * object with the identity `Ice/LocatorFinder'. This allows clients + * to retrieve the locator proxy with just the endpoint information of + * the service. + * \headerfile Ice/Ice.h + */ +class ICE_API LocatorFinder : public virtual Object +{ +public: + + using ProxyType = LocatorFinderPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param current The Current object for the invocation. + * @return The locator proxy. + */ + virtual ::std::shared_ptr getLocator(const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getLocator(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * The Ice locator interface. This interface is used by clients to + * lookup adapters and objects. It is also used by servers to get the + * locator registry proxy. + * + *

The {@link Locator} interface is intended to be used by + * Ice internals and by locator implementations. Regular user code + * should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) LocatorPrx : public virtual Proxy +{ +public: + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @return The proxy, or null if the object is not active. + * @throws Ice::ObjectNotFoundException Raised if the object cannot + * be found. + */ + ::std::shared_ptr findObjectById(const Identity& id, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(true, this, &LocatorPrx::_iceI_findObjectById, id, context).get(); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto findObjectByIdAsync(const Identity& id, const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>, P>(false, this, &LocatorPrx::_iceI_findObjectById, id, context); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + findObjectByIdAsync(const Identity& id, + ::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorPrx::_iceI_findObjectById, id, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_findObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>&, const Identity&, const Context&); + /// \endcond + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @return The adapter proxy, or null if the adapter is not active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot be + * found. + */ + ::std::shared_ptr findAdapterById(const ::std::string& id, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(true, this, &LocatorPrx::_iceI_findAdapterById, id, context).get(); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto findAdapterByIdAsync(const ::std::string& id, const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>, P>(false, this, &LocatorPrx::_iceI_findAdapterById, id, context); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + findAdapterByIdAsync(const ::std::string& id, + ::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorPrx::_iceI_findAdapterById, id, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_findAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>&, const ::std::string&, const Context&); + /// \endcond + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @return The locator registry. + */ + ::std::shared_ptr getRegistry(const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::LocatorRegistryPrx>>(true, this, &LocatorPrx::_iceI_getRegistry, context).get(); + } + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getRegistryAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::LocatorRegistryPrx>, P>(false, this, &LocatorPrx::_iceI_getRegistry, context); + } + + /** + * Get the locator registry. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getRegistryAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::LocatorRegistryPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorPrx::_iceI_getRegistry, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getRegistry(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::LocatorRegistryPrx>>>&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LocatorPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +/** + * The Ice locator registry interface. This interface is used by + * servers to register adapter endpoints with the locator. + * + *

The {@link LocatorRegistry} interface is intended to be used + * by Ice internals and by locator implementations. Regular user + * code should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) LocatorRegistryPrx : public virtual Proxy +{ +public: + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows + * registered adapters to set their active proxy and the + * adapter is not registered with the locator. + */ + void setAdapterDirectProxy(const ::std::string& id, const ::std::shared_ptr& proxy, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &LocatorRegistryPrx::_iceI_setAdapterDirectProxy, id, proxy, context).get(); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto setAdapterDirectProxyAsync(const ::std::string& id, const ::std::shared_ptr& proxy, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LocatorRegistryPrx::_iceI_setAdapterDirectProxy, id, proxy, context); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + setAdapterDirectProxyAsync(const ::std::string& id, const ::std::shared_ptr& proxy, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorRegistryPrx::_iceI_setAdapterDirectProxy, id, proxy, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_setAdapterDirectProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::shared_ptr&, const Context&); + /// \endcond + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows registered adapters to + * set their active proxy and the adapter is not registered with + * the locator. + * @throws Ice::InvalidReplicaGroupIdException Raised if the given + * replica group doesn't match the one registered with the + * locator registry for this object adapter. + */ + void setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::std::shared_ptr& p, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &LocatorRegistryPrx::_iceI_setReplicatedAdapterDirectProxy, adapterId, replicaGroupId, p, context).get(); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto setReplicatedAdapterDirectProxyAsync(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::std::shared_ptr& p, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LocatorRegistryPrx::_iceI_setReplicatedAdapterDirectProxy, adapterId, replicaGroupId, p, context); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + setReplicatedAdapterDirectProxyAsync(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::std::shared_ptr& p, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorRegistryPrx::_iceI_setReplicatedAdapterDirectProxy, adapterId, replicaGroupId, p, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_setReplicatedAdapterDirectProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::string&, const ::std::shared_ptr&, const Context&); + /// \endcond + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @throws Ice::ServerNotFoundException Raised if the server cannot + * be found. + */ + void setServerProcessProxy(const ::std::string& id, const ::std::shared_ptr& proxy, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &LocatorRegistryPrx::_iceI_setServerProcessProxy, id, proxy, context).get(); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto setServerProcessProxyAsync(const ::std::string& id, const ::std::shared_ptr& proxy, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LocatorRegistryPrx::_iceI_setServerProcessProxy, id, proxy, context); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + setServerProcessProxyAsync(const ::std::string& id, const ::std::shared_ptr& proxy, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorRegistryPrx::_iceI_setServerProcessProxy, id, proxy, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_setServerProcessProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::shared_ptr&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LocatorRegistryPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +/** + * This inferface should be implemented by services implementing the + * Ice::Locator interface. It should be advertised through an Ice + * object with the identity `Ice/LocatorFinder'. This allows clients + * to retrieve the locator proxy with just the endpoint information of + * the service. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) LocatorFinderPrx : public virtual Proxy +{ +public: + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The locator proxy. + */ + ::std::shared_ptr getLocator(const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::LocatorPrx>>(true, this, &LocatorFinderPrx::_iceI_getLocator, context).get(); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getLocatorAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::LocatorPrx>, P>(false, this, &LocatorFinderPrx::_iceI_getLocator, context); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getLocatorAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::LocatorPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::LocatorFinderPrx::_iceI_getLocator, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::LocatorPrx>>>&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LocatorFinderPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using LocatorRegistryPtr = ::std::shared_ptr; +using LocatorRegistryPrxPtr = ::std::shared_ptr; + +using LocatorPtr = ::std::shared_ptr; +using LocatorPrxPtr = ::std::shared_ptr; + +using LocatorFinderPtr = ::std::shared_ptr; +using LocatorFinderPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class LocatorRegistry; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LocatorRegistry>&); +ICE_API ::IceProxy::Ice::Object* upCast(LocatorRegistry*); +/// \endcond + +class Locator; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Locator>&); +ICE_API ::IceProxy::Ice::Object* upCast(Locator*); +/// \endcond + +class LocatorFinder; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LocatorFinder>&); +ICE_API ::IceProxy::Ice::Object* upCast(LocatorFinder*); +/// \endcond + +} + +} + +namespace Ice +{ + +class LocatorRegistry; +/// \cond INTERNAL +ICE_API Object* upCast(LocatorRegistry*); +/// \endcond +typedef ::IceInternal::Handle< LocatorRegistry> LocatorRegistryPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::LocatorRegistry> LocatorRegistryPrx; +typedef LocatorRegistryPrx LocatorRegistryPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LocatorRegistryPtr&, const ObjectPtr&); +/// \endcond + +class Locator; +/// \cond INTERNAL +ICE_API Object* upCast(Locator*); +/// \endcond +typedef ::IceInternal::Handle< Locator> LocatorPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Locator> LocatorPrx; +typedef LocatorPrx LocatorPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LocatorPtr&, const ObjectPtr&); +/// \endcond + +class LocatorFinder; +/// \cond INTERNAL +ICE_API Object* upCast(LocatorFinder*); +/// \endcond +typedef ::IceInternal::Handle< LocatorFinder> LocatorFinderPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::LocatorFinder> LocatorFinderPrx; +typedef LocatorFinderPrx LocatorFinderPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LocatorFinderPtr&, const ObjectPtr&); +/// \endcond + +} + +namespace Ice +{ + +/** + * This exception is raised if an adapter cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_API AdapterNotFoundException : public UserException +{ +public: + + AdapterNotFoundException() {} + +#ifdef ICE_CPP11_COMPILER + AdapterNotFoundException(const AdapterNotFoundException&) = default; + virtual ~AdapterNotFoundException(); +#else + virtual ~AdapterNotFoundException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual AdapterNotFoundException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +static AdapterNotFoundException _iceS_AdapterNotFoundException_init; +/// \endcond + +/** + * This exception is raised if the replica group provided by the + * server is invalid. + * \headerfile Ice/Ice.h + */ +class ICE_API InvalidReplicaGroupIdException : public UserException +{ +public: + + InvalidReplicaGroupIdException() {} + +#ifdef ICE_CPP11_COMPILER + InvalidReplicaGroupIdException(const InvalidReplicaGroupIdException&) = default; + virtual ~InvalidReplicaGroupIdException(); +#else + virtual ~InvalidReplicaGroupIdException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual InvalidReplicaGroupIdException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +/** + * This exception is raised if a server tries to set endpoints for + * an adapter that is already active. + * \headerfile Ice/Ice.h + */ +class ICE_API AdapterAlreadyActiveException : public UserException +{ +public: + + AdapterAlreadyActiveException() {} + +#ifdef ICE_CPP11_COMPILER + AdapterAlreadyActiveException(const AdapterAlreadyActiveException&) = default; + virtual ~AdapterAlreadyActiveException(); +#else + virtual ~AdapterAlreadyActiveException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual AdapterAlreadyActiveException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +/** + * This exception is raised if an object cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectNotFoundException : public UserException +{ +public: + + ObjectNotFoundException() {} + +#ifdef ICE_CPP11_COMPILER + ObjectNotFoundException(const ObjectNotFoundException&) = default; + virtual ~ObjectNotFoundException(); +#else + virtual ~ObjectNotFoundException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ObjectNotFoundException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +/** + * This exception is raised if a server cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_API ServerNotFoundException : public UserException +{ +public: + + ServerNotFoundException() {} + +#ifdef ICE_CPP11_COMPILER + ServerNotFoundException(const ServerNotFoundException&) = default; + virtual ~ServerNotFoundException(); +#else + virtual ~ServerNotFoundException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual ServerNotFoundException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * AMD callback class for Ice::Locator::findObjectById_async. + * Call the ice_response method for a successful completion, or the ice_exception + * method in the case of an error. + */ +class ICE_API AMD_Locator_findObjectById : public virtual AMDCallback +{ +public: + + virtual ~AMD_Locator_findObjectById(); + + /** + * Call ice_response for a successful completion. + * @param result The proxy, or null if the object is not active. + */ + virtual void ice_response(const ObjectPrx& result) = 0; +}; + +typedef ::IceUtil::Handle< ::Ice::AMD_Locator_findObjectById> AMD_Locator_findObjectByIdPtr; + +/** + * AMD callback class for Ice::Locator::findAdapterById_async. + * Call the ice_response method for a successful completion, or the ice_exception + * method in the case of an error. + */ +class ICE_API AMD_Locator_findAdapterById : public virtual AMDCallback +{ +public: + + virtual ~AMD_Locator_findAdapterById(); + + /** + * Call ice_response for a successful completion. + * @param result The adapter proxy, or null if the adapter is not active. + */ + virtual void ice_response(const ObjectPrx& result) = 0; +}; + +typedef ::IceUtil::Handle< ::Ice::AMD_Locator_findAdapterById> AMD_Locator_findAdapterByIdPtr; + +/** + * AMD callback class for Ice::LocatorRegistry::setAdapterDirectProxy_async. + * Call the ice_response method for a successful completion, or the ice_exception + * method in the case of an error. + */ +class ICE_API AMD_LocatorRegistry_setAdapterDirectProxy : public virtual AMDCallback +{ +public: + + virtual ~AMD_LocatorRegistry_setAdapterDirectProxy(); + + /** + * Call ice_response for a successful completion. + */ + virtual void ice_response() = 0; +}; + +typedef ::IceUtil::Handle< ::Ice::AMD_LocatorRegistry_setAdapterDirectProxy> AMD_LocatorRegistry_setAdapterDirectProxyPtr; + +/** + * AMD callback class for Ice::LocatorRegistry::setReplicatedAdapterDirectProxy_async. + * Call the ice_response method for a successful completion, or the ice_exception + * method in the case of an error. + */ +class ICE_API AMD_LocatorRegistry_setReplicatedAdapterDirectProxy : public virtual AMDCallback +{ +public: + + virtual ~AMD_LocatorRegistry_setReplicatedAdapterDirectProxy(); + + /** + * Call ice_response for a successful completion. + */ + virtual void ice_response() = 0; +}; + +typedef ::IceUtil::Handle< ::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy> AMD_LocatorRegistry_setReplicatedAdapterDirectProxyPtr; + +/** + * AMD callback class for Ice::LocatorRegistry::setServerProcessProxy_async. + * Call the ice_response method for a successful completion, or the ice_exception + * method in the case of an error. + */ +class ICE_API AMD_LocatorRegistry_setServerProcessProxy : public virtual AMDCallback +{ +public: + + virtual ~AMD_LocatorRegistry_setServerProcessProxy(); + + /** + * Call ice_response for a successful completion. + */ + virtual void ice_response() = 0; +}; + +typedef ::IceUtil::Handle< ::Ice::AMD_LocatorRegistry_setServerProcessProxy> AMD_LocatorRegistry_setServerProcessProxyPtr; + +} + +/// \cond INTERNAL +namespace IceAsync +{ + +namespace Ice +{ + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API AMD_Locator_findObjectById : public ::Ice::AMD_Locator_findObjectById, public ::IceInternal::IncomingAsync +{ +public: + + AMD_Locator_findObjectById(::IceInternal::Incoming&); + + virtual void ice_response(const ::Ice::ObjectPrx&); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API AMD_Locator_findAdapterById : public ::Ice::AMD_Locator_findAdapterById, public ::IceInternal::IncomingAsync +{ +public: + + AMD_Locator_findAdapterById(::IceInternal::Incoming&); + + virtual void ice_response(const ::Ice::ObjectPrx&); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API AMD_LocatorRegistry_setAdapterDirectProxy : public ::Ice::AMD_LocatorRegistry_setAdapterDirectProxy, public ::IceInternal::IncomingAsync +{ +public: + + AMD_LocatorRegistry_setAdapterDirectProxy(::IceInternal::Incoming&); + + virtual void ice_response(); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API AMD_LocatorRegistry_setReplicatedAdapterDirectProxy : public ::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxy, public ::IceInternal::IncomingAsync +{ +public: + + AMD_LocatorRegistry_setReplicatedAdapterDirectProxy(::IceInternal::Incoming&); + + virtual void ice_response(); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(push) +# pragma warning(disable:4239) +#endif + +class ICE_API AMD_LocatorRegistry_setServerProcessProxy : public ::Ice::AMD_LocatorRegistry_setServerProcessProxy, public ::IceInternal::IncomingAsync +{ +public: + + AMD_LocatorRegistry_setServerProcessProxy(::IceInternal::Incoming&); + + virtual void ice_response(); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(pop) +#endif + +} + +} +/// \endcond + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Locator::begin_findObjectById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findObjectById. + */ +class Callback_Locator_findObjectById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Locator_findObjectById_Base> Callback_Locator_findObjectByIdPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Locator::begin_findAdapterById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findAdapterById. + */ +class Callback_Locator_findAdapterById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Locator_findAdapterById_Base> Callback_Locator_findAdapterByIdPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Locator::begin_getRegistry. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_getRegistry. + */ +class Callback_Locator_getRegistry_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Locator_getRegistry_Base> Callback_Locator_getRegistryPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setAdapterDirectProxy. + */ +class Callback_LocatorRegistry_setAdapterDirectProxy_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LocatorRegistry_setAdapterDirectProxy_Base> Callback_LocatorRegistry_setAdapterDirectProxyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy. + */ +class Callback_LocatorRegistry_setReplicatedAdapterDirectProxy_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LocatorRegistry_setReplicatedAdapterDirectProxy_Base> Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setServerProcessProxy. + */ +class Callback_LocatorRegistry_setServerProcessProxy_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LocatorRegistry_setServerProcessProxy_Base> Callback_LocatorRegistry_setServerProcessProxyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LocatorFinder::begin_getLocator. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorFinder_getLocator. + */ +class Callback_LocatorFinder_getLocator_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LocatorFinder_getLocator_Base> Callback_LocatorFinder_getLocatorPtr; + +} + +namespace IceProxy +{ + +namespace Ice +{ + +class ICE_CLASS(ICE_API) Locator : public virtual ::Ice::Proxy +{ +public: + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @return The proxy, or null if the object is not active. + * @throws Ice::ObjectNotFoundException Raised if the object cannot + * be found. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx findObjectById(const ::Ice::Identity& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_findObjectById(_iceI_begin_findObjectById(id, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::Ice::Identity& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_findObjectById(id, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::Ice::Identity& id, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::Ice::Identity& id, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(id, context, cb, cookie); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::Ice::Identity& id, const ::Ice::Callback_Locator_findObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param id The identity. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::Ice::Identity& id, const ::Ice::Context& context, const ::Ice::Callback_Locator_findObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(id, context, cb, cookie); + } + + /** + * Completes an invocation of begin_findObjectById. + * @param result The asynchronous result object for the invocation. + * @return The proxy, or null if the object is not active. + * @throws Ice::ObjectNotFoundException Raised if the object cannot + * be found. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx end_findObjectById(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_findObjectById(const ::Ice::Identity&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @return The adapter proxy, or null if the adapter is not active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx findAdapterById(const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_findAdapterById(_iceI_begin_findAdapterById(id, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_findAdapterById(id, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& id, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& id, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(id, context, cb, cookie); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& id, const ::Ice::Callback_Locator_findAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param id The adapter id. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& id, const ::Ice::Context& context, const ::Ice::Callback_Locator_findAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(id, context, cb, cookie); + } + + /** + * Completes an invocation of begin_findAdapterById. + * @param result The asynchronous result object for the invocation. + * @return The adapter proxy, or null if the adapter is not active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx end_findAdapterById(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_findAdapterById(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @return The locator registry. + */ + ICE_MEMBER(ICE_API) ::Ice::LocatorRegistryPrx getRegistry(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getRegistry(_iceI_begin_getRegistry(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRegistry(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getRegistry(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the locator registry. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRegistry(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRegistry(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRegistry(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRegistry(context, cb, cookie); + } + + /** + * Get the locator registry. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRegistry(const ::Ice::Callback_Locator_getRegistryPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRegistry(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the locator registry. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRegistry(const ::Ice::Context& context, const ::Ice::Callback_Locator_getRegistryPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRegistry(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getRegistry. + * @param result The asynchronous result object for the invocation. + * @return The locator registry. + */ + ICE_MEMBER(ICE_API) ::Ice::LocatorRegistryPrx end_getRegistry(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getRegistry(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) LocatorRegistry : public virtual ::Ice::Proxy +{ +public: + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows + * registered adapters to set their active proxy and the + * adapter is not registered with the locator. + */ + ICE_MEMBER(ICE_API) void setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_setAdapterDirectProxy(_iceI_begin_setAdapterDirectProxy(id, proxy, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_setAdapterDirectProxy(id, proxy, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setAdapterDirectProxy(id, proxy, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setAdapterDirectProxy(id, proxy, context, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::Callback_LocatorRegistry_setAdapterDirectProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setAdapterDirectProxy(id, proxy, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setAdapterDirectProxy(const ::std::string& id, const ::Ice::ObjectPrx& proxy, const ::Ice::Context& context, const ::Ice::Callback_LocatorRegistry_setAdapterDirectProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setAdapterDirectProxy(id, proxy, context, cb, cookie); + } + + /** + * Completes an invocation of begin_setAdapterDirectProxy. + * @param result The asynchronous result object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows + * registered adapters to set their active proxy and the + * adapter is not registered with the locator. + */ + ICE_MEMBER(ICE_API) void end_setAdapterDirectProxy(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_setAdapterDirectProxy(const ::std::string&, const ::Ice::ObjectPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows registered adapters to + * set their active proxy and the adapter is not registered with + * the locator. + * @throws Ice::InvalidReplicaGroupIdException Raised if the given + * replica group doesn't match the one registered with the + * locator registry for this object adapter. + */ + ICE_MEMBER(ICE_API) void setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_setReplicatedAdapterDirectProxy(_iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, context, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the adapter endpoints with the locator registry. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setReplicatedAdapterDirectProxy(const ::std::string& adapterId, const ::std::string& replicaGroupId, const ::Ice::ObjectPrx& p, const ::Ice::Context& context, const ::Ice::Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setReplicatedAdapterDirectProxy(adapterId, replicaGroupId, p, context, cb, cookie); + } + + /** + * Completes an invocation of begin_setReplicatedAdapterDirectProxy. + * @param result The asynchronous result object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows registered adapters to + * set their active proxy and the adapter is not registered with + * the locator. + * @throws Ice::InvalidReplicaGroupIdException Raised if the given + * replica group doesn't match the one registered with the + * locator registry for this object adapter. + */ + ICE_MEMBER(ICE_API) void end_setReplicatedAdapterDirectProxy(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_setReplicatedAdapterDirectProxy(const ::std::string&, const ::std::string&, const ::Ice::ObjectPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @throws Ice::ServerNotFoundException Raised if the server cannot + * be found. + */ + ICE_MEMBER(ICE_API) void setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_setServerProcessProxy(_iceI_begin_setServerProcessProxy(id, proxy, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_setServerProcessProxy(id, proxy, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setServerProcessProxy(id, proxy, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setServerProcessProxy(id, proxy, context, cb, cookie); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::Callback_LocatorRegistry_setServerProcessProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setServerProcessProxy(id, proxy, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Set the process proxy for a server. + * @param id The server id. + * @param proxy The process proxy. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setServerProcessProxy(const ::std::string& id, const ::Ice::ProcessPrx& proxy, const ::Ice::Context& context, const ::Ice::Callback_LocatorRegistry_setServerProcessProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setServerProcessProxy(id, proxy, context, cb, cookie); + } + + /** + * Completes an invocation of begin_setServerProcessProxy. + * @param result The asynchronous result object for the invocation. + * @throws Ice::ServerNotFoundException Raised if the server cannot + * be found. + */ + ICE_MEMBER(ICE_API) void end_setServerProcessProxy(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_setServerProcessProxy(const ::std::string&, const ::Ice::ProcessPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) LocatorFinder : public virtual ::Ice::Proxy +{ +public: + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The locator proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::LocatorPrx getLocator(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getLocator(_iceI_begin_getLocator(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLocator(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getLocator(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLocator(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLocator(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLocator(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLocator(context, cb, cookie); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLocator(const ::Ice::Callback_LocatorFinder_getLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLocator(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLocator(const ::Ice::Context& context, const ::Ice::Callback_LocatorFinder_getLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLocator(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getLocator. + * @param result The asynchronous result object for the invocation. + * @return The locator proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::LocatorPrx end_getLocator(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getLocator(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace Ice +{ + +/** + * The Ice locator interface. This interface is used by clients to + * lookup adapters and objects. It is also used by servers to get the + * locator registry proxy. + * + *

The {@link Locator} interface is intended to be used by + * Ice internals and by locator implementations. Regular user code + * should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_API Locator : public virtual Object +{ +public: + + typedef LocatorPrx ProxyType; + typedef LocatorPtr PointerType; + + virtual ~Locator(); + +#ifdef ICE_CPP11_COMPILER + Locator() = default; + Locator(const Locator&) = default; + Locator& operator=(const Locator&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Find an object by identity and return a proxy that contains + * the adapter ID or endpoints which can be used to access the + * object. + * @param cb The AMD callback object for the invocation. + * @param id The identity. + * @param current The Current object for the invocation. + * @throws Ice::ObjectNotFoundException Raised if the object cannot + * be found. + */ + virtual void findObjectById_async(const ::Ice::AMD_Locator_findObjectByIdPtr& cb, const Identity& id, const Current& current = emptyCurrent) const = 0; + /// \cond INTERNAL + bool _iceD_findObjectById(::IceInternal::Incoming&, const ::Ice::Current&) const; + /// \endcond + + /** + * Find an adapter by id and return a proxy that contains + * its endpoints. + * @param cb The AMD callback object for the invocation. + * @param id The adapter id. + * @param current The Current object for the invocation. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot be + * found. + */ + virtual void findAdapterById_async(const ::Ice::AMD_Locator_findAdapterByIdPtr& cb, const ::std::string& id, const Current& current = emptyCurrent) const = 0; + /// \cond INTERNAL + bool _iceD_findAdapterById(::IceInternal::Incoming&, const ::Ice::Current&) const; + /// \endcond + + /** + * Get the locator registry. + * @param current The Current object for the invocation. + * @return The locator registry. + */ + virtual LocatorRegistryPrx getRegistry(const Current& current = emptyCurrent) const = 0; + /// \cond INTERNAL + bool _iceD_getRegistry(::IceInternal::Incoming&, const ::Ice::Current&) const; + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const Locator& lhs, const Locator& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Locator& lhs, const Locator& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The Ice locator registry interface. This interface is used by + * servers to register adapter endpoints with the locator. + * + *

The {@link LocatorRegistry} interface is intended to be used + * by Ice internals and by locator implementations. Regular user + * code should not attempt to use any functionality of this interface + * directly. + * \headerfile Ice/Ice.h + */ +class ICE_API LocatorRegistry : public virtual Object +{ +public: + + typedef LocatorRegistryPrx ProxyType; + typedef LocatorRegistryPtr PointerType; + + virtual ~LocatorRegistry(); + +#ifdef ICE_CPP11_COMPILER + LocatorRegistry() = default; + LocatorRegistry(const LocatorRegistry&) = default; + LocatorRegistry& operator=(const LocatorRegistry&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Set the adapter endpoints with the locator registry. + * @param cb The AMD callback object for the invocation. + * @param id The adapter id. + * @param proxy The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param current The Current object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows + * registered adapters to set their active proxy and the + * adapter is not registered with the locator. + */ + virtual void setAdapterDirectProxy_async(const ::Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb, const ::std::string& id, const ObjectPrx& proxy, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_setAdapterDirectProxy(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Set the adapter endpoints with the locator registry. + * @param cb The AMD callback object for the invocation. + * @param adapterId The adapter id. + * @param replicaGroupId The replica group id. + * @param p The adapter proxy (a dummy direct proxy created + * by the adapter). The direct proxy contains the adapter + * endpoints. + * @param current The Current object for the invocation. + * @throws Ice::AdapterAlreadyActiveException Raised if an adapter with the same + * id is already active. + * @throws Ice::AdapterNotFoundException Raised if the adapter cannot + * be found, or if the locator only allows registered adapters to + * set their active proxy and the adapter is not registered with + * the locator. + * @throws Ice::InvalidReplicaGroupIdException Raised if the given + * replica group doesn't match the one registered with the + * locator registry for this object adapter. + */ + virtual void setReplicatedAdapterDirectProxy_async(const ::Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxyPtr& cb, const ::std::string& adapterId, const ::std::string& replicaGroupId, const ObjectPrx& p, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_setReplicatedAdapterDirectProxy(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Set the process proxy for a server. + * @param cb The AMD callback object for the invocation. + * @param id The server id. + * @param proxy The process proxy. + * @param current The Current object for the invocation. + * @throws Ice::ServerNotFoundException Raised if the server cannot + * be found. + */ + virtual void setServerProcessProxy_async(const ::Ice::AMD_LocatorRegistry_setServerProcessProxyPtr& cb, const ::std::string& id, const ProcessPrx& proxy, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_setServerProcessProxy(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const LocatorRegistry& lhs, const LocatorRegistry& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const LocatorRegistry& lhs, const LocatorRegistry& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * This inferface should be implemented by services implementing the + * Ice::Locator interface. It should be advertised through an Ice + * object with the identity `Ice/LocatorFinder'. This allows clients + * to retrieve the locator proxy with just the endpoint information of + * the service. + * \headerfile Ice/Ice.h + */ +class ICE_API LocatorFinder : public virtual Object +{ +public: + + typedef LocatorFinderPrx ProxyType; + typedef LocatorFinderPtr PointerType; + + virtual ~LocatorFinder(); + +#ifdef ICE_CPP11_COMPILER + LocatorFinder() = default; + LocatorFinder(const LocatorFinder&) = default; + LocatorFinder& operator=(const LocatorFinder&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the locator proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param current The Current object for the invocation. + * @return The locator proxy. + */ + virtual LocatorPrx getLocator(const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getLocator(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const LocatorFinder& lhs, const LocatorFinder& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const LocatorFinder& lhs, const LocatorFinder& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::AdapterNotFoundException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +template<> +struct StreamableTraits< ::Ice::InvalidReplicaGroupIdException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +template<> +struct StreamableTraits< ::Ice::AdapterAlreadyActiveException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +template<> +struct StreamableTraits< ::Ice::ObjectNotFoundException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +template<> +struct StreamableTraits< ::Ice::ServerNotFoundException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +} +/// \endcond + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Locator::begin_findObjectById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findObjectById. + */ +template +class CallbackNC_Locator_findObjectById : public Callback_Locator_findObjectById_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ObjectPrx&); + + CallbackNC_Locator_findObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_findObjectById(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findObjectById. + */ +template Callback_Locator_findObjectByIdPtr +newCallback_Locator_findObjectById(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findObjectById. + */ +template Callback_Locator_findObjectByIdPtr +newCallback_Locator_findObjectById(T* instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Locator::begin_findObjectById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findObjectById. + */ +template +class Callback_Locator_findObjectById : public Callback_Locator_findObjectById_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ObjectPrx&, const CT&); + + Callback_Locator_findObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_findObjectById(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findObjectById. + */ +template Callback_Locator_findObjectByIdPtr +newCallback_Locator_findObjectById(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findObjectById. + */ +template Callback_Locator_findObjectByIdPtr +newCallback_Locator_findObjectById(T* instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Locator::begin_findAdapterById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findAdapterById. + */ +template +class CallbackNC_Locator_findAdapterById : public Callback_Locator_findAdapterById_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ObjectPrx&); + + CallbackNC_Locator_findAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_findAdapterById(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findAdapterById. + */ +template Callback_Locator_findAdapterByIdPtr +newCallback_Locator_findAdapterById(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findAdapterById. + */ +template Callback_Locator_findAdapterByIdPtr +newCallback_Locator_findAdapterById(T* instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Locator::begin_findAdapterById. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_findAdapterById. + */ +template +class Callback_Locator_findAdapterById : public Callback_Locator_findAdapterById_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ObjectPrx&, const CT&); + + Callback_Locator_findAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_findAdapterById(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findAdapterById. + */ +template Callback_Locator_findAdapterByIdPtr +newCallback_Locator_findAdapterById(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_findAdapterById. + */ +template Callback_Locator_findAdapterByIdPtr +newCallback_Locator_findAdapterById(T* instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Locator::begin_getRegistry. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_getRegistry. + */ +template +class CallbackNC_Locator_getRegistry : public Callback_Locator_getRegistry_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const LocatorRegistryPrx&); + + CallbackNC_Locator_getRegistry(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + LocatorRegistryPrx ret; + try + { + ret = proxy->end_getRegistry(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_getRegistry. + */ +template Callback_Locator_getRegistryPtr +newCallback_Locator_getRegistry(const IceUtil::Handle& instance, void (T::*cb)(const LocatorRegistryPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_getRegistry(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_getRegistry. + */ +template Callback_Locator_getRegistryPtr +newCallback_Locator_getRegistry(T* instance, void (T::*cb)(const LocatorRegistryPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Locator_getRegistry(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Locator::begin_getRegistry. + * Create a wrapper instance by calling ::Ice::newCallback_Locator_getRegistry. + */ +template +class Callback_Locator_getRegistry : public Callback_Locator_getRegistry_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const LocatorRegistryPrx&, const CT&); + + Callback_Locator_getRegistry(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorPrx proxy = LocatorPrx::uncheckedCast(result->getProxy()); + LocatorRegistryPrx ret; + try + { + ret = proxy->end_getRegistry(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_getRegistry. + */ +template Callback_Locator_getRegistryPtr +newCallback_Locator_getRegistry(const IceUtil::Handle& instance, void (T::*cb)(const LocatorRegistryPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_getRegistry(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Locator::begin_getRegistry. + */ +template Callback_Locator_getRegistryPtr +newCallback_Locator_getRegistry(T* instance, void (T::*cb)(const LocatorRegistryPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Locator_getRegistry(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setAdapterDirectProxy. + */ +template +class CallbackNC_LocatorRegistry_setAdapterDirectProxy : public Callback_LocatorRegistry_setAdapterDirectProxy_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LocatorRegistry_setAdapterDirectProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setAdapterDirectProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setAdapterDirectProxy. + */ +template +class Callback_LocatorRegistry_setAdapterDirectProxy : public Callback_LocatorRegistry_setAdapterDirectProxy_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LocatorRegistry_setAdapterDirectProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setAdapterDirectProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setAdapterDirectProxyPtr +newCallback_LocatorRegistry_setAdapterDirectProxy(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy. + */ +template +class CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy : public Callback_LocatorRegistry_setReplicatedAdapterDirectProxy_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setReplicatedAdapterDirectProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy. + */ +template +class Callback_LocatorRegistry_setReplicatedAdapterDirectProxy : public Callback_LocatorRegistry_setReplicatedAdapterDirectProxy_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LocatorRegistry_setReplicatedAdapterDirectProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setReplicatedAdapterDirectProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setReplicatedAdapterDirectProxy. + */ +template Callback_LocatorRegistry_setReplicatedAdapterDirectProxyPtr +newCallback_LocatorRegistry_setReplicatedAdapterDirectProxy(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setReplicatedAdapterDirectProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setServerProcessProxy. + */ +template +class CallbackNC_LocatorRegistry_setServerProcessProxy : public Callback_LocatorRegistry_setServerProcessProxy_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LocatorRegistry_setServerProcessProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setServerProcessProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setServerProcessProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setServerProcessProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setServerProcessProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorRegistry_setServerProcessProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorRegistry_setServerProcessProxy. + */ +template +class Callback_LocatorRegistry_setServerProcessProxy : public Callback_LocatorRegistry_setServerProcessProxy_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LocatorRegistry_setServerProcessProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorRegistryPrx proxy = LocatorRegistryPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_setServerProcessProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setServerProcessProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setServerProcessProxy(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setServerProcessProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorRegistry::begin_setServerProcessProxy. + */ +template Callback_LocatorRegistry_setServerProcessProxyPtr +newCallback_LocatorRegistry_setServerProcessProxy(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorRegistry_setServerProcessProxy(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LocatorFinder::begin_getLocator. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorFinder_getLocator. + */ +template +class CallbackNC_LocatorFinder_getLocator : public Callback_LocatorFinder_getLocator_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const LocatorPrx&); + + CallbackNC_LocatorFinder_getLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorFinderPrx proxy = LocatorFinderPrx::uncheckedCast(result->getProxy()); + LocatorPrx ret; + try + { + ret = proxy->end_getLocator(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorFinder::begin_getLocator. + */ +template Callback_LocatorFinder_getLocatorPtr +newCallback_LocatorFinder_getLocator(const IceUtil::Handle& instance, void (T::*cb)(const LocatorPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorFinder_getLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorFinder::begin_getLocator. + */ +template Callback_LocatorFinder_getLocatorPtr +newCallback_LocatorFinder_getLocator(T* instance, void (T::*cb)(const LocatorPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LocatorFinder_getLocator(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LocatorFinder::begin_getLocator. + * Create a wrapper instance by calling ::Ice::newCallback_LocatorFinder_getLocator. + */ +template +class Callback_LocatorFinder_getLocator : public Callback_LocatorFinder_getLocator_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const LocatorPrx&, const CT&); + + Callback_LocatorFinder_getLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LocatorFinderPrx proxy = LocatorFinderPrx::uncheckedCast(result->getProxy()); + LocatorPrx ret; + try + { + ret = proxy->end_getLocator(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorFinder::begin_getLocator. + */ +template Callback_LocatorFinder_getLocatorPtr +newCallback_LocatorFinder_getLocator(const IceUtil::Handle& instance, void (T::*cb)(const LocatorPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorFinder_getLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LocatorFinder::begin_getLocator. + */ +template Callback_LocatorFinder_getLocatorPtr +newCallback_LocatorFinder_getLocator(T* instance, void (T::*cb)(const LocatorPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LocatorFinder_getLocator(instance, cb, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/LocatorF.h b/Sources/IceCpp/include/Ice/LocatorF.h new file mode 100644 index 0000000..351e57d --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocatorF.h @@ -0,0 +1,147 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_LocatorF_h__ +#define __Ice_LocatorF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Locator; +class LocatorPrx; +class LocatorRegistry; +class LocatorRegistryPrx; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using LocatorPtr = ::std::shared_ptr; +using LocatorPrxPtr = ::std::shared_ptr; + +using LocatorRegistryPtr = ::std::shared_ptr; +using LocatorRegistryPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class Locator; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Locator>&); +ICE_API ::IceProxy::Ice::Object* upCast(Locator*); +/// \endcond + +class LocatorRegistry; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LocatorRegistry>&); +ICE_API ::IceProxy::Ice::Object* upCast(LocatorRegistry*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Locator; +/// \cond INTERNAL +ICE_API Object* upCast(Locator*); +/// \endcond +typedef ::IceInternal::Handle< Locator> LocatorPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Locator> LocatorPrx; +typedef LocatorPrx LocatorPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LocatorPtr&, const ObjectPtr&); +/// \endcond + +class LocatorRegistry; +/// \cond INTERNAL +ICE_API Object* upCast(LocatorRegistry*); +/// \endcond +typedef ::IceInternal::Handle< LocatorRegistry> LocatorRegistryPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::LocatorRegistry> LocatorRegistryPrx; +typedef LocatorRegistryPrx LocatorRegistryPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LocatorRegistryPtr&, const ObjectPtr&); +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/LocatorInfo.h b/Sources/IceCpp/include/Ice/LocatorInfo.h new file mode 100644 index 0000000..b156c46 --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocatorInfo.h @@ -0,0 +1,189 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOCATOR_INFO_H +#define ICE_LOCATOR_INFO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace IceInternal +{ + +class LocatorManager : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + LocatorManager(const Ice::PropertiesPtr&); + + void destroy(); + + // + // Returns locator info for a given locator. Automatically creates + // the locator info if it doesn't exist yet. + // + LocatorInfoPtr get(const Ice::LocatorPrxPtr&); + +private: + + const bool _background; + +#ifdef ICE_CPP11_MAPPING + using LocatorInfoTable = std::map, + LocatorInfoPtr, + Ice::TargetCompare, std::less>>; +#else + typedef std::map LocatorInfoTable; +#endif + LocatorInfoTable _table; + LocatorInfoTable::iterator _tableHint; + + std::map, LocatorTablePtr> _locatorTables; +}; + +class LocatorTable : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + LocatorTable(); + + void clear(); + + bool getAdapterEndpoints(const std::string&, int, ::std::vector&); + void addAdapterEndpoints(const std::string&, const ::std::vector&); + ::std::vector removeAdapterEndpoints(const std::string&); + + bool getObjectReference(const Ice::Identity&, int, ReferencePtr&); + void addObjectReference(const Ice::Identity&, const ReferencePtr&); + ReferencePtr removeObjectReference(const Ice::Identity&); + +private: + + bool checkTTL(const IceUtil::Time&, int) const; + + std::map > > _adapterEndpointsMap; + std::map > _objectMap; +}; + +class LocatorInfo : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + class GetEndpointsCallback : public virtual IceUtil::Shared + { + public: + + virtual void setEndpoints(const std::vector&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle GetEndpointsCallbackPtr; + + class RequestCallback : public virtual IceUtil::Shared + { + public: + + RequestCallback(const ReferencePtr&, int, const GetEndpointsCallbackPtr&); + + void response(const LocatorInfoPtr&, const Ice::ObjectPrxPtr&); + void exception(const LocatorInfoPtr&, const Ice::Exception&); + + private: + + const ReferencePtr _reference; + const int _ttl; + const GetEndpointsCallbackPtr _callback; + }; + typedef IceUtil::Handle RequestCallbackPtr; + + class Request : public virtual IceUtil::Shared + { + public: + + void addCallback(const ReferencePtr&, const ReferencePtr&, int, const GetEndpointsCallbackPtr&); + + void response(const Ice::ObjectPrxPtr&); + void exception(const Ice::Exception&); + + protected: + + Request(const LocatorInfoPtr&, const ReferencePtr&); + + virtual void send() = 0; + + const LocatorInfoPtr _locatorInfo; + const ReferencePtr _reference; + + private: + + IceUtil::Monitor _monitor; + std::vector _callbacks; + std::vector _wellKnownRefs; + bool _sent; + bool _response; + Ice::ObjectPrxPtr _proxy; + IceInternal::UniquePtr _exception; + }; + typedef IceUtil::Handle RequestPtr; + + LocatorInfo(const Ice::LocatorPrxPtr&, const LocatorTablePtr&, bool); + + void destroy(); + + bool operator==(const LocatorInfo&) const; + bool operator<(const LocatorInfo&) const; + + const Ice::LocatorPrxPtr& getLocator() const + { + // + // No mutex lock necessary, _locator is immutable. + // + return _locator; + } + Ice::LocatorRegistryPrxPtr getLocatorRegistry(); + + void getEndpoints(const ReferencePtr& ref, int ttl, const GetEndpointsCallbackPtr& cb) + { + getEndpoints(ref, 0, ttl, cb); + } + void getEndpoints(const ReferencePtr&, const ReferencePtr&, int, const GetEndpointsCallbackPtr&); + + void clearCache(const ReferencePtr&); + +private: + + void getEndpointsException(const ReferencePtr&, const Ice::Exception&); + void getEndpointsTrace(const ReferencePtr&, const std::vector&, bool); + void trace(const std::string&, const ReferencePtr&, const std::vector&); + void trace(const std::string&, const ReferencePtr&, const ReferencePtr&); + + RequestPtr getAdapterRequest(const ReferencePtr&); + RequestPtr getObjectRequest(const ReferencePtr&); + + void finishRequest(const ReferencePtr&, const std::vector&, const Ice::ObjectPrxPtr&, bool); + friend class Request; + friend class RequestCallback; + + const Ice::LocatorPrxPtr _locator; + Ice::LocatorRegistryPrxPtr _locatorRegistry; + const LocatorTablePtr _table; + const bool _background; + + std::map _adapterRequests; + std::map _objectRequests; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/LocatorInfoF.h b/Sources/IceCpp/include/Ice/LocatorInfoF.h new file mode 100644 index 0000000..fd689ce --- /dev/null +++ b/Sources/IceCpp/include/Ice/LocatorInfoF.h @@ -0,0 +1,29 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOCATOR_INFO_F_H +#define ICE_LOCATOR_INFO_F_H + +#include + +#include + +namespace IceInternal +{ + +class LocatorManager; +IceUtil::Shared* upCast(LocatorManager*); +typedef Handle LocatorManagerPtr; + +class LocatorInfo; +IceUtil::Shared* upCast(LocatorInfo*); +typedef Handle LocatorInfoPtr; + +class LocatorTable; +IceUtil::Shared* upCast(LocatorTable*); +typedef Handle LocatorTablePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Logger.h b/Sources/IceCpp/include/Ice/Logger.h new file mode 100644 index 0000000..c438b9e --- /dev/null +++ b/Sources/IceCpp/include/Ice/Logger.h @@ -0,0 +1,237 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Logger.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Logger_h__ +#define __Ice_Logger_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Logger; + +} + +namespace Ice +{ + +/** + * The Ice message logger. Applications can provide their own logger + * by implementing this interface and installing it in a communicator. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Logger +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Logger(); + + /** + * Print a message. The message is printed literally, without + * any decorations such as executable name or time stamp. + * @param message The message to log. + */ + virtual void print(const ::std::string& message) = 0; + + /** + * Log a trace message. + * @param category The trace category. + * @param message The trace message to log. + */ + virtual void trace(const ::std::string& category, const ::std::string& message) = 0; + + /** + * Log a warning message. + * @param message The warning message to log. + * @see #error + */ + virtual void warning(const ::std::string& message) = 0; + + /** + * Log an error message. + * @param message The error message to log. + * @see #warning + */ + virtual void error(const ::std::string& message) = 0; + + /** + * Returns this logger's prefix. + * @return The prefix. + */ + virtual ::std::string getPrefix() = 0; + + /** + * Returns a clone of the logger with a new prefix. + * @param prefix The new prefix for the logger. + * @return A logger instance. + */ + virtual ::std::shared_ptr<::Ice::Logger> cloneWithPrefix(const ::std::string& prefix) = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using LoggerPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class Logger; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Logger*); +/// \endcond +typedef ::IceInternal::Handle< Logger> LoggerPtr; + +} + +namespace Ice +{ + +/** + * The Ice message logger. Applications can provide their own logger + * by implementing this interface and installing it in a communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API Logger : public virtual LocalObject +{ +public: + + typedef LoggerPtr PointerType; + + virtual ~Logger(); + +#ifdef ICE_CPP11_COMPILER + Logger() = default; + Logger(const Logger&) = default; + Logger& operator=(const Logger&) = default; +#endif + + /** + * Print a message. The message is printed literally, without + * any decorations such as executable name or time stamp. + * @param message The message to log. + */ + virtual void print(const ::std::string& message) = 0; + + /** + * Log a trace message. + * @param category The trace category. + * @param message The trace message to log. + */ + virtual void trace(const ::std::string& category, const ::std::string& message) = 0; + + /** + * Log a warning message. + * @param message The warning message to log. + * @see #error + */ + virtual void warning(const ::std::string& message) = 0; + + /** + * Log an error message. + * @param message The error message to log. + * @see #warning + */ + virtual void error(const ::std::string& message) = 0; + + /** + * Returns this logger's prefix. + * @return The prefix. + */ + virtual ::std::string getPrefix() = 0; + + /** + * Returns a clone of the logger with a new prefix. + * @param prefix The new prefix for the logger. + * @return A logger instance. + */ + virtual LoggerPtr cloneWithPrefix(const ::std::string& prefix) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Logger& lhs, const Logger& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Logger& lhs, const Logger& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/LoggerAdminI.h b/Sources/IceCpp/include/Ice/LoggerAdminI.h new file mode 100644 index 0000000..f697fb2 --- /dev/null +++ b/Sources/IceCpp/include/Ice/LoggerAdminI.h @@ -0,0 +1,41 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOGGER_ADMIN_I_H +#define ICE_LOGGER_ADMIN_I_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +// +// A logger that works in tandem with a "Logger" admin facet. +// +class LoggerAdminLogger : public Ice::Logger +{ +public: + + // + // Return the associated Admin facet + // + virtual Ice::ObjectPtr getFacet() const = 0; + + // + // Destroy this logger, in particular join any thread + // that this logger may have started + // + virtual void destroy() = 0; +}; +ICE_DEFINE_PTR(LoggerAdminLoggerPtr, LoggerAdminLogger); + +LoggerAdminLoggerPtr +createLoggerAdminLogger(const Ice::PropertiesPtr&, const Ice::LoggerPtr&); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/LoggerF.h b/Sources/IceCpp/include/Ice/LoggerF.h new file mode 100644 index 0000000..69e3c1d --- /dev/null +++ b/Sources/IceCpp/include/Ice/LoggerF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `LoggerF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_LoggerF_h__ +#define __Ice_LoggerF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Logger; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using LoggerPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class Logger; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Logger*); +/// \endcond +typedef ::IceInternal::Handle< Logger> LoggerPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/LoggerI.h b/Sources/IceCpp/include/Ice/LoggerI.h new file mode 100644 index 0000000..0a48c29 --- /dev/null +++ b/Sources/IceCpp/include/Ice/LoggerI.h @@ -0,0 +1,52 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOGGER_I_H +#define ICE_LOGGER_I_H + +#include +#include +#include + +namespace Ice +{ + +class LoggerI : public Logger +{ +public: + + LoggerI(const std::string&, const std::string&, bool convert = true, std::size_t sizeMax = 0); + ~LoggerI(); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual LoggerPtr cloneWithPrefix(const std::string&); + +private: + + void write(const std::string&, bool); + + const std::string _prefix; + std::string _formattedPrefix; + const bool _convert; + const StringConverterPtr _converter; + std::ofstream _out; + + std::string _file; + std::size_t _sizeMax; + + // + // In case of a log file rename failure is set to the time in milliseconds + // after which rename could be attempted again. Otherwise is set to zero. + // + IceUtil::Time _nextRetry; +}; +ICE_DEFINE_PTR(LoggerIPtr, LoggerI); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/LoggerUtil.h b/Sources/IceCpp/include/Ice/LoggerUtil.h new file mode 100644 index 0000000..8696a75 --- /dev/null +++ b/Sources/IceCpp/include/Ice/LoggerUtil.h @@ -0,0 +1,185 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_LOGGER_UTIL_H +#define ICE_LOGGER_UTIL_H + +#include +#include +#include +#include + +namespace Ice +{ + +/** + * Base class for logger output utility classes. + * \headerfile Ice/Ice.h + */ +class ICE_API LoggerOutputBase : private IceUtil::noncopyable +{ +public: + + /** Obtains the collected output. */ + std::string str() const; + + /// \cond INTERNAL + std::ostringstream& _stream(); // For internal use only. Don't use in your code. + /// \endcond + +private: + + std::ostringstream _os; +}; + +/// \cond INTERNAL +ICE_API LoggerOutputBase& loggerInsert(LoggerOutputBase& out, const IceUtil::Exception& ex); + +template +struct IsException +{ + static char testex(IceUtil::Exception*); + static long testex(...); + + static const bool value = sizeof(testex(static_cast(0))) == sizeof(char); +}; + +template +struct LoggerOutputInserter +{ + static inline LoggerOutputBase& + insert(LoggerOutputBase& out, const T& val) + { + out._stream() << val; + return out; + } +}; + +// Partial specialization +template +struct LoggerOutputInserter +{ + static inline LoggerOutputBase& + insert(LoggerOutputBase& out, const T& ex) + { + return loggerInsert(out, ex); + } +}; + +template +inline LoggerOutputBase& +operator<<(LoggerOutputBase& out, const T& val) +{ + return LoggerOutputInserter::value>::insert(out, val); +} + +#ifdef ICE_CPP11_MAPPING +template::value>::type* = nullptr> +inline LoggerOutputBase& +operator<<(LoggerOutputBase& os, const ::std::shared_ptr& p) +#else +template +inline LoggerOutputBase& +operator<<(LoggerOutputBase& os, const ::IceInternal::ProxyHandle& p) +#endif +{ + return os << (p ? p->ice_toString() : ""); +} + +inline LoggerOutputBase& +operator<<(LoggerOutputBase& out, const ::std::exception& ex) +{ + out._stream() << ex.what(); + return out; +} + +ICE_API LoggerOutputBase& operator<<(LoggerOutputBase&, std::ios_base& (*)(std::ios_base&)); +/// \endcond + +/** + * Collects output and flushes it via a logger method. + * \headerfile Ice/Ice.h + */ +template +class LoggerOutput : public LoggerOutputBase +{ +public: + inline LoggerOutput(const LPtr& lptr) : + _logger(lptr) + {} + + inline ~LoggerOutput() + { + flush(); + } + + /** Flushes the colleted output to the logger method. */ + inline void flush() + { + std::string s = _stream().str(); + if(!s.empty()) + { + L& ref = *_logger; + (ref.*output)(s); + } + _stream().str(""); + } + +private: + + LPtr _logger; +}; + +/** Flushes output to Logger::print. */ +typedef LoggerOutput Print; + +/** Flushes output to Logger::warning. */ +typedef LoggerOutput Warning; + +/** Flushes output to Logger::error. */ +typedef LoggerOutput Error; + +/** + * Flushes output to Logger::trace. + * \headerfile Ice/Ice.h + */ +class ICE_API Trace : public LoggerOutputBase +{ +public: + Trace(const LoggerPtr&, const std::string&); + ~Trace(); + void flush(); + +private: + + LoggerPtr _logger; + std::string _category; +}; + +/** + * A special plug-in that installs a logger during a communicator's initialization. + * Both initialize and destroy are no-op. See Ice::InitializationData. + * \headerfile Ice/Ice.h + */ +class ICE_API LoggerPlugin : public Ice::Plugin +{ +public: + + /** + * Constructs the plug-in with a target communicator and a logger. + * @param communicator The communicator in which to install the logger. + * @param logger The logger to be installed. + */ + LoggerPlugin(const CommunicatorPtr& communicator, const LoggerPtr& logger); + + /** This method is a no-op. */ + virtual void initialize(); + + /** This method is a no-op. */ + virtual void destroy(); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Metrics.h b/Sources/IceCpp/include/Ice/Metrics.h new file mode 100644 index 0000000..5830cc2 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Metrics.h @@ -0,0 +1,4769 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Metrics.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Metrics_h__ +#define __Ice_Metrics_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceMX +{ + +class Metrics; +class MetricsAdmin; +class MetricsAdminPrx; +class ThreadMetrics; +class DispatchMetrics; +class ChildInvocationMetrics; +class CollocatedMetrics; +class RemoteMetrics; +class InvocationMetrics; +class ConnectionMetrics; + +} + +namespace IceMX +{ + +/** + * A dictionnary of strings to integers. + */ +using StringIntDict = ::std::map<::std::string, int>; + +/** + * A structure to keep track of failures associated with a given + * metrics. + * \headerfile Ice/Ice.h + */ +struct MetricsFailures +{ + /** + * The identifier of the metrics object associated to the + * failures. + */ + ::std::string id; + /** + * The failures observed for this metrics. + */ + ::IceMX::StringIntDict failures; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, failures); + } +}; + +/** + * A sequence of {@link MetricsFailures}. + */ +using MetricsFailuresSeq = ::std::vector; + +/** + * A metrics map is a sequence of metrics. We use a sequence here + * instead of a map because the ID of the metrics is already included + * in the Metrics class and using sequences of metrics objects is more + * efficient than using dictionaries since lookup is not necessary. + */ +using MetricsMap = ::std::vector<::std::shared_ptr>; + +/** + * A metrics view is a dictionary of metrics map. The key of the + * dictionary is the name of the metrics map. + */ +using MetricsView = ::std::map<::std::string, MetricsMap>; + +/** + * Raised if a metrics view cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) UnknownMetricsView : public ::Ice::UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~UnknownMetricsView(); + + UnknownMetricsView(const UnknownMetricsView&) = default; + + UnknownMetricsView() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/// \cond INTERNAL +static UnknownMetricsView _iceS_UnknownMetricsView_init; +/// \endcond + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +namespace IceMX +{ + +/** + * The metrics administrative facet interface. This interface allows + * remote administrative clients to access metrics of an application + * that enabled the Ice administrative facility and configured some + * metrics views. + * \headerfile Ice/Ice.h + */ +class ICE_API MetricsAdmin : public virtual ::Ice::Object +{ +public: + + using ProxyType = MetricsAdminPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const ::Ice::Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const ::Ice::Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Encapsulates the results of a call to getMetricsViewNames. + */ + struct GetMetricsViewNamesResult + { + /** The name of the enabled views. */ + ::Ice::StringSeq returnValue; + /** The names of the disabled views. */ + ::Ice::StringSeq disabledViews; + }; + + /** + * Get the names of enabled and disabled metrics. + * @param disabledViews The names of the disabled views. + * @param current The Current object for the invocation. + * @return The name of the enabled views. + */ + virtual ::Ice::StringSeq getMetricsViewNames(::Ice::StringSeq& disabledViews, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsViewNames(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param current The Current object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual void enableMetricsView(::std::string name, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_enableMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param current The Current object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual void disableMetricsView(::std::string name, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_disableMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Encapsulates the results of a call to getMetricsView. + */ + struct GetMetricsViewResult + { + /** The metrics view data. */ + MetricsView returnValue; + /** The local time of the process when the metrics object were retrieved. */ + long long int timestamp; + }; + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param timestamp The local time of the process when the metrics + * object were retrieved. + * @param current The Current object for the invocation. + * @return The metrics view data. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsView getMetricsView(::std::string view, long long int& timestamp, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param current The Current object for the invocation. + * @return The metrics failures associated with the map. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsFailuresSeq getMapMetricsFailures(::std::string view, ::std::string map, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getMapMetricsFailures(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param current The Current object for the invocation. + * @return The metrics failures associated with the metrics. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsFailures getMetricsFailures(::std::string view, ::std::string map, ::std::string id, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsFailures(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override; + /// \endcond +}; + +} + +namespace IceMX +{ + +/** + * The base class for metrics. A metrics object represents a + * collection of measurements associated to a given a system. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Metrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Metrics(); + + Metrics() = default; + + Metrics(const Metrics&) = default; + Metrics(Metrics&&) = default; + Metrics& operator=(const Metrics&) = default; + Metrics& operator=(Metrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + */ + Metrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures) : + id(id), + total(total), + current(current), + totalLifetime(totalLifetime), + failures(failures) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The metrics identifier. + */ + ::std::string id; + /** + * The total number of objects observed by this metrics. This includes + * the number of currently observed objects and the number of objects + * observed in the past. + */ + long long int total = 0LL; + /** + * The number of objects currently observed by this metrics. + */ + int current = 0; + /** + * The sum of the lifetime of each observed objects. This does not + * include the lifetime of objects which are currently observed, + * only the objects observed in the past. + */ + long long int totalLifetime = 0LL; + /** + * The number of failures observed. + */ + int failures = 0; +}; + +/// \cond INTERNAL +static Metrics _iceS_Metrics_init; +/// \endcond + +/** + * Provides information on the number of threads currently in use and + * their activity. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ThreadMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ThreadMetrics(); + + ThreadMetrics() = default; + + ThreadMetrics(const ThreadMetrics&) = default; + ThreadMetrics(ThreadMetrics&&) = default; + ThreadMetrics& operator=(const ThreadMetrics&) = default; + ThreadMetrics& operator=(ThreadMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param inUseForIO The number of threads which are currently performing socket read or writes. + * @param inUseForUser The number of threads which are currently calling user code (servant dispatch, AMI callbacks, etc). + * @param inUseForOther The number of threads which are currently performing other activities. + */ + ThreadMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, int inUseForIO, int inUseForUser, int inUseForOther) : + Ice::ValueHelper(id, total, current, totalLifetime, failures), + inUseForIO(inUseForIO), + inUseForUser(inUseForUser), + inUseForOther(inUseForOther) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, inUseForIO, inUseForUser, inUseForOther); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The number of threads which are currently performing socket + * read or writes. + */ + int inUseForIO = 0; + /** + * The number of threads which are currently calling user code + * (servant dispatch, AMI callbacks, etc). + */ + int inUseForUser = 0; + /** + * The number of threads which are currently performing other + * activities. These are all other that are not counted with + * {@link #inUseForUser} or {@link #inUseForIO}, such as DNS + * lookups, garbage collection). + */ + int inUseForOther = 0; +}; + +/** + * Provides information on servant dispatch. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) DispatchMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~DispatchMetrics(); + + DispatchMetrics() = default; + + DispatchMetrics(const DispatchMetrics&) = default; + DispatchMetrics(DispatchMetrics&&) = default; + DispatchMetrics& operator=(const DispatchMetrics&) = default; + DispatchMetrics& operator=(DispatchMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param userException The number of dispatch that failed with a user exception. + * @param size The size of the dispatch. + * @param replySize The size of the dispatch reply. + */ + DispatchMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, int userException, long long int size, long long int replySize) : + Ice::ValueHelper(id, total, current, totalLifetime, failures), + userException(userException), + size(size), + replySize(replySize) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, userException, size, replySize); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The number of dispatch that failed with a user exception. + */ + int userException = 0; + /** + * The size of the dispatch. This corresponds to the size of the + * marshalled input parameters. + */ + long long int size = 0LL; + /** + * The size of the dispatch reply. This corresponds to the size of + * the marshalled output and return parameters. + */ + long long int replySize = 0LL; +}; + +/** + * Provides information on child invocations. A child invocation is + * either remote (sent over an Ice connection) or collocated. An + * invocation can have multiple child invocation if it is + * retried. Child invocation metrics are embedded within + * {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ChildInvocationMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ChildInvocationMetrics(); + + ChildInvocationMetrics() = default; + + ChildInvocationMetrics(const ChildInvocationMetrics&) = default; + ChildInvocationMetrics(ChildInvocationMetrics&&) = default; + ChildInvocationMetrics& operator=(const ChildInvocationMetrics&) = default; + ChildInvocationMetrics& operator=(ChildInvocationMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + ChildInvocationMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, long long int size, long long int replySize) : + Ice::ValueHelper(id, total, current, totalLifetime, failures), + size(size), + replySize(replySize) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, size, replySize); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The size of the invocation. This corresponds to the size of the + * marshalled input parameters. + */ + long long int size = 0LL; + /** + * The size of the invocation reply. This corresponds to the size + * of the marshalled output and return parameters. + */ + long long int replySize = 0LL; +}; + +/** + * Provides information on invocations that are collocated. Collocated + * metrics are embedded within {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) CollocatedMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~CollocatedMetrics(); + + CollocatedMetrics() = default; + + CollocatedMetrics(const CollocatedMetrics&) = default; + CollocatedMetrics(CollocatedMetrics&&) = default; + CollocatedMetrics& operator=(const CollocatedMetrics&) = default; + CollocatedMetrics& operator=(CollocatedMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + CollocatedMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, long long int size, long long int replySize) : + Ice::ValueHelper(id, total, current, totalLifetime, failures, size, replySize) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, size, replySize); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/** + * Provides information on invocations that are specifically sent over + * Ice connections. Remote metrics are embedded within {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RemoteMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~RemoteMetrics(); + + RemoteMetrics() = default; + + RemoteMetrics(const RemoteMetrics&) = default; + RemoteMetrics(RemoteMetrics&&) = default; + RemoteMetrics& operator=(const RemoteMetrics&) = default; + RemoteMetrics& operator=(RemoteMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + RemoteMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, long long int size, long long int replySize) : + Ice::ValueHelper(id, total, current, totalLifetime, failures, size, replySize) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, size, replySize); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/** + * Provide measurements for proxy invocations. Proxy invocations can + * either be sent over the wire or be collocated. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) InvocationMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~InvocationMetrics(); + + InvocationMetrics() = default; + + InvocationMetrics(const InvocationMetrics&) = default; + InvocationMetrics(InvocationMetrics&&) = default; + InvocationMetrics& operator=(const InvocationMetrics&) = default; + InvocationMetrics& operator=(InvocationMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param retry The number of retries for the invocation(s). + * @param userException The number of invocations that failed with a user exception. + * @param remotes The remote invocation metrics map. + * @param collocated The collocated invocation metrics map. + */ + InvocationMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, int retry, int userException, const ::IceMX::MetricsMap& remotes, const ::IceMX::MetricsMap& collocated) : + Ice::ValueHelper(id, total, current, totalLifetime, failures), + retry(retry), + userException(userException), + remotes(remotes), + collocated(collocated) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, retry, userException, remotes, collocated); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The number of retries for the invocation(s). + */ + int retry = 0; + /** + * The number of invocations that failed with a user exception. + */ + int userException = 0; + /** + * The remote invocation metrics map. + * @see RemoteMetrics + */ + ::IceMX::MetricsMap remotes; + /** + * The collocated invocation metrics map. + * @see CollocatedMetrics + */ + ::IceMX::MetricsMap collocated; +}; + +/** + * Provides information on the data sent and received over Ice + * connections. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ConnectionMetrics : public ::Ice::ValueHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ConnectionMetrics(); + + ConnectionMetrics() = default; + + ConnectionMetrics(const ConnectionMetrics&) = default; + ConnectionMetrics(ConnectionMetrics&&) = default; + ConnectionMetrics& operator=(const ConnectionMetrics&) = default; + ConnectionMetrics& operator=(ConnectionMetrics&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param receivedBytes The number of bytes received by the connection. + * @param sentBytes The number of bytes sent by the connection. + */ + ConnectionMetrics(const ::std::string& id, long long int total, int current, long long int totalLifetime, int failures, long long int receivedBytes, long long int sentBytes) : + Ice::ValueHelper(id, total, current, totalLifetime, failures), + receivedBytes(receivedBytes), + sentBytes(sentBytes) + { + } + + /** + * Obtains a tuple containing all of the value's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(id, total, current, totalLifetime, failures, receivedBytes, sentBytes); + } + + /** + * Obtains the Slice type ID of this value. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + + /** + * The number of bytes received by the connection. + */ + long long int receivedBytes = 0LL; + /** + * The number of bytes sent by the connection. + */ + long long int sentBytes = 0LL; +}; + +} + +namespace IceMX +{ + +/** + * The metrics administrative facet interface. This interface allows + * remote administrative clients to access metrics of an application + * that enabled the Ice administrative facility and configured some + * metrics views. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) MetricsAdminPrx : public virtual ::Ice::Proxy +{ +public: + + /** + * Get the names of enabled and disabled metrics. + * @param disabledViews The names of the disabled views. + * @param context The Context map to send with the invocation. + * @return The name of the enabled views. + */ + ::Ice::StringSeq getMetricsViewNames(::Ice::StringSeq& disabledViews, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + auto _result = _makePromiseOutgoing(true, this, &MetricsAdminPrx::_iceI_getMetricsViewNames, context).get(); + disabledViews = ::std::move(_result.disabledViews); + return ::std::move(_result.returnValue); + } + + /** + * Get the names of enabled and disabled metrics. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getMetricsViewNamesAsync(const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &MetricsAdminPrx::_iceI_getMetricsViewNames, context); + } + + /** + * Get the names of enabled and disabled metrics. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getMetricsViewNamesAsync(::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + auto _responseCb = [response](MetricsAdmin::GetMetricsViewNamesResult&& _result) + { + response(::std::move(_result.returnValue), ::std::move(_result.disabledViews)); + }; + return _makeLamdaOutgoing(std::move(_responseCb), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_getMetricsViewNames, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getMetricsViewNames(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::Ice::Context&); + /// \endcond + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + void enableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &MetricsAdminPrx::_iceI_enableMetricsView, name, context).get(); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto enableMetricsViewAsync(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &MetricsAdminPrx::_iceI_enableMetricsView, name, context); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + enableMetricsViewAsync(const ::std::string& name, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_enableMetricsView, name, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_enableMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + void disableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &MetricsAdminPrx::_iceI_disableMetricsView, name, context).get(); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto disableMetricsViewAsync(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &MetricsAdminPrx::_iceI_disableMetricsView, name, context); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + disableMetricsViewAsync(const ::std::string& name, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_disableMetricsView, name, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_disableMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param timestamp The local time of the process when the metrics + * object were retrieved. + * @param context The Context map to send with the invocation. + * @return The metrics view data. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + MetricsView getMetricsView(const ::std::string& view, long long int& timestamp, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + auto _result = _makePromiseOutgoing(true, this, &MetricsAdminPrx::_iceI_getMetricsView, view, context).get(); + timestamp = _result.timestamp; + return ::std::move(_result.returnValue); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getMetricsViewAsync(const ::std::string& view, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &MetricsAdminPrx::_iceI_getMetricsView, view, context); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getMetricsViewAsync(const ::std::string& view, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + auto _responseCb = [response](MetricsAdmin::GetMetricsViewResult&& _result) + { + response(::std::move(_result.returnValue), _result.timestamp); + }; + return _makeLamdaOutgoing(std::move(_responseCb), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_getMetricsView, view, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getMetricsView(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @return The metrics failures associated with the map. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + MetricsFailuresSeq getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makePromiseOutgoing<::IceMX::MetricsFailuresSeq>(true, this, &MetricsAdminPrx::_iceI_getMapMetricsFailures, view, map, context).get(); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getMapMetricsFailuresAsync(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing<::IceMX::MetricsFailuresSeq, P>(false, this, &MetricsAdminPrx::_iceI_getMapMetricsFailures, view, map, context); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getMapMetricsFailuresAsync(const ::std::string& view, const ::std::string& map, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing<::IceMX::MetricsFailuresSeq>(std::move(response), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_getMapMetricsFailures, view, map, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getMapMetricsFailures(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::IceMX::MetricsFailuresSeq>>&, const ::std::string&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @return The metrics failures associated with the metrics. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + MetricsFailures getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makePromiseOutgoing<::IceMX::MetricsFailures>(true, this, &MetricsAdminPrx::_iceI_getMetricsFailures, view, map, id, context).get(); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getMetricsFailuresAsync(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing<::IceMX::MetricsFailures, P>(false, this, &MetricsAdminPrx::_iceI_getMetricsFailures, view, map, id, context); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getMetricsFailuresAsync(const ::std::string& view, const ::std::string& map, const ::std::string& id, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing<::IceMX::MetricsFailures>(std::move(response), std::move(ex), std::move(sent), this, &IceMX::MetricsAdminPrx::_iceI_getMetricsFailures, view, map, id, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getMetricsFailures(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::IceMX::MetricsFailures>>&, const ::std::string&, const ::std::string&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + MetricsAdminPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +template +struct StreamReader<::IceMX::Metrics, S> +{ + static void read(S* istr, ::IceMX::Metrics& v) + { + istr->readAll(v.id, v.total, v.current, v.totalLifetime, v.failures); + } +}; + +template<> +struct StreamableTraits<::IceMX::MetricsFailures> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; + +template +struct StreamReader<::IceMX::MetricsFailures, S> +{ + static void read(S* istr, ::IceMX::MetricsFailures& v) + { + istr->readAll(v.id, v.failures); + } +}; + +template +struct StreamWriter<::IceMX::ThreadMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ThreadMetrics& v) + { + ostr->writeAll(v.inUseForIO, v.inUseForUser, v.inUseForOther); + } +}; + +template +struct StreamReader<::IceMX::ThreadMetrics, S> +{ + static void read(S* istr, ::IceMX::ThreadMetrics& v) + { + istr->readAll(v.inUseForIO, v.inUseForUser, v.inUseForOther); + } +}; + +template +struct StreamWriter<::IceMX::DispatchMetrics, S> +{ + static void write(S* ostr, const ::IceMX::DispatchMetrics& v) + { + ostr->writeAll(v.userException, v.size, v.replySize); + } +}; + +template +struct StreamReader<::IceMX::DispatchMetrics, S> +{ + static void read(S* istr, ::IceMX::DispatchMetrics& v) + { + istr->readAll(v.userException, v.size, v.replySize); + } +}; + +template +struct StreamWriter<::IceMX::ChildInvocationMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ChildInvocationMetrics& v) + { + ostr->writeAll(v.size, v.replySize); + } +}; + +template +struct StreamReader<::IceMX::ChildInvocationMetrics, S> +{ + static void read(S* istr, ::IceMX::ChildInvocationMetrics& v) + { + istr->readAll(v.size, v.replySize); + } +}; + +template +struct StreamWriter<::IceMX::CollocatedMetrics, S> +{ + static void write(S*, const ::IceMX::CollocatedMetrics&) + { + } +}; + +template +struct StreamReader<::IceMX::CollocatedMetrics, S> +{ + static void read(S*, ::IceMX::CollocatedMetrics&) + { + } +}; + +template +struct StreamWriter<::IceMX::RemoteMetrics, S> +{ + static void write(S*, const ::IceMX::RemoteMetrics&) + { + } +}; + +template +struct StreamReader<::IceMX::RemoteMetrics, S> +{ + static void read(S*, ::IceMX::RemoteMetrics&) + { + } +}; + +template +struct StreamWriter<::IceMX::InvocationMetrics, S> +{ + static void write(S* ostr, const ::IceMX::InvocationMetrics& v) + { + ostr->writeAll(v.retry, v.userException, v.remotes, v.collocated); + } +}; + +template +struct StreamReader<::IceMX::InvocationMetrics, S> +{ + static void read(S* istr, ::IceMX::InvocationMetrics& v) + { + istr->readAll(v.retry, v.userException, v.remotes, v.collocated); + } +}; + +template +struct StreamWriter<::IceMX::ConnectionMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ConnectionMetrics& v) + { + ostr->writeAll(v.receivedBytes, v.sentBytes); + } +}; + +template +struct StreamReader<::IceMX::ConnectionMetrics, S> +{ + static void read(S* istr, ::IceMX::ConnectionMetrics& v) + { + istr->readAll(v.receivedBytes, v.sentBytes); + } +}; + +} +/// \endcond + +/// \cond INTERNAL +namespace IceMX +{ + +using MetricsPtr = ::std::shared_ptr; + +using MetricsAdminPtr = ::std::shared_ptr; +using MetricsAdminPrxPtr = ::std::shared_ptr; + +using ThreadMetricsPtr = ::std::shared_ptr; + +using DispatchMetricsPtr = ::std::shared_ptr; + +using ChildInvocationMetricsPtr = ::std::shared_ptr; + +using CollocatedMetricsPtr = ::std::shared_ptr; + +using RemoteMetricsPtr = ::std::shared_ptr; + +using InvocationMetricsPtr = ::std::shared_ptr; + +using ConnectionMetricsPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace IceMX +{ + +class Metrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Metrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(Metrics*); +/// \endcond + +class MetricsAdmin; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< MetricsAdmin>&); +ICE_API ::IceProxy::Ice::Object* upCast(MetricsAdmin*); +/// \endcond + +class ThreadMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< ThreadMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(ThreadMetrics*); +/// \endcond + +class DispatchMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< DispatchMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(DispatchMetrics*); +/// \endcond + +class ChildInvocationMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< ChildInvocationMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(ChildInvocationMetrics*); +/// \endcond + +class CollocatedMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< CollocatedMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(CollocatedMetrics*); +/// \endcond + +class RemoteMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< RemoteMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(RemoteMetrics*); +/// \endcond + +class InvocationMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< InvocationMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(InvocationMetrics*); +/// \endcond + +class ConnectionMetrics; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< ConnectionMetrics>&); +ICE_API ::IceProxy::Ice::Object* upCast(ConnectionMetrics*); +/// \endcond + +} + +} + +namespace IceMX +{ + +class Metrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(Metrics*); +/// \endcond +typedef ::IceInternal::Handle< Metrics> MetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::Metrics> MetricsPrx; +typedef MetricsPrx MetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(MetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class MetricsAdmin; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(MetricsAdmin*); +/// \endcond +typedef ::IceInternal::Handle< MetricsAdmin> MetricsAdminPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::MetricsAdmin> MetricsAdminPrx; +typedef MetricsAdminPrx MetricsAdminPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(MetricsAdminPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class ThreadMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(ThreadMetrics*); +/// \endcond +typedef ::IceInternal::Handle< ThreadMetrics> ThreadMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::ThreadMetrics> ThreadMetricsPrx; +typedef ThreadMetricsPrx ThreadMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ThreadMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class DispatchMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(DispatchMetrics*); +/// \endcond +typedef ::IceInternal::Handle< DispatchMetrics> DispatchMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::DispatchMetrics> DispatchMetricsPrx; +typedef DispatchMetricsPrx DispatchMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(DispatchMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class ChildInvocationMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(ChildInvocationMetrics*); +/// \endcond +typedef ::IceInternal::Handle< ChildInvocationMetrics> ChildInvocationMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::ChildInvocationMetrics> ChildInvocationMetricsPrx; +typedef ChildInvocationMetricsPrx ChildInvocationMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ChildInvocationMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class CollocatedMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(CollocatedMetrics*); +/// \endcond +typedef ::IceInternal::Handle< CollocatedMetrics> CollocatedMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::CollocatedMetrics> CollocatedMetricsPrx; +typedef CollocatedMetricsPrx CollocatedMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(CollocatedMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class RemoteMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(RemoteMetrics*); +/// \endcond +typedef ::IceInternal::Handle< RemoteMetrics> RemoteMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::RemoteMetrics> RemoteMetricsPrx; +typedef RemoteMetricsPrx RemoteMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(RemoteMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class InvocationMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(InvocationMetrics*); +/// \endcond +typedef ::IceInternal::Handle< InvocationMetrics> InvocationMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::InvocationMetrics> InvocationMetricsPrx; +typedef InvocationMetricsPrx InvocationMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(InvocationMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class ConnectionMetrics; +/// \cond INTERNAL +ICE_API ::Ice::Object* upCast(ConnectionMetrics*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionMetrics> ConnectionMetricsPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceMX::ConnectionMetrics> ConnectionMetricsPrx; +typedef ConnectionMetricsPrx ConnectionMetricsPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ConnectionMetricsPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +} + +namespace IceMX +{ + +/** + * A dictionnary of strings to integers. + */ +typedef ::std::map< ::std::string, ::Ice::Int> StringIntDict; + +/** + * A structure to keep track of failures associated with a given + * metrics. + * \headerfile Ice/Ice.h + */ +struct MetricsFailures +{ + /** + * The identifier of the metrics object associated to the + * failures. + */ + ::std::string id; + /** + * The failures observed for this metrics. + */ + ::IceMX::StringIntDict failures; +}; + +/** + * A sequence of {@link MetricsFailures}. + */ +typedef ::std::vector MetricsFailuresSeq; + +/** + * A metrics map is a sequence of metrics. We use a sequence here + * instead of a map because the ID of the metrics is already included + * in the Metrics class and using sequences of metrics objects is more + * efficient than using dictionaries since lookup is not necessary. + */ +typedef ::std::vector MetricsMap; + +/** + * A metrics view is a dictionary of metrics map. The key of the + * dictionary is the name of the metrics map. + */ +typedef ::std::map< ::std::string, MetricsMap> MetricsView; + +/** + * Raised if a metrics view cannot be found. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownMetricsView : public ::Ice::UserException +{ +public: + + UnknownMetricsView() {} + +#ifdef ICE_CPP11_COMPILER + UnknownMetricsView(const UnknownMetricsView&) = default; + virtual ~UnknownMetricsView(); +#else + virtual ~UnknownMetricsView() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual UnknownMetricsView* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(::Ice::OutputStream*) const; + virtual void _readImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +static UnknownMetricsView _iceS_UnknownMetricsView_init; +/// \endcond + +} + +namespace IceMX +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsViewNames. + */ +class Callback_MetricsAdmin_getMetricsViewNames_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_getMetricsViewNames_Base> Callback_MetricsAdmin_getMetricsViewNamesPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_enableMetricsView. + */ +class Callback_MetricsAdmin_enableMetricsView_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_enableMetricsView_Base> Callback_MetricsAdmin_enableMetricsViewPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_disableMetricsView. + */ +class Callback_MetricsAdmin_disableMetricsView_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_disableMetricsView_Base> Callback_MetricsAdmin_disableMetricsViewPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsView. + */ +class Callback_MetricsAdmin_getMetricsView_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_getMetricsView_Base> Callback_MetricsAdmin_getMetricsViewPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMapMetricsFailures. + */ +class Callback_MetricsAdmin_getMapMetricsFailures_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_getMapMetricsFailures_Base> Callback_MetricsAdmin_getMapMetricsFailuresPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsFailures. + */ +class Callback_MetricsAdmin_getMetricsFailures_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_MetricsAdmin_getMetricsFailures_Base> Callback_MetricsAdmin_getMetricsFailuresPtr; + +} + +namespace IceProxy +{ + +namespace IceMX +{ + +class ICE_CLASS(ICE_API) Metrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) MetricsAdmin : public virtual ::Ice::Proxy +{ +public: + + /** + * Get the names of enabled and disabled metrics. + * @param disabledViews The names of the disabled views. + * @param context The Context map to send with the invocation. + * @return The name of the enabled views. + */ + ICE_MEMBER(ICE_API) ::Ice::StringSeq getMetricsViewNames(::Ice::StringSeq& disabledViews, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getMetricsViewNames(disabledViews, _iceI_begin_getMetricsViewNames(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the names of enabled and disabled metrics. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsViewNames(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getMetricsViewNames(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the names of enabled and disabled metrics. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsViewNames(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsViewNames(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the names of enabled and disabled metrics. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsViewNames(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsViewNames(context, cb, cookie); + } + + /** + * Get the names of enabled and disabled metrics. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsViewNames(const ::IceMX::Callback_MetricsAdmin_getMetricsViewNamesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsViewNames(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the names of enabled and disabled metrics. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsViewNames(const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_getMetricsViewNamesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsViewNames(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getMetricsViewNames. + * @param disabledViews The names of the disabled views. + * @param result The asynchronous result object for the invocation. + * @return The name of the enabled views. + */ + ICE_MEMBER(ICE_API) ::Ice::StringSeq end_getMetricsViewNames(::Ice::StringSeq& disabledViews, const ::Ice::AsyncResultPtr& result); + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) void _iceI_end_getMetricsViewNames(::Ice::StringSeq& iceP_disabledViews, ::Ice::StringSeq& ret, const ::Ice::AsyncResultPtr&); + /// \endcond + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getMetricsViewNames(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) void enableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_enableMetricsView(_iceI_begin_enableMetricsView(name, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_enableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_enableMetricsView(name, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_enableMetricsView(const ::std::string& name, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_enableMetricsView(name, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_enableMetricsView(const ::std::string& name, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_enableMetricsView(name, context, cb, cookie); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_enableMetricsView(const ::std::string& name, const ::IceMX::Callback_MetricsAdmin_enableMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_enableMetricsView(name, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_enableMetricsView(const ::std::string& name, const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_enableMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_enableMetricsView(name, context, cb, cookie); + } + + /** + * Completes an invocation of begin_enableMetricsView. + * @param result The asynchronous result object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) void end_enableMetricsView(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_enableMetricsView(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) void disableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_disableMetricsView(_iceI_begin_disableMetricsView(name, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_disableMetricsView(const ::std::string& name, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_disableMetricsView(name, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_disableMetricsView(const ::std::string& name, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_disableMetricsView(name, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_disableMetricsView(const ::std::string& name, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_disableMetricsView(name, context, cb, cookie); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_disableMetricsView(const ::std::string& name, const ::IceMX::Callback_MetricsAdmin_disableMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_disableMetricsView(name, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_disableMetricsView(const ::std::string& name, const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_disableMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_disableMetricsView(name, context, cb, cookie); + } + + /** + * Completes an invocation of begin_disableMetricsView. + * @param result The asynchronous result object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) void end_disableMetricsView(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_disableMetricsView(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param timestamp The local time of the process when the metrics + * object were retrieved. + * @param context The Context map to send with the invocation. + * @return The metrics view data. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsView getMetricsView(const ::std::string& view, ::Ice::Long& timestamp, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getMetricsView(timestamp, _iceI_begin_getMetricsView(view, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsView(const ::std::string& view, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getMetricsView(view, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsView(const ::std::string& view, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsView(view, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsView(const ::std::string& view, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsView(view, context, cb, cookie); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsView(const ::std::string& view, const ::IceMX::Callback_MetricsAdmin_getMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsView(view, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsView(const ::std::string& view, const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_getMetricsViewPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsView(view, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getMetricsView. + * @param timestamp The local time of the process when the metrics + * object were retrieved. + * @param result The asynchronous result object for the invocation. + * @return The metrics view data. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsView end_getMetricsView(::Ice::Long& timestamp, const ::Ice::AsyncResultPtr& result); + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) void _iceI_end_getMetricsView(::Ice::Long& iceP_timestamp, ::IceMX::MetricsView& ret, const ::Ice::AsyncResultPtr&); + /// \endcond + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getMetricsView(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @return The metrics failures associated with the map. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsFailuresSeq getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getMapMetricsFailures(_iceI_begin_getMapMetricsFailures(view, map, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getMapMetricsFailures(view, map, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMapMetricsFailures(view, map, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMapMetricsFailures(view, map, context, cb, cookie); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::IceMX::Callback_MetricsAdmin_getMapMetricsFailuresPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMapMetricsFailures(view, map, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_getMapMetricsFailuresPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMapMetricsFailures(view, map, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getMapMetricsFailures. + * @param result The asynchronous result object for the invocation. + * @return The metrics failures associated with the map. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsFailuresSeq end_getMapMetricsFailures(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getMapMetricsFailures(const ::std::string&, const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @return The metrics failures associated with the metrics. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsFailures getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getMetricsFailures(_iceI_begin_getMetricsFailures(view, map, id, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getMetricsFailures(view, map, id, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsFailures(view, map, id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsFailures(view, map, id, context, cb, cookie); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::IceMX::Callback_MetricsAdmin_getMetricsFailuresPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsFailures(view, map, id, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Context& context, const ::IceMX::Callback_MetricsAdmin_getMetricsFailuresPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getMetricsFailures(view, map, id, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getMetricsFailures. + * @param result The asynchronous result object for the invocation. + * @return The metrics failures associated with the metrics. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + ICE_MEMBER(ICE_API) ::IceMX::MetricsFailures end_getMetricsFailures(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getMetricsFailures(const ::std::string&, const ::std::string&, const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) ThreadMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) DispatchMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) ChildInvocationMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) CollocatedMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) RemoteMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) InvocationMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) ConnectionMetrics : public virtual ::Ice::Proxy +{ +public: + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace IceMX +{ + +/** + * The base class for metrics. A metrics object represents a + * collection of measurements associated to a given a system. + * \headerfile Ice/Ice.h + */ +class ICE_API Metrics : public virtual ::Ice::Object +{ +public: + + typedef MetricsPrx ProxyType; + typedef MetricsPtr PointerType; + + virtual ~Metrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + Metrics() : + total(ICE_INT64(0)), + current(0), + totalLifetime(ICE_INT64(0)), + failures(0) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + */ + Metrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures) : + id(id), + total(total), + current(current), + totalLifetime(totalLifetime), + failures(failures) + { + } + +#ifdef ICE_CPP11_COMPILER + Metrics(const Metrics&) = default; + Metrics& operator=(const Metrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The metrics identifier. + */ + ::std::string id; + /** + * The total number of objects observed by this metrics. This includes + * the number of currently observed objects and the number of objects + * observed in the past. + */ + ::Ice::Long total; + /** + * The number of objects currently observed by this metrics. + */ + ::Ice::Int current; + /** + * The sum of the lifetime of each observed objects. This does not + * include the lifetime of objects which are currently observed, + * only the objects observed in the past. + */ + ::Ice::Long totalLifetime; + /** + * The number of failures observed. + */ + ::Ice::Int failures; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_Metrics_init = ::IceMX::Metrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const Metrics& lhs, const Metrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Metrics& lhs, const Metrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The metrics administrative facet interface. This interface allows + * remote administrative clients to access metrics of an application + * that enabled the Ice administrative facility and configured some + * metrics views. + * \headerfile Ice/Ice.h + */ +class ICE_API MetricsAdmin : public virtual ::Ice::Object +{ +public: + + typedef MetricsAdminPrx ProxyType; + typedef MetricsAdminPtr PointerType; + + virtual ~MetricsAdmin(); + +#ifdef ICE_CPP11_COMPILER + MetricsAdmin() = default; + MetricsAdmin(const MetricsAdmin&) = default; + MetricsAdmin& operator=(const MetricsAdmin&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the names of enabled and disabled metrics. + * @param disabledViews The names of the disabled views. + * @param current The Current object for the invocation. + * @return The name of the enabled views. + */ + virtual ::Ice::StringSeq getMetricsViewNames(::Ice::StringSeq& disabledViews, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsViewNames(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Enables a metrics view. + * @param name The metrics view name. + * @param current The Current object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual void enableMetricsView(const ::std::string& name, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_enableMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Disable a metrics view. + * @param name The metrics view name. + * @param current The Current object for the invocation. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual void disableMetricsView(const ::std::string& name, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_disableMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get the metrics objects for the given metrics view. This + * returns a dictionnary of metric maps for each metrics class + * configured with the view. The timestamp allows the client to + * compute averages which are not dependent of the invocation + * latency for this operation. + * @param view The name of the metrics view. + * @param timestamp The local time of the process when the metrics + * object were retrieved. + * @param current The Current object for the invocation. + * @return The metrics view data. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsView getMetricsView(const ::std::string& view, ::Ice::Long& timestamp, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsView(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get the metrics failures associated with the given view and map. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param current The Current object for the invocation. + * @return The metrics failures associated with the map. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsFailuresSeq getMapMetricsFailures(const ::std::string& view, const ::std::string& map, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getMapMetricsFailures(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get the metrics failure associated for the given metrics. + * @param view The name of the metrics view. + * @param map The name of the metrics map. + * @param id The ID of the metrics. + * @param current The Current object for the invocation. + * @return The metrics failures associated with the metrics. + * @throws IceMX::UnknownMetricsView Raised if the metrics view cannot be + * found. + */ + virtual MetricsFailures getMetricsFailures(const ::std::string& view, const ::std::string& map, const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getMetricsFailures(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const MetricsAdmin& lhs, const MetricsAdmin& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const MetricsAdmin& lhs, const MetricsAdmin& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on the number of threads currently in use and + * their activity. + * \headerfile Ice/Ice.h + */ +class ICE_API ThreadMetrics : public Metrics +{ +public: + + typedef ThreadMetricsPrx ProxyType; + typedef ThreadMetricsPtr PointerType; + + virtual ~ThreadMetrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + ThreadMetrics() : + inUseForIO(0), + inUseForUser(0), + inUseForOther(0) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param inUseForIO The number of threads which are currently performing socket read or writes. + * @param inUseForUser The number of threads which are currently calling user code (servant dispatch, AMI callbacks, etc). + * @param inUseForOther The number of threads which are currently performing other activities. + */ + ThreadMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Int inUseForIO, ::Ice::Int inUseForUser, ::Ice::Int inUseForOther) : + ::IceMX::Metrics(id, total, current, totalLifetime, failures), + inUseForIO(inUseForIO), + inUseForUser(inUseForUser), + inUseForOther(inUseForOther) + { + } + +#ifdef ICE_CPP11_COMPILER + ThreadMetrics(const ThreadMetrics&) = default; + ThreadMetrics& operator=(const ThreadMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The number of threads which are currently performing socket + * read or writes. + */ + ::Ice::Int inUseForIO; + /** + * The number of threads which are currently calling user code + * (servant dispatch, AMI callbacks, etc). + */ + ::Ice::Int inUseForUser; + /** + * The number of threads which are currently performing other + * activities. These are all other that are not counted with + * {@link #inUseForUser} or {@link #inUseForIO}, such as DNS + * lookups, garbage collection). + */ + ::Ice::Int inUseForOther; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_ThreadMetrics_init = ::IceMX::ThreadMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const ThreadMetrics& lhs, const ThreadMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ThreadMetrics& lhs, const ThreadMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on servant dispatch. + * \headerfile Ice/Ice.h + */ +class ICE_API DispatchMetrics : public Metrics +{ +public: + + typedef DispatchMetricsPrx ProxyType; + typedef DispatchMetricsPtr PointerType; + + virtual ~DispatchMetrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + DispatchMetrics() : + userException(0), + size(ICE_INT64(0)), + replySize(ICE_INT64(0)) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param userException The number of dispatch that failed with a user exception. + * @param size The size of the dispatch. + * @param replySize The size of the dispatch reply. + */ + DispatchMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Int userException, ::Ice::Long size, ::Ice::Long replySize) : + ::IceMX::Metrics(id, total, current, totalLifetime, failures), + userException(userException), + size(size), + replySize(replySize) + { + } + +#ifdef ICE_CPP11_COMPILER + DispatchMetrics(const DispatchMetrics&) = default; + DispatchMetrics& operator=(const DispatchMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The number of dispatch that failed with a user exception. + */ + ::Ice::Int userException; + /** + * The size of the dispatch. This corresponds to the size of the + * marshalled input parameters. + */ + ::Ice::Long size; + /** + * The size of the dispatch reply. This corresponds to the size of + * the marshalled output and return parameters. + */ + ::Ice::Long replySize; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_DispatchMetrics_init = ::IceMX::DispatchMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const DispatchMetrics& lhs, const DispatchMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const DispatchMetrics& lhs, const DispatchMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on child invocations. A child invocation is + * either remote (sent over an Ice connection) or collocated. An + * invocation can have multiple child invocation if it is + * retried. Child invocation metrics are embedded within + * {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_API ChildInvocationMetrics : public Metrics +{ +public: + + typedef ChildInvocationMetricsPrx ProxyType; + typedef ChildInvocationMetricsPtr PointerType; + + virtual ~ChildInvocationMetrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + ChildInvocationMetrics() : + size(ICE_INT64(0)), + replySize(ICE_INT64(0)) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + ChildInvocationMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Long size, ::Ice::Long replySize) : + ::IceMX::Metrics(id, total, current, totalLifetime, failures), + size(size), + replySize(replySize) + { + } + +#ifdef ICE_CPP11_COMPILER + ChildInvocationMetrics(const ChildInvocationMetrics&) = default; + ChildInvocationMetrics& operator=(const ChildInvocationMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The size of the invocation. This corresponds to the size of the + * marshalled input parameters. + */ + ::Ice::Long size; + /** + * The size of the invocation reply. This corresponds to the size + * of the marshalled output and return parameters. + */ + ::Ice::Long replySize; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_ChildInvocationMetrics_init = ::IceMX::ChildInvocationMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const ChildInvocationMetrics& lhs, const ChildInvocationMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ChildInvocationMetrics& lhs, const ChildInvocationMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on invocations that are collocated. Collocated + * metrics are embedded within {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_API CollocatedMetrics : public ChildInvocationMetrics +{ +public: + + typedef CollocatedMetricsPrx ProxyType; + typedef CollocatedMetricsPtr PointerType; + + virtual ~CollocatedMetrics(); + + CollocatedMetrics() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + CollocatedMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Long size, ::Ice::Long replySize) : + ::IceMX::ChildInvocationMetrics(id, total, current, totalLifetime, failures, size, replySize) + { + } + +#ifdef ICE_CPP11_COMPILER + CollocatedMetrics(const CollocatedMetrics&) = default; + CollocatedMetrics& operator=(const CollocatedMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_CollocatedMetrics_init = ::IceMX::CollocatedMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const CollocatedMetrics& lhs, const CollocatedMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const CollocatedMetrics& lhs, const CollocatedMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on invocations that are specifically sent over + * Ice connections. Remote metrics are embedded within {@link InvocationMetrics}. + * \headerfile Ice/Ice.h + */ +class ICE_API RemoteMetrics : public ChildInvocationMetrics +{ +public: + + typedef RemoteMetricsPrx ProxyType; + typedef RemoteMetricsPtr PointerType; + + virtual ~RemoteMetrics(); + + RemoteMetrics() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param size The size of the invocation. + * @param replySize The size of the invocation reply. + */ + RemoteMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Long size, ::Ice::Long replySize) : + ::IceMX::ChildInvocationMetrics(id, total, current, totalLifetime, failures, size, replySize) + { + } + +#ifdef ICE_CPP11_COMPILER + RemoteMetrics(const RemoteMetrics&) = default; + RemoteMetrics& operator=(const RemoteMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_RemoteMetrics_init = ::IceMX::RemoteMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const RemoteMetrics& lhs, const RemoteMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const RemoteMetrics& lhs, const RemoteMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provide measurements for proxy invocations. Proxy invocations can + * either be sent over the wire or be collocated. + * \headerfile Ice/Ice.h + */ +class ICE_API InvocationMetrics : public Metrics, public ::IceInternal::GCObject +{ +public: + + typedef InvocationMetricsPrx ProxyType; + typedef InvocationMetricsPtr PointerType; + + virtual ~InvocationMetrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + InvocationMetrics() : + retry(0), + userException(0) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param retry The number of retries for the invocation(s). + * @param userException The number of invocations that failed with a user exception. + * @param remotes The remote invocation metrics map. + * @param collocated The collocated invocation metrics map. + */ + InvocationMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Int retry, ::Ice::Int userException, const ::IceMX::MetricsMap& remotes, const ::IceMX::MetricsMap& collocated) : + ::IceMX::Metrics(id, total, current, totalLifetime, failures), + retry(retry), + userException(userException), + remotes(remotes), + collocated(collocated) + { + } + +#ifdef ICE_CPP11_COMPILER + InvocationMetrics(const InvocationMetrics&) = default; + InvocationMetrics& operator=(const InvocationMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + /// \cond INTERNAL + virtual void _iceGcVisitMembers(::IceInternal::GCVisitor&); + /// \endcond + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The number of retries for the invocation(s). + */ + ::Ice::Int retry; + /** + * The number of invocations that failed with a user exception. + */ + ::Ice::Int userException; + /** + * The remote invocation metrics map. + * @see RemoteMetrics + */ + ::IceMX::MetricsMap remotes; + /** + * The collocated invocation metrics map. + * @see CollocatedMetrics + */ + ::IceMX::MetricsMap collocated; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_InvocationMetrics_init = ::IceMX::InvocationMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const InvocationMetrics& lhs, const InvocationMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const InvocationMetrics& lhs, const InvocationMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Provides information on the data sent and received over Ice + * connections. + * \headerfile Ice/Ice.h + */ +class ICE_API ConnectionMetrics : public Metrics +{ +public: + + typedef ConnectionMetricsPrx ProxyType; + typedef ConnectionMetricsPtr PointerType; + + virtual ~ConnectionMetrics(); + + /** Default constructor that assigns default values to members as specified in the Slice definition. */ + ConnectionMetrics() : + receivedBytes(ICE_INT64(0)), + sentBytes(ICE_INT64(0)) + { + } + + /** + * One-shot constructor to initialize all data members. + * @param id The metrics identifier. + * @param total The total number of objects observed by this metrics. + * @param current The number of objects currently observed by this metrics. + * @param totalLifetime The sum of the lifetime of each observed objects. + * @param failures The number of failures observed. + * @param receivedBytes The number of bytes received by the connection. + * @param sentBytes The number of bytes sent by the connection. + */ + ConnectionMetrics(const ::std::string& id, ::Ice::Long total, ::Ice::Int current, ::Ice::Long totalLifetime, ::Ice::Int failures, ::Ice::Long receivedBytes, ::Ice::Long sentBytes) : + ::IceMX::Metrics(id, total, current, totalLifetime, failures), + receivedBytes(receivedBytes), + sentBytes(sentBytes) + { + } + +#ifdef ICE_CPP11_COMPILER + ConnectionMetrics(const ConnectionMetrics&) = default; + ConnectionMetrics& operator=(const ConnectionMetrics&) = default; +#endif + + /** + * Polymorphically clones this object. + * @return A shallow copy of this object. + */ + virtual ::Ice::ObjectPtr ice_clone() const; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Obtains a value factory that instantiates this class. + * @return The value factory. + */ + static ::Ice::ValueFactoryPtr ice_factory(); + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond + +public: + + /** + * The number of bytes received by the connection. + */ + ::Ice::Long receivedBytes; + /** + * The number of bytes sent by the connection. + */ + ::Ice::Long sentBytes; +}; +/// \cond INTERNAL +static ::Ice::ValueFactoryPtr _iceS_ConnectionMetrics_init = ::IceMX::ConnectionMetrics::ice_factory(); +/// \endcond + +/// \cond INTERNAL +inline bool operator==(const ConnectionMetrics& lhs, const ConnectionMetrics& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ConnectionMetrics& lhs, const ConnectionMetrics& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +template +struct StreamWriter< ::IceMX::Metrics, S> +{ + static void write(S* ostr, const ::IceMX::Metrics& v) + { + ostr->write(v.id); + ostr->write(v.total); + ostr->write(v.current); + ostr->write(v.totalLifetime); + ostr->write(v.failures); + } +}; + +template +struct StreamReader< ::IceMX::Metrics, S> +{ + static void read(S* istr, ::IceMX::Metrics& v) + { + istr->read(v.id); + istr->read(v.total); + istr->read(v.current); + istr->read(v.totalLifetime); + istr->read(v.failures); + } +}; + +template<> +struct StreamableTraits< ::IceMX::MetricsFailures> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; + +template +struct StreamWriter< ::IceMX::MetricsFailures, S> +{ + static void write(S* ostr, const ::IceMX::MetricsFailures& v) + { + ostr->write(v.id); + ostr->write(v.failures); + } +}; + +template +struct StreamReader< ::IceMX::MetricsFailures, S> +{ + static void read(S* istr, ::IceMX::MetricsFailures& v) + { + istr->read(v.id); + istr->read(v.failures); + } +}; + +template<> +struct StreamableTraits< ::IceMX::UnknownMetricsView> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +template +struct StreamWriter< ::IceMX::ThreadMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ThreadMetrics& v) + { + ostr->write(v.inUseForIO); + ostr->write(v.inUseForUser); + ostr->write(v.inUseForOther); + } +}; + +template +struct StreamReader< ::IceMX::ThreadMetrics, S> +{ + static void read(S* istr, ::IceMX::ThreadMetrics& v) + { + istr->read(v.inUseForIO); + istr->read(v.inUseForUser); + istr->read(v.inUseForOther); + } +}; + +template +struct StreamWriter< ::IceMX::DispatchMetrics, S> +{ + static void write(S* ostr, const ::IceMX::DispatchMetrics& v) + { + ostr->write(v.userException); + ostr->write(v.size); + ostr->write(v.replySize); + } +}; + +template +struct StreamReader< ::IceMX::DispatchMetrics, S> +{ + static void read(S* istr, ::IceMX::DispatchMetrics& v) + { + istr->read(v.userException); + istr->read(v.size); + istr->read(v.replySize); + } +}; + +template +struct StreamWriter< ::IceMX::ChildInvocationMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ChildInvocationMetrics& v) + { + ostr->write(v.size); + ostr->write(v.replySize); + } +}; + +template +struct StreamReader< ::IceMX::ChildInvocationMetrics, S> +{ + static void read(S* istr, ::IceMX::ChildInvocationMetrics& v) + { + istr->read(v.size); + istr->read(v.replySize); + } +}; + +template +struct StreamWriter< ::IceMX::InvocationMetrics, S> +{ + static void write(S* ostr, const ::IceMX::InvocationMetrics& v) + { + ostr->write(v.retry); + ostr->write(v.userException); + ostr->write(v.remotes); + ostr->write(v.collocated); + } +}; + +template +struct StreamReader< ::IceMX::InvocationMetrics, S> +{ + static void read(S* istr, ::IceMX::InvocationMetrics& v) + { + istr->read(v.retry); + istr->read(v.userException); + istr->read(v.remotes); + istr->read(v.collocated); + } +}; + +template +struct StreamWriter< ::IceMX::ConnectionMetrics, S> +{ + static void write(S* ostr, const ::IceMX::ConnectionMetrics& v) + { + ostr->write(v.receivedBytes); + ostr->write(v.sentBytes); + } +}; + +template +struct StreamReader< ::IceMX::ConnectionMetrics, S> +{ + static void read(S* istr, ::IceMX::ConnectionMetrics& v) + { + istr->read(v.receivedBytes); + istr->read(v.sentBytes); + } +}; + +} +/// \endcond + +namespace IceMX +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsViewNames. + */ +template +class CallbackNC_MetricsAdmin_getMetricsViewNames : public Callback_MetricsAdmin_getMetricsViewNames_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ::Ice::StringSeq&, const ::Ice::StringSeq&); + + CallbackNC_MetricsAdmin_getMetricsViewNames(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + ::Ice::StringSeq iceP_disabledViews; + ::Ice::StringSeq ret; + try + { + ret = proxy->end_getMetricsViewNames(iceP_disabledViews, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret, iceP_disabledViews); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + */ +template Callback_MetricsAdmin_getMetricsViewNamesPtr +newCallback_MetricsAdmin_getMetricsViewNames(const IceUtil::Handle& instance, void (T::*cb)(const ::Ice::StringSeq&, const ::Ice::StringSeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsViewNames(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + */ +template Callback_MetricsAdmin_getMetricsViewNamesPtr +newCallback_MetricsAdmin_getMetricsViewNames(T* instance, void (T::*cb)(const ::Ice::StringSeq&, const ::Ice::StringSeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsViewNames(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsViewNames. + */ +template +class Callback_MetricsAdmin_getMetricsViewNames : public Callback_MetricsAdmin_getMetricsViewNames_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ::Ice::StringSeq&, const ::Ice::StringSeq&, const CT&); + + Callback_MetricsAdmin_getMetricsViewNames(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + ::Ice::StringSeq iceP_disabledViews; + ::Ice::StringSeq ret; + try + { + ret = proxy->end_getMetricsViewNames(iceP_disabledViews, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, iceP_disabledViews, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + */ +template Callback_MetricsAdmin_getMetricsViewNamesPtr +newCallback_MetricsAdmin_getMetricsViewNames(const IceUtil::Handle& instance, void (T::*cb)(const ::Ice::StringSeq&, const ::Ice::StringSeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsViewNames(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsViewNames. + */ +template Callback_MetricsAdmin_getMetricsViewNamesPtr +newCallback_MetricsAdmin_getMetricsViewNames(T* instance, void (T::*cb)(const ::Ice::StringSeq&, const ::Ice::StringSeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsViewNames(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_enableMetricsView. + */ +template +class CallbackNC_MetricsAdmin_enableMetricsView : public Callback_MetricsAdmin_enableMetricsView_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_MetricsAdmin_enableMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_enableMetricsView(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_enableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_enableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_enableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_enableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_enableMetricsView. + */ +template +class Callback_MetricsAdmin_enableMetricsView : public Callback_MetricsAdmin_enableMetricsView_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_MetricsAdmin_enableMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_enableMetricsView(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_enableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_enableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_enableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_enableMetricsView. + */ +template Callback_MetricsAdmin_enableMetricsViewPtr +newCallback_MetricsAdmin_enableMetricsView(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_enableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_disableMetricsView. + */ +template +class CallbackNC_MetricsAdmin_disableMetricsView : public Callback_MetricsAdmin_disableMetricsView_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_MetricsAdmin_disableMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_disableMetricsView(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_disableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_disableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_disableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_disableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_disableMetricsView. + */ +template +class Callback_MetricsAdmin_disableMetricsView : public Callback_MetricsAdmin_disableMetricsView_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_MetricsAdmin_disableMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_disableMetricsView(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_disableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_disableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_disableMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_disableMetricsView. + */ +template Callback_MetricsAdmin_disableMetricsViewPtr +newCallback_MetricsAdmin_disableMetricsView(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_disableMetricsView(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsView. + */ +template +class CallbackNC_MetricsAdmin_getMetricsView : public Callback_MetricsAdmin_getMetricsView_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const MetricsView&, ::Ice::Long); + + CallbackNC_MetricsAdmin_getMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + ::Ice::Long iceP_timestamp; + MetricsView ret; + try + { + ret = proxy->end_getMetricsView(iceP_timestamp, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret, iceP_timestamp); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + */ +template Callback_MetricsAdmin_getMetricsViewPtr +newCallback_MetricsAdmin_getMetricsView(const IceUtil::Handle& instance, void (T::*cb)(const MetricsView&, ::Ice::Long), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + */ +template Callback_MetricsAdmin_getMetricsViewPtr +newCallback_MetricsAdmin_getMetricsView(T* instance, void (T::*cb)(const MetricsView&, ::Ice::Long), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsView(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsView. + */ +template +class Callback_MetricsAdmin_getMetricsView : public Callback_MetricsAdmin_getMetricsView_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const MetricsView&, ::Ice::Long, const CT&); + + Callback_MetricsAdmin_getMetricsView(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + ::Ice::Long iceP_timestamp; + MetricsView ret; + try + { + ret = proxy->end_getMetricsView(iceP_timestamp, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, iceP_timestamp, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + */ +template Callback_MetricsAdmin_getMetricsViewPtr +newCallback_MetricsAdmin_getMetricsView(const IceUtil::Handle& instance, void (T::*cb)(const MetricsView&, ::Ice::Long, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsView(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsView. + */ +template Callback_MetricsAdmin_getMetricsViewPtr +newCallback_MetricsAdmin_getMetricsView(T* instance, void (T::*cb)(const MetricsView&, ::Ice::Long, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsView(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMapMetricsFailures. + */ +template +class CallbackNC_MetricsAdmin_getMapMetricsFailures : public Callback_MetricsAdmin_getMapMetricsFailures_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const MetricsFailuresSeq&); + + CallbackNC_MetricsAdmin_getMapMetricsFailures(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + MetricsFailuresSeq ret; + try + { + ret = proxy->end_getMapMetricsFailures(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + */ +template Callback_MetricsAdmin_getMapMetricsFailuresPtr +newCallback_MetricsAdmin_getMapMetricsFailures(const IceUtil::Handle& instance, void (T::*cb)(const MetricsFailuresSeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMapMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + */ +template Callback_MetricsAdmin_getMapMetricsFailuresPtr +newCallback_MetricsAdmin_getMapMetricsFailures(T* instance, void (T::*cb)(const MetricsFailuresSeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMapMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMapMetricsFailures. + */ +template +class Callback_MetricsAdmin_getMapMetricsFailures : public Callback_MetricsAdmin_getMapMetricsFailures_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const MetricsFailuresSeq&, const CT&); + + Callback_MetricsAdmin_getMapMetricsFailures(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + MetricsFailuresSeq ret; + try + { + ret = proxy->end_getMapMetricsFailures(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + */ +template Callback_MetricsAdmin_getMapMetricsFailuresPtr +newCallback_MetricsAdmin_getMapMetricsFailures(const IceUtil::Handle& instance, void (T::*cb)(const MetricsFailuresSeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMapMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMapMetricsFailures. + */ +template Callback_MetricsAdmin_getMapMetricsFailuresPtr +newCallback_MetricsAdmin_getMapMetricsFailures(T* instance, void (T::*cb)(const MetricsFailuresSeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMapMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsFailures. + */ +template +class CallbackNC_MetricsAdmin_getMetricsFailures : public Callback_MetricsAdmin_getMetricsFailures_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const MetricsFailures&); + + CallbackNC_MetricsAdmin_getMetricsFailures(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + MetricsFailures ret; + try + { + ret = proxy->end_getMetricsFailures(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + */ +template Callback_MetricsAdmin_getMetricsFailuresPtr +newCallback_MetricsAdmin_getMetricsFailures(const IceUtil::Handle& instance, void (T::*cb)(const MetricsFailures&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + */ +template Callback_MetricsAdmin_getMetricsFailuresPtr +newCallback_MetricsAdmin_getMetricsFailures(T* instance, void (T::*cb)(const MetricsFailures&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_MetricsAdmin_getMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + * Create a wrapper instance by calling ::IceMX::newCallback_MetricsAdmin_getMetricsFailures. + */ +template +class Callback_MetricsAdmin_getMetricsFailures : public Callback_MetricsAdmin_getMetricsFailures_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const MetricsFailures&, const CT&); + + Callback_MetricsAdmin_getMetricsFailures(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + MetricsAdminPrx proxy = MetricsAdminPrx::uncheckedCast(result->getProxy()); + MetricsFailures ret; + try + { + ret = proxy->end_getMetricsFailures(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + */ +template Callback_MetricsAdmin_getMetricsFailuresPtr +newCallback_MetricsAdmin_getMetricsFailures(const IceUtil::Handle& instance, void (T::*cb)(const MetricsFailures&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsFailures(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceMX::MetricsAdmin::begin_getMetricsFailures. + */ +template Callback_MetricsAdmin_getMetricsFailuresPtr +newCallback_MetricsAdmin_getMetricsFailures(T* instance, void (T::*cb)(const MetricsFailures&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_MetricsAdmin_getMetricsFailures(instance, cb, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/MetricsAdminI.h b/Sources/IceCpp/include/Ice/MetricsAdminI.h new file mode 100644 index 0000000..d4c0585 --- /dev/null +++ b/Sources/IceCpp/include/Ice/MetricsAdminI.h @@ -0,0 +1,715 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_METRICSADMIN_I_H +#define ICE_METRICSADMIN_I_H + +#include +#include +#include + +#include + +#ifdef _MSC_VER +# define ICE_CPP11_COMPILER_REGEXP +#endif + +#ifdef __MINGW32__ + // + // No regexp support with MinGW, when MinGW C++11 mode is not experimental + // we can use std::regex. + // +#elif defined(ICE_CPP11_COMPILER_REGEXP) +# include +#else +# include +#endif + +#include + +namespace IceMX +{ + +/// \cond INTERNAL +class Updater; +template class MetricsHelperT; +/// \endcond + +} + +namespace IceInternal +{ + +class ICE_API MetricsMapI; +ICE_DEFINE_PTR(MetricsMapIPtr, MetricsMapI); + +class ICE_API MetricsMapI : +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public virtual IceUtil::Shared +#endif +{ +public: + + class ICE_API RegExp : public IceUtil::Shared + { + public: + + RegExp(const std::string&, const std::string&); + ~RegExp(); + + template bool + match(const IceMX::MetricsHelperT& helper, bool reject) + { + std::string value; + try + { + value = helper(_attribute); + } + catch(const std::exception&) + { + return !reject; + } + return match(value); + } + + private: + + bool match(const std::string&); + + const std::string _attribute; + +#ifdef __MINGW32__ + // + // No regexp support with MinGW, when MinGW C++11 mode is not experimental + // we can use std::regex. + // +#elif defined(ICE_CPP11_COMPILER_REGEXP) +# if _MSC_VER < 1600 + std::tr1::regex _regex; +# else + std::regex _regex; +# endif +#else + regex_t _preg; +#endif + }; + ICE_DEFINE_PTR(RegExpPtr, RegExp); + + virtual ~MetricsMapI(); + + MetricsMapI(const std::string&, const Ice::PropertiesPtr&); + MetricsMapI(const MetricsMapI&); + + virtual void destroy() = 0; + + virtual IceMX::MetricsFailuresSeq getFailures() = 0; + virtual IceMX::MetricsFailures getFailures(const std::string&) = 0; + virtual IceMX::MetricsMap getMetrics() const = 0; + + virtual MetricsMapIPtr clone() const = 0; + + const Ice::PropertyDict& getProperties() const; + +protected: + + const Ice::PropertyDict _properties; + const std::vector _groupByAttributes; + const std::vector _groupBySeparators; + const int _retain; + const std::vector _accept; + const std::vector _reject; +}; + +class ICE_API MetricsMapFactory +#ifndef ICE_CPP11_MAPPING + : public Ice::LocalObject +#endif +{ +public: + + virtual ~MetricsMapFactory(); + + MetricsMapFactory(IceMX::Updater*); + + virtual MetricsMapIPtr create(const std::string&, const Ice::PropertiesPtr&) = 0; + + void update(); + +private: + + IceMX::Updater* _updater; +}; +ICE_DEFINE_PTR(MetricsMapFactoryPtr, MetricsMapFactory); + +template class MetricsMapT : public MetricsMapI, private IceUtil::Mutex +{ +public: + + typedef MetricsType T; + typedef ICE_INTERNAL_HANDLE TPtr; + + ICE_DEFINE_PTR(MetricsMapTPtr, MetricsMapT); + + typedef IceMX::MetricsMap MetricsType::* SubMapMember; + + class EntryT; + ICE_DEFINE_PTR(EntryTPtr, EntryT); + + class EntryT : +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public Ice::LocalObject +#endif + { + public: + + EntryT(MetricsMapTPtr map, const TPtr& object, const typename std::list::iterator& p) : + _map(map), _object(object), _detachedPos(p) + { + } + + ~EntryT() + { + assert(_object->total > 0); + for(typename std::map >::const_iterator p = + _subMaps.begin(); p != _subMaps.end(); ++p) + { + p->second.first->destroy(); // Break cyclic reference counts. + } + } + + void + failed(const std::string& exceptionName) + { + IceUtil::Mutex::Lock sync(*_map); + ++_object->failures; + ++_failures[exceptionName]; + } + + template typename MetricsMapT::EntryTPtr + getMatching(const std::string& mapName, const IceMX::MetricsHelperT& helper) + { + MetricsMapIPtr m; + { + IceUtil::Mutex::Lock sync(*_map); + typename std::map >::iterator p = + _subMaps.find(mapName); + if(p == _subMaps.end()) + { + std::pair map = _map->createSubMap(mapName); + if(map.first) + { + p = _subMaps.insert(make_pair(mapName, map)).first; + } + } + if(p == _subMaps.end()) + { + return 0; + } + m = p->second.first; + } + + MetricsMapT* map = dynamic_cast*>(m.get()); + assert(map); + return map->getMatching(helper); + } + + void + detach(Ice::Long lifetime) + { + IceUtil::Mutex::Lock sync(*_map); + _object->totalLifetime += lifetime; + if(--_object->current == 0) + { +#ifdef ICE_CPP11_MAPPING + _map->detached(this->shared_from_this()); +#else + _map->detached(this); +#endif + } + } + + template void + execute(Function func) + { + IceUtil::Mutex::Lock sync(*_map); + func(_object); + } + + MetricsMapT* + getMap() + { + return _map.get(); + } + + private: + + IceMX::MetricsFailures + getFailures() const + { + IceMX::MetricsFailures f; + f.id = _object->id; + f.failures = _failures; + return f; + } + + IceMX::MetricsPtr + clone() const + { + TPtr metrics = ICE_DYNAMIC_CAST(T, _object->ice_clone()); + for(typename std::map >::const_iterator p = + _subMaps.begin(); p != _subMaps.end(); ++p) + { + metrics.get()->*p->second.second = p->second.first->getMetrics(); + } + return metrics; + } + + bool + isDetached() const + { + return _object->current == 0; + } + + void + attach(const IceMX::MetricsHelperT& helper) + { + ++_object->total; + ++_object->current; + helper.initMetrics(_object); + } + + friend class MetricsMapT; + MetricsMapTPtr _map; + TPtr _object; + IceMX::StringIntDict _failures; + std::map > _subMaps; + typename std::list::iterator _detachedPos; + }; + + MetricsMapT(const std::string& mapPrefix, + const Ice::PropertiesPtr& properties, + const std::map >& subMaps) : + MetricsMapI(mapPrefix, properties), _destroyed(false) + { + std::vector subMapNames; + typename std::map >::const_iterator p; + for(p = subMaps.begin(); p != subMaps.end(); ++p) + { + subMapNames.push_back(p->first); + const std::string subMapsPrefix = mapPrefix + "Map."; + std::string subMapPrefix = subMapsPrefix + p->first + '.'; + if(properties->getPropertiesForPrefix(subMapPrefix).empty()) + { + if(properties->getPropertiesForPrefix(subMapsPrefix).empty()) + { + subMapPrefix = mapPrefix; + } + else + { + continue; // This sub-map isn't configured. + } + } + _subMaps.insert(std::make_pair(p->first, + std::make_pair(p->second.first, + p->second.second->create(subMapPrefix, properties)))); + } + } + + MetricsMapT(const MetricsMapT& other) + : +#ifndef ICE_CPP11_MAPPING + IceUtil::Shared(), +#endif + MetricsMapI(other), + IceUtil::Mutex(), + _destroyed(false) + { + } + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(MetricsMapI::shared_from_this()); + } +#endif + + virtual void + destroy() + { + Lock sync(*this); + _destroyed = true; + _objects.clear(); // Break cyclic reference counts + _detachedQueue.clear(); // Break cyclic reference counts + } + + virtual IceMX::MetricsMap + getMetrics() const + { + IceMX::MetricsMap objects; + + Lock sync(*this); + for(typename std::map::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + objects.push_back(p->second->clone()); + } + return objects; + } + + virtual IceMX::MetricsFailuresSeq + getFailures() + { + IceMX::MetricsFailuresSeq failures; + + Lock sync(*this); + for(typename std::map::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + IceMX::MetricsFailures f = p->second->getFailures(); + if(!f.failures.empty()) + { + failures.push_back(f); + } + } + return failures; + } + + virtual IceMX::MetricsFailures + getFailures(const std::string& id) + { + Lock sync(*this); + typename std::map::const_iterator p = _objects.find(id); + if(p != _objects.end()) + { + return p->second->getFailures(); + } + return IceMX::MetricsFailures(); + } + + std::pair + createSubMap(const std::string& subMapName) + { + typename std::map >::const_iterator p = + _subMaps.find(subMapName); + if(p != _subMaps.end()) + { + return std::pair(ICE_GET_SHARED_FROM_THIS(p->second.second->clone()), p->second.first); + } + return std::pair(MetricsMapIPtr(ICE_NULLPTR), static_cast(0)); + } + + EntryTPtr + getMatching(const IceMX::MetricsHelperT& helper, const EntryTPtr& previous = EntryTPtr()) + { + // + // Check the accept and reject filters. + // + for(std::vector::const_iterator p = _accept.begin(); p != _accept.end(); ++p) + { + if(!(*p)->match(helper, false)) + { + return ICE_NULLPTR; + } + } + + for(std::vector::const_iterator p = _reject.begin(); p != _reject.end(); ++p) + { + if((*p)->match(helper, true)) + { + return ICE_NULLPTR; + } + } + + // + // Compute the key from the GroupBy property. + // + std::string key; + try + { + if(_groupByAttributes.size() == 1) + { + key = helper(_groupByAttributes.front()); + } + else + { + std::ostringstream os; + std::vector::const_iterator q = _groupBySeparators.begin(); + for(std::vector::const_iterator p = _groupByAttributes.begin(); + p != _groupByAttributes.end(); ++p) + { + os << helper(*p); + if(q != _groupBySeparators.end()) + { + os << *q++; + } + } + key = os.str(); + } + } + catch(const std::exception&) + { + return ICE_NULLPTR; + } + + // + // Lookup the metrics object. + // + Lock sync(*this); + if(_destroyed) + { + return ICE_NULLPTR; + } + + if(previous && previous->_object->id == key) + { + assert(_objects[key] == previous); + return previous; + } + + typename std::map::const_iterator p = _objects.find(key); + if(p == _objects.end()) + { + TPtr t = ICE_MAKE_SHARED(T); + t->id = key; + +#ifdef ICE_CPP11_MAPPING + p = _objects.insert(typename std::map::value_type( + key, std::make_shared(shared_from_this(), t, _detachedQueue.end()))).first; +#else + p = _objects.insert(typename std::map::value_type( + key, new EntryT(this, t, _detachedQueue.end()))).first; +#endif + + } + p->second->attach(helper); + return p->second; + } + +private: + + virtual MetricsMapIPtr clone() const + { + return ICE_MAKE_SHARED(MetricsMapT, *this); + } + + void detached(EntryTPtr entry) + { + // This is called with the map mutex locked. + + if(_retain == 0 || _destroyed) + { + return; + } + + assert(static_cast(_detachedQueue.size()) <= _retain); + + // If the entry is already detached and in the queue, just move it to the back. + if(entry->_detachedPos != _detachedQueue.end()) + { + if(entry->_detachedPos != --_detachedQueue.end()) // If not already at the end + { + _detachedQueue.splice(_detachedQueue.end(), _detachedQueue, entry->_detachedPos); + entry->_detachedPos = --_detachedQueue.end(); + } + return; + } + + // Otherwise, compress the queue by removing entries which are no longer detached. + if(static_cast(_detachedQueue.size()) == _retain) + { + // Remove entries which are no longer detached + typename std::list::iterator p = _detachedQueue.begin(); + while(p != _detachedQueue.end()) + { + if(!(*p)->isDetached()) + { + (*p)->_detachedPos = _detachedQueue.end(); + p = _detachedQueue.erase(p); + } + else + { + ++p; + } + } + } + + // If there's still no room, remove the oldest entry (at the front). + if(static_cast(_detachedQueue.size()) == _retain) + { + _objects.erase(_detachedQueue.front()->_object->id); + _detachedQueue.pop_front(); + } + + // Add the entry at the back of the queue. + entry->_detachedPos = _detachedQueue.insert(_detachedQueue.end(), entry); + assert(entry->_detachedPos != _detachedQueue.end()); + return; + } + + friend class EntryT; + + bool _destroyed; + std::map _objects; + std::list _detachedQueue; + std::map > _subMaps; +}; + +template class MetricsMapFactoryT : public MetricsMapFactory +{ +public: + + MetricsMapFactoryT(IceMX::Updater* updater) : MetricsMapFactory(updater) + { + } + + virtual MetricsMapIPtr + create(const std::string& mapPrefix, const Ice::PropertiesPtr& properties) + { + return ICE_MAKE_SHARED(MetricsMapT, mapPrefix, properties, _subMaps); + } + + template void + registerSubMap(const std::string& subMap, IceMX::MetricsMap MetricsType::* member) + { + _subMaps[subMap] = std::pair(member, ICE_MAKE_SHARED(MetricsMapFactoryT, ICE_NULLPTR)); + } + +private: + + std::map > _subMaps; +}; + +class MetricsViewI : public IceUtil::Shared +{ +public: + + MetricsViewI(const std::string&); + + void destroy(); + + bool addOrUpdateMap(const Ice::PropertiesPtr&, const std::string&, const MetricsMapFactoryPtr&, + const Ice::LoggerPtr&); + bool removeMap(const std::string&); + + IceMX::MetricsView getMetrics(); + IceMX::MetricsFailuresSeq getFailures(const std::string&); + IceMX::MetricsFailures getFailures(const std::string&, const std::string&); + + std::vector getMaps() const; + + MetricsMapIPtr getMap(const std::string&) const; + +private: + + const std::string _name; + std::map _maps; +}; +ICE_DEFINE_PTR(MetricsViewIPtr, MetricsViewI); + +class ICE_API MetricsAdminI : public IceMX::MetricsAdmin, +#ifndef ICE_CPP11_MAPPING + public Ice::PropertiesAdminUpdateCallback, +#endif + private IceUtil::Mutex +{ +public: + + MetricsAdminI(const ::Ice::PropertiesPtr&, const Ice::LoggerPtr&); + ~MetricsAdminI(); + + void destroy(); + + void updateViews(); + + template void + registerMap(const std::string& map, IceMX::Updater* updater) + { + bool updated; + MetricsMapFactoryPtr factory; + { + Lock sync(*this); + factory = ICE_MAKE_SHARED(MetricsMapFactoryT, updater); + _factories[map] = factory; + updated = addOrUpdateMap(map, factory); + } + if(updated) + { + factory->update(); + } + } + + template void + registerSubMap(const std::string& map, const std::string& subMap, IceMX::MetricsMap MetricsType::* member) + { + bool updated; + ICE_HANDLE > factory; + { + Lock sync(*this); + std::map::const_iterator p = _factories.find(map); + if(p == _factories.end()) + { + return; + } +#ifdef ICE_CPP11_MAPPING + factory = ::std::dynamic_pointer_cast>(p->second); +#else + factory = dynamic_cast*>(p->second.get()); +#endif + factory->template registerSubMap(subMap, member); + removeMap(map); + updated = addOrUpdateMap(map, factory); + } + if(updated) + { + factory->update(); + } + } + + void unregisterMap(const std::string&); + + virtual Ice::StringSeq getMetricsViewNames(Ice::StringSeq&, const ::Ice::Current&); + + void updated(const Ice::PropertyDict&); + +#ifdef ICE_CPP11_MAPPING + virtual void enableMetricsView(std::string, const ::Ice::Current&); + virtual void disableMetricsView(std::string, const ::Ice::Current&); + virtual IceMX::MetricsView getMetricsView(std::string, Ice::Long&, const ::Ice::Current&); + virtual IceMX::MetricsFailuresSeq getMapMetricsFailures(std::string, std::string, const ::Ice::Current&); + virtual IceMX::MetricsFailures getMetricsFailures(std::string, std::string, std::string, const ::Ice::Current&); +#else + virtual void enableMetricsView(const std::string&, const ::Ice::Current&); + virtual void disableMetricsView(const std::string&, const ::Ice::Current&); + virtual IceMX::MetricsView getMetricsView(const std::string&, Ice::Long&, const ::Ice::Current&); + virtual IceMX::MetricsFailuresSeq getMapMetricsFailures(const std::string&, const std::string&, + const ::Ice::Current&); + virtual IceMX::MetricsFailures getMetricsFailures(const std::string&, const std::string&, const std::string&, + const ::Ice::Current&); +#endif + std::vector getMaps(const std::string&) const; + + const Ice::LoggerPtr& getLogger() const; + +private: + + MetricsViewIPtr getMetricsView(const std::string&); + + bool addOrUpdateMap(const std::string&, const MetricsMapFactoryPtr&); + bool removeMap(const std::string&); + + std::map _views; + std::set _disabledViews; + std::map _factories; + + const Ice::LoggerPtr _logger; + Ice::PropertiesPtr _properties; +}; +ICE_DEFINE_PTR(MetricsAdminIPtr, MetricsAdminI); + +}; + +#endif diff --git a/Sources/IceCpp/include/Ice/MetricsFunctional.h b/Sources/IceCpp/include/Ice/MetricsFunctional.h new file mode 100644 index 0000000..3d4dc81 --- /dev/null +++ b/Sources/IceCpp/include/Ice/MetricsFunctional.h @@ -0,0 +1,159 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_METRICSFUNCTIONAL_H +#define ICE_METRICSFUNCTIONAL_H + +namespace IceInternal +{ + +template struct ReferenceWrapper +{ + static R* get(const R& v) + { + return const_cast(&v); + } +}; + +#ifdef ICE_CPP11_MAPPING // C++11 mapping +template struct ReferenceWrapper<::std::shared_ptr > +{ + static R* get(const ::std::shared_ptr& v) + { + return v.get(); + } +}; + +template struct ReferenceWrapper& > +{ + static R* get(const ::std::shared_ptr& v) + { + return v.get(); + } +}; +#else // C++98 mapping +template struct ReferenceWrapper > +{ + static R* get(const IceInternal::ProxyHandle& v) + { + return v.get(); + } +}; + +template struct ReferenceWrapper& > +{ + static R* get(const IceInternal::ProxyHandle& v) + { + return v.get(); + } +}; + +template struct ReferenceWrapper > +{ + static R* get(const IceInternal::Handle& v) + { + return v.get(); + } +}; + +template struct ReferenceWrapper& > +{ + static R* get(const IceInternal::Handle& v) + { + return v.get(); + } +}; +#endif + +template struct ReferenceWrapper +{ + static R* get(R* v) + { + return v; + } +}; + +template struct ReferenceWrapper +{ + static R* get(const R& v) + { + return const_cast(&v); + } +}; + +}; + +namespace IceMX +{ + +/// \cond INTERNAL +template struct ApplyOnMember +{ + ApplyOnMember(Y T::*m, Func f) : func(f), member(m) + { + } + + template + void operator()(const R& v) + { + func(IceInternal::ReferenceWrapper::get(v)->*member); + } + + Func func; + Y T::*member; +}; + +template struct Decrement +{ + void operator()(T& v) + { + --v; + } +}; + +template struct Increment +{ + void operator()(T& v) + { + ++v; + } +}; + +template struct Add +{ + Add(T v) : value(v) { } + + template + void operator()(Y& v) + { + v += value; + } + + T value; +}; + +template ApplyOnMember applyOnMember(Y T::*member, F func) +{ + return ApplyOnMember(member, func); +} + +template ApplyOnMember > add(Y T::*member, V value) +{ + return applyOnMember(member, Add(value)); +} + +template ApplyOnMember > inc(Y T::*member) +{ + return applyOnMember(member, Increment()); +} + +template ApplyOnMember > dec(Y T::*member) +{ + return applyOnMember(member, Decrement()); +} +/// \endcond + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/MetricsObserverI.h b/Sources/IceCpp/include/Ice/MetricsObserverI.h new file mode 100644 index 0000000..d2a3eea --- /dev/null +++ b/Sources/IceCpp/include/Ice/MetricsObserverI.h @@ -0,0 +1,669 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICEMX_METRICSOBSERVER_I_H +#define ICEMX_METRICSOBSERVER_I_H + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +namespace IceMX +{ + +/// \cond INTERNAL +template class MetricsHelperT +{ +public: + + virtual ~MetricsHelperT() + { + } + + virtual std::string operator()(const std::string&) const = 0; + + virtual void initMetrics(const ICE_INTERNAL_HANDLE&) const + { + // To be overriden in specialization to initialize state attributes + } + +protected: + + template class AttributeResolverT + { + class Resolver + { + public: + + Resolver(const std::string& name) : _name(name) + { + } + + virtual ~Resolver() + { + } + + virtual std::string operator()(const Helper* h) const = 0; + + protected: + + std::string _name; + }; + + public: + + AttributeResolverT() : _default(0) + { + } + + ~AttributeResolverT() + { + for(typename std::map::iterator p = _attributes.begin(); p != _attributes.end();++p) + { + delete p->second; + } + } + + std::string operator()(const Helper* helper, const std::string& attribute) const + { + typename std::map::const_iterator p = _attributes.find(attribute); + if(p == _attributes.end()) + { + if(attribute == "none") + { + return ""; + } + if(_default) + { + return (helper->*_default)(attribute); + } + throw std::invalid_argument(attribute); + } + return (*p->second)(helper); + } + + void + setDefault(std::string (Helper::*memberFn)(const std::string&) const) + { + _default = memberFn; + } + + template void + add(const std::string& name, Y Helper::*member) + { + _attributes.insert(typename std::map::value_type(name, new HelperMemberResolver(name, member))); + } + + template void + add(const std::string& name, Y (Helper::*memberFn)() const) + { + _attributes.insert(typename std::map::value_type(name, new HelperMemberFunctionResolver(name, memberFn))); + } + + template void + add(const std::string& name, O (Helper::*getFn)() const, Y I::*member) + { + _attributes.insert(typename std::map::value_type(name, new MemberResolver(name, getFn, member))); + } + + template void + add(const std::string& name, O (Helper::*getFn)() const, Y (I::*memberFn)() const) + { + _attributes.insert(typename std::map::value_type(name, new MemberFunctionResolver(name, getFn, + memberFn))); + } + +#if ICE_CPLUSPLUS >= 201703L + // + // Since C++17 the noexcept-specification is part of the function type and we need a separate + // overload to handle memberFn being noexcept + // + template void + add(const std::string& name, O (Helper::*getFn)() const, Y (I::*memberFn)() const noexcept) + { + _attributes.insert(typename std::map::value_type(name, new MemberFunctionResolver(name, getFn, + memberFn))); + } +#endif + + private: + + template class HelperMemberResolver : public Resolver + { + public: + + HelperMemberResolver(const std::string& name, Y Helper::*member) : Resolver(name), _member(member) + { + } + + virtual std::string operator()(const Helper* r) const + { + return toString(r->*_member); + } + + private: + + Y Helper::*_member; + }; + + template class HelperMemberFunctionResolver : public Resolver + { + public: + + HelperMemberFunctionResolver(const std::string& name, Y (Helper::*memberFn)() const) : + Resolver(name), _memberFn(memberFn) + { + } + + virtual std::string operator()(const Helper* r) const + { + return toString((r->*_memberFn)()); + } + + private: + + Y (Helper::*_memberFn)() const; + }; + + template class MemberResolver : public Resolver + { + public: + + MemberResolver(const std::string& name, O (Helper::*getFn)() const, Y I::*member) : + Resolver(name), _getFn(getFn), _member(member) + { + } + + virtual std::string operator()(const Helper* r) const + { + O o = (r->*_getFn)(); + I* v = dynamicCast(IceInternal::ReferenceWrapper::get(o)); + if(v) + { + return toString(v->*_member); + } + else + { + throw std::invalid_argument(Resolver::_name); + } + } + + private: + + O (Helper::*_getFn)() const; + Y I::*_member; + }; + + template class MemberFunctionResolver : public Resolver + { + public: + + MemberFunctionResolver(const std::string& name, O (Helper::*getFn)() const, Y (I::*memberFn)() const) : + Resolver(name), _getFn(getFn), _memberFn(memberFn) + { + } + + virtual std::string operator()(const Helper* r) const + { + O o = (r->*_getFn)(); + I* v = dynamicCast(IceInternal::ReferenceWrapper::get(o)); + if(v) + { + return toString((v->*_memberFn)()); + } + else + { + throw std::invalid_argument(Resolver::_name); + } + } + + private: + + O (Helper::*_getFn)() const; + Y (I::*_memberFn)() const; + }; + + template static I* + dynamicCast(V* v) + { + return dynamic_cast(v); + } + + template static I* + dynamicCast(Ice::EndpointInfo* v) + { + for(Ice::EndpointInfo* info = v; info; info = info->underlying.get()) + { + I* i = dynamic_cast(info); + if(i) + { + return i; + } + } + return 0; + } + + template static I* + dynamicCast(Ice::ConnectionInfo* v) + { + for(Ice::ConnectionInfo* info = v; info; info = info->underlying.get()) + { + I* i = dynamic_cast(info); + if(i) + { + return i; + } + } + return 0; + } + + template static std::string + toString(const I& v) + { + std::ostringstream os; + os << v; + return os.str(); + } + + static const std::string + toString(const Ice::ObjectPrxPtr& p) + { + return p->ice_toString(); + } + + static const std::string& + toString(const std::string& s) + { + return s; + } + + static std::string + toString(const ::Ice::EndpointPtr& e) + { + return e->toString(); + } + + static std::string + toString(const ::Ice::ConnectionPtr& e) + { + return e->toString(); + } + + static std::string + toString(bool v) + { + return v ? "true" : "false"; + } + + std::map _attributes; + std::string (Helper::*_default)(const std::string&) const; + }; +}; + +class Updater +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + virtual void update() = 0; +}; +ICE_DEFINE_PTR(UpdaterPtr, Updater); + +template class UpdaterT ICE_FINAL : public Updater +{ +public: + +#ifdef ICE_CPP11_MAPPING + UpdaterT(const std::shared_ptr& updater, void (T::*fn)()) : +#else + UpdaterT(T* updater, void (T::*fn)()) : +#endif + _updater(updater), + _fn(fn) + { + } + + virtual void update() + { + (_updater.get()->*_fn)(); + } + +private: + + const ICE_HANDLE _updater; + void (T::*_fn)(); +}; + +#ifdef ICE_CPP11_MAPPING +template UpdaterPtr +newUpdater(const std::shared_ptr& updater, void (T::*fn)()) +{ + if(updater) + { + return std::make_shared>(updater, fn); + } + else + { + return nullptr; + } +} +#else +template UpdaterPtr +newUpdater(const IceInternal::Handle& updater, void (T::*fn)()) +{ + if(updater) + { + return UpdaterPtr(new UpdaterT(updater.get(), fn)); + } + else + { + return 0; + } +} +#endif + +template class ObserverT : public virtual ::Ice::Instrumentation::Observer +{ +public: + + typedef T MetricsType; + typedef typename IceInternal::MetricsMapT::EntryTPtr EntryPtrType; + typedef std::vector EntrySeqType; + + ObserverT() : _previousDelay(0) + { + } + + virtual void + attach() + { + if(!_watch.isStarted()) + { + _watch.start(); + } + } + + virtual void + detach() + { + ::Ice::Long lifetime = _previousDelay + _watch.stop(); + for(typename EntrySeqType::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + (*p)->detach(lifetime); + } + } + + virtual void + failed(const std::string& exceptionName) + { + for(typename EntrySeqType::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + (*p)->failed(exceptionName); + } + } + + template void + forEach(const Function& func) + { + for(typename EntrySeqType::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + (*p)->execute(func); + } + } + + void + init(const MetricsHelperT& /*helper*/, EntrySeqType& objects, ObserverT* previous = 0) + { + _objects.swap(objects); + + if(previous == 0) + { + return; + } + + _previousDelay = previous->_previousDelay + previous->_watch.delay(); + // + // Detach entries from previous observer which are no longer + // attached to this new observer. + // + for(typename EntrySeqType::const_iterator p = previous->_objects.begin(); p != previous->_objects.end(); ++p) + { + if(find(_objects.begin(), _objects.end(), *p) == _objects.end()) + { + (*p)->detach(_previousDelay); + } + } + } + + EntryPtrType + getEntry(IceInternal::MetricsMapT* map) + { + for(typename EntrySeqType::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + if((*p)->getMap() == map) + { + return *p; + } + } + return ICE_NULLPTR; + } + + template ICE_INTERNAL_HANDLE + getObserver(const std::string& mapName, const MetricsHelperT& helper) + { + std::vector::EntryTPtr> metricsObjects; + for(typename EntrySeqType::const_iterator p = _objects.begin(); p != _objects.end(); ++p) + { + typename IceInternal::MetricsMapT::EntryTPtr e = (*p)->getMatching(mapName, helper); + if(e) + { + metricsObjects.push_back(e); + } + } + + if(metricsObjects.empty()) + { + return ICE_NULLPTR; + } + + ICE_INTERNAL_HANDLE obsv = ICE_MAKE_SHARED(ObserverImpl); + obsv->init(helper, metricsObjects); + return obsv; + } + +private: + + EntrySeqType _objects; + IceUtilInternal::StopWatch _watch; + IceUtil::Int64 _previousDelay; +}; + +template +class ObserverFactoryT : public Updater, private IceUtil::Mutex +{ +public: + +#ifdef ICE_CPP11_MAPPING + using ObserverImplPtrType = ::std::shared_ptr; + using MetricsType = typename ObserverImplType::MetricsType; + using MetricsMapSeqType = std::vector<::std::shared_ptr>>; +#else + typedef IceUtil::Handle ObserverImplPtrType; + typedef typename ObserverImplType::MetricsType MetricsType; + typedef std::vector > > MetricsMapSeqType; +#endif + + ObserverFactoryT(const IceInternal::MetricsAdminIPtr& metrics, const std::string& name) : + _metrics(metrics), _name(name), _enabled(0) + { + _metrics->registerMap(name, this); + } + + ~ObserverFactoryT() + { + if(_metrics) + { + _metrics->unregisterMap(_name); + } + } + + ObserverImplPtrType + getObserver(const MetricsHelperT& helper) + { + IceUtil::Mutex::Lock sync(*this); + if(!_metrics) + { + return ICE_NULLPTR; + } + + typename ObserverImplType::EntrySeqType metricsObjects; + for(typename MetricsMapSeqType::const_iterator p = _maps.begin(); p != _maps.end(); ++p) + { + typename ObserverImplType::EntryPtrType entry = (*p)->getMatching(helper); + if(entry) + { + metricsObjects.push_back(entry); + } + } + + if(metricsObjects.empty()) + { + return ICE_NULLPTR; + } + + ObserverImplPtrType obsv = ICE_MAKE_SHARED(ObserverImplType); + obsv->init(helper, metricsObjects); + return obsv; + } + + template ObserverImplPtrType + getObserver(const MetricsHelperT& helper, const ObserverPtrType& observer) + { +#ifdef ICE_CPP11_MAPPING + ObserverImplPtrType old = std::dynamic_pointer_cast(observer); +#else + ObserverImplPtrType old = ObserverImplPtrType::dynamicCast(observer); +#endif + + if(!observer || !old) + { + return getObserver(helper); + } + IceUtil::Mutex::Lock sync(*this); + if(!_metrics) + { + return ICE_NULLPTR; + } + + typename ObserverImplType::EntrySeqType metricsObjects; + for(typename MetricsMapSeqType::const_iterator p = _maps.begin(); p != _maps.end(); ++p) + { + typename ObserverImplType::EntryPtrType entry = (*p)->getMatching(helper, old->getEntry(p->get())); + if(entry) + { + metricsObjects.push_back(entry); + } + } + if(metricsObjects.empty()) + { + old->detach(); + return ICE_NULLPTR; + } + + ObserverImplPtrType obsv = ICE_MAKE_SHARED(ObserverImplType); + obsv->init(helper, metricsObjects, old.get()); + return obsv; + } + + template void + registerSubMap(const std::string& subMap, MetricsMap MetricsType::* member) + { + assert(_metrics); + _metrics->registerSubMap(_name, subMap, member); + } + + bool isEnabled() const + { + return _enabled != 0; + } + + virtual void update() + { + UpdaterPtr updater; + { + IceUtil::Mutex::Lock sync(*this); + if(!_metrics) + { + return; + } + + std::vector maps = _metrics->getMaps(_name); + _maps.clear(); + for(std::vector::const_iterator p = maps.begin(); p != maps.end(); ++p) + { +#ifdef ICE_CPP11_MAPPING + _maps.push_back(::std::dynamic_pointer_cast>(*p)); +#else + _maps.push_back(IceUtil::Handle >::dynamicCast(*p)); +#endif + assert(_maps.back()); + } + _enabled.exchange(_maps.empty() ? 0 : 1); + updater = _updater; + } + + if(updater) + { + updater->update(); + } + } + + void setUpdater(const UpdaterPtr& updater) + { + IceUtil::Mutex::Lock sync(*this); + _updater = updater; + } + + void destroy() + { + IceUtil::Mutex::Lock sync(*this); + _metrics = 0; + _maps.clear(); + } + +private: + + IceInternal::MetricsAdminIPtr _metrics; + const std::string _name; + MetricsMapSeqType _maps; + // + // TODO: Replace by std::atomic when it becomes widely + // available. + // + IceUtilInternal::Atomic _enabled; + UpdaterPtr _updater; +}; + +typedef ObserverT ObserverI; +/// \endcond + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/NativePropertiesAdmin.h b/Sources/IceCpp/include/Ice/NativePropertiesAdmin.h new file mode 100644 index 0000000..849a0a3 --- /dev/null +++ b/Sources/IceCpp/include/Ice/NativePropertiesAdmin.h @@ -0,0 +1,86 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROPERTIES_ADMIN_H +#define ICE_PROPERTIES_ADMIN_H + +#include + +namespace Ice +{ + +#ifndef ICE_CPP11_MAPPING +/** + * An application can be notified when its configuration properties are modified + * via the Properties admin facet. The application must define a subclass of + * PropertiesAdminUpdateCallback and register it with the facet. The facet + * implements the class NativePropertiesAdmin, so the application needs to + * downcast the facet to this type in order to register the callback. + * + * For example: + * + * \code + * Ice::ObjectPtr obj = communicator->findAdminFacet("Properties"); + * assert(obj); // May be null if the facet is not enabled + * NativePropertiesAdminPtr facet = NativePropertiesAdminPtr::dynamicCast(obj); + * PropertiesAdminUpdateCallbackPtr myCallback = ...; + * facet->addUpdateCallback(myCallback); + * \endcode + * + * Ice ignores any exceptions raised by the callback. + * \headerfile Ice/Ice.h + */ +class ICE_API PropertiesAdminUpdateCallback : public virtual Ice::LocalObject +{ +public: + + virtual ~PropertiesAdminUpdateCallback(); + + /** + * Called when the communicator's properties have been updated. + * @param d A dictionary containing the properties that were added, changed or removed, + * with a removed property denoted by an entry whose value is an empty string. + */ + virtual void updated(const PropertyDict& d) = 0; +}; +typedef IceUtil::Handle PropertiesAdminUpdateCallbackPtr; +#endif + +/** + * Base class for the Properties admin facet. + * \headerfile Ice/Ice.h + */ +class ICE_API NativePropertiesAdmin +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + virtual ~NativePropertiesAdmin(); + +#ifdef ICE_CPP11_MAPPING + /** + * Register an update callback that will be invoked when property updates occur. + * @param cb The callback. + */ + virtual std::function addUpdateCallback(std::function cb) = 0; +#else + /** + * Register an update callback that will be invoked when property updates occur. + * @param cb The callback. + */ + virtual void addUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb) = 0; + /** + * Remove an update callback. + * @param cb The callback to be removed. + */ + virtual void removeUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb) = 0; +#endif +}; +ICE_DEFINE_PTR(NativePropertiesAdminPtr, NativePropertiesAdmin); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Network.h b/Sources/IceCpp/include/Ice/Network.h new file mode 100644 index 0000000..866fa14 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Network.h @@ -0,0 +1,289 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_NETWORK_H +#define ICE_NETWORK_H + +#ifdef __hpux +# define _XOPEN_SOURCE_EXTENDED +#endif + +#include + +#include +#include +#include // For setTcpBufSize +#include // For setTcpBufSize +#include +#include +#include + +#if defined(_WIN32) +# include +# include +# if !defined(__MINGW32__) +typedef int ssize_t; +# endif +#else +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#if defined(__linux__) && !defined(ICE_NO_EPOLL) +# define ICE_USE_EPOLL 1 +#elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && TARGET_OS_IPHONE == 0 && !defined(ICE_NO_KQUEUE) +# define ICE_USE_KQUEUE 1 +#elif defined(__APPLE__) && !defined(ICE_NO_CFSTREAM) +# define ICE_USE_CFSTREAM 1 +#elif defined(_WIN32) +# if !defined(ICE_NO_IOCP) +# define ICE_USE_IOCP 1 +# else +# define ICE_USE_SELECT 1 +# endif +#else +# define ICE_USE_POLL 1 +#endif + +#if defined(_WIN32) || defined(__osf__) +typedef int socklen_t; +#endif + +#if !defined(_WIN32) +# define SOCKET int +# define INVALID_SOCKET -1 +# define SOCKET_ERROR -1 +#endif + +#ifndef SHUT_RD +# define SHUT_RD 0 +#endif + +#ifndef SHUT_WR +# define SHUT_WR 1 +#endif + +#ifndef SHUT_RDWR +# define SHUT_RDWR 2 +#endif + +#ifndef NETDB_INTERNAL +# define NETDB_INTERNAL -1 +#endif + +#ifndef NETDB_SUCCESS +# define NETDB_SUCCESS 0 +#endif + +#if defined(__MINGW32__) && !defined WSAID_CONNECTEX +# define WSAID_CONNECTEX {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}} +# define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} +# define SO_UPDATE_ACCEPT_CONTEXT 0x700B +# define SO_UPDATE_CONNECT_CONTEXT 0x7010 + typedef BOOL (PASCAL FAR * LPFN_CONNECTEX) (IN SOCKET s, IN const struct sockaddr FAR *name, IN int namelen, + IN PVOID lpSendBuffer OPTIONAL, IN DWORD dwSendDataLength, + OUT LPDWORD lpdwBytesSent, IN LPOVERLAPPED lpOverlapped); + + typedef BOOL (PASCAL FAR * LPFN_ACCEPTEX)(IN SOCKET sListenSocket, IN SOCKET sAcceptSocket, + IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, + IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, + OUT LPDWORD lpdwBytesReceived, IN LPOVERLAPPED lpOverlapped); +#endif + +namespace IceInternal +{ + +union Address +{ + Address() + { + memset(&saStorage, 0, sizeof(sockaddr_storage)); + saStorage.ss_family = AF_UNSPEC; + } + + sockaddr sa; + sockaddr_in saIn; + sockaddr_in6 saIn6; + sockaddr_storage saStorage; +}; + +enum SocketOperation +{ + SocketOperationNone = 0, + SocketOperationRead = 1, + // With BSD sockets, write and connect readiness are the same so + // we use the same value for both. + SocketOperationWrite = 2, +#ifdef ICE_USE_CFSTREAM + SocketOperationConnect = 4 +#else + SocketOperationConnect = 2 +#endif +}; + +// +// AsyncInfo struct for Windows IOCP holds the result of +// asynchronous operations after it completed. +// +#if defined(ICE_USE_IOCP) +struct ICE_API AsyncInfo : WSAOVERLAPPED +{ + AsyncInfo(SocketOperation); + + SocketOperation status; + WSABUF buf; + DWORD flags; + DWORD count; + DWORD error; +}; +#endif + +class ICE_API ReadyCallback : public virtual ::IceUtil::Shared +{ +public: + + virtual ~ReadyCallback(); + + virtual void ready(SocketOperation, bool) = 0; +}; +typedef IceUtil::Handle ReadyCallbackPtr; + +class ICE_API NativeInfo : public virtual IceUtil::Shared +{ +public: + + virtual ~NativeInfo(); + + NativeInfo(SOCKET socketFd = INVALID_SOCKET) : _fd(socketFd) +#if !defined(ICE_USE_IOCP) + , _newFd(INVALID_SOCKET) +#endif + { + } + + SOCKET fd() const + { + return _fd; + } + + void setReadyCallback(const ReadyCallbackPtr& callback); + + void ready(SocketOperation operation, bool value) + { + assert(_readyCallback); + _readyCallback->ready(operation, value); + } + + // + // This is implemented by transceiver and acceptor implementations. + // +#if defined(ICE_USE_IOCP) + virtual AsyncInfo* getAsyncInfo(SocketOperation) = 0; + void initialize(HANDLE, ULONG_PTR); + void completed(SocketOperation); +#else + bool newFd(); + void setNewFd(SOCKET); +#endif + +protected: + + SOCKET _fd; + ReadyCallbackPtr _readyCallback; + +#if defined(ICE_USE_IOCP) + HANDLE _handle; + ULONG_PTR _key; +#else + SOCKET _newFd; +#endif +}; +typedef IceUtil::Handle NativeInfoPtr; + +ICE_API bool noMoreFds(int); +ICE_API std::string errorToStringDNS(int); +ICE_API std::vector

getAddresses(const std::string&, int, ProtocolSupport, Ice::EndpointSelectionType, bool, + bool); +ICE_API ProtocolSupport getProtocolSupport(const Address&); +ICE_API Address getAddressForServer(const std::string&, int, ProtocolSupport, bool, bool); +ICE_API int compareAddress(const Address&, const Address&); + +ICE_API bool isIPv6Supported(); +ICE_API SOCKET createSocket(bool, const Address&); +ICE_API SOCKET createServerSocket(bool, const Address&, ProtocolSupport); +ICE_API void closeSocketNoThrow(SOCKET); +ICE_API void closeSocket(SOCKET); + +ICE_API std::string addrToString(const Address&); +ICE_API void fdToLocalAddress(SOCKET, Address&); +ICE_API bool fdToRemoteAddress(SOCKET, Address&); +ICE_API std::string fdToString(SOCKET, const NetworkProxyPtr&, const Address&); +ICE_API std::string fdToString(SOCKET); +ICE_API void fdToAddressAndPort(SOCKET, std::string&, int&, std::string&, int&); +ICE_API void addrToAddressAndPort(const Address&, std::string&, int&); +ICE_API std::string addressesToString(const Address&, const Address&, bool); +ICE_API bool isAddressValid(const Address&); + +ICE_API std::vector getHostsForEndpointExpand(const std::string&, ProtocolSupport, bool); +ICE_API std::vector getInterfacesForMulticast(const std::string&, ProtocolSupport); + +ICE_API std::string inetAddrToString(const Address&); +ICE_API int getPort(const Address&); +ICE_API void setPort(Address&, int); + +ICE_API bool isMulticast(const Address&); +ICE_API void setTcpBufSize(SOCKET, const ProtocolInstancePtr&); +ICE_API void setTcpBufSize(SOCKET, int, int, const ProtocolInstancePtr&); + +ICE_API void setBlock(SOCKET, bool); +ICE_API void setSendBufferSize(SOCKET, int); +ICE_API int getSendBufferSize(SOCKET); +ICE_API void setRecvBufferSize(SOCKET, int); +ICE_API int getRecvBufferSize(SOCKET); + +ICE_API void setMcastGroup(SOCKET, const Address&, const std::string&); +ICE_API void setMcastInterface(SOCKET, const std::string&, const Address&); +ICE_API void setMcastTtl(SOCKET, int, const Address&); +ICE_API void setReuseAddress(SOCKET, bool); +ICE_API Address doBind(SOCKET, const Address&, const std::string& intf = ""); +ICE_API void doListen(SOCKET, int); + +ICE_API bool interrupted(); +ICE_API bool acceptInterrupted(); +ICE_API bool noBuffers(); +ICE_API bool wouldBlock(); +ICE_API bool notConnected(); +ICE_API bool recvTruncated(); + +ICE_API bool connectFailed(); +ICE_API bool connectionRefused(); +ICE_API bool connectInProgress(); +ICE_API bool connectionLost(); + +ICE_API bool doConnect(SOCKET, const Address&, const Address&); +ICE_API void doFinishConnect(SOCKET); +ICE_API SOCKET doAccept(SOCKET); + +ICE_API void createPipe(SOCKET fds[2]); + +ICE_API int getSocketErrno(); + +ICE_API Address getNumericAddress(const std::string&); + +#if defined(ICE_USE_IOCP) +ICE_API void doConnectAsync(SOCKET, const Address&, const Address&, AsyncInfo&); +ICE_API void doFinishConnectAsync(SOCKET, AsyncInfo&); +#endif + +ICE_API bool isIpAddress(const std::string&); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/NetworkF.h b/Sources/IceCpp/include/Ice/NetworkF.h new file mode 100644 index 0000000..56f0b27 --- /dev/null +++ b/Sources/IceCpp/include/Ice/NetworkF.h @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_NETWORK_F_H +#define ICE_NETWORK_F_H + +#include + +#include + +namespace IceInternal +{ + +union Address; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/NetworkProxy.h b/Sources/IceCpp/include/Ice/NetworkProxy.h new file mode 100644 index 0000000..22714af --- /dev/null +++ b/Sources/IceCpp/include/Ice/NetworkProxy.h @@ -0,0 +1,72 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_NETWORK_PROXY_H +#define ICE_NETWORK_PROXY_H + +#include +#include + +namespace IceInternal +{ + +class ICE_API NetworkProxy : public virtual IceUtil::Shared +{ +public: + + virtual ~NetworkProxy(); + + // + // Write the connection request on the connection established + // with the network proxy server. This is called right after + // the connection establishment succeeds. + // + virtual void beginWrite(const Address&, Buffer&) = 0; + virtual SocketOperation endWrite(Buffer&) = 0; + + // + // Once the connection request has been sent, this is called + // to prepare and read the response from the proxy server. + // + virtual void beginRead(Buffer&) = 0; + virtual SocketOperation endRead(Buffer&) = 0; + + // + // This is called when the response from the proxy has been + // read. The proxy should copy the extra read data (if any) in the + // given byte vector. + // + virtual void finish(Buffer&, Buffer&) = 0; + + // + // If the proxy host needs to be resolved, this should return + // a new NetworkProxy containing the IP address of the proxy. + // This is called from the endpoint host resolver thread, so + // it's safe if this this method blocks. + // + virtual NetworkProxyPtr resolveHost(ProtocolSupport) const = 0; + + // + // Returns the IP address of the network proxy. This method + // must not block. It's only called on a network proxy object + // returned by resolveHost(). + // + virtual Address getAddress() const = 0; + + // + // Returns the name of the proxy, used for tracing purposes. + // + virtual std::string getName() const = 0; + + // + // Returns the protocols supported by the proxy. + // + virtual ProtocolSupport getProtocolSupport() const = 0; +}; + +NetworkProxyPtr createNetworkProxy(const Ice::PropertiesPtr&, ProtocolSupport); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/NetworkProxyF.h b/Sources/IceCpp/include/Ice/NetworkProxyF.h new file mode 100644 index 0000000..eaf9811 --- /dev/null +++ b/Sources/IceCpp/include/Ice/NetworkProxyF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_NETWORK_PROXY_F_H +#define ICE_NETWORK_PROXY_F_H + +#include + +#include + +namespace IceInternal +{ + +class NetworkProxy; +ICE_API IceUtil::Shared* upCast(NetworkProxy*); +typedef Handle NetworkProxyPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/OSLogLoggerI.h b/Sources/IceCpp/include/Ice/OSLogLoggerI.h new file mode 100644 index 0000000..16da911 --- /dev/null +++ b/Sources/IceCpp/include/Ice/OSLogLoggerI.h @@ -0,0 +1,40 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OSLOG_LOGGER_I_H +#define ICE_OSLOG_LOGGER_I_H + +#ifdef ICE_SWIFT + +#include +#include +#include + +namespace Ice +{ + +class OSLogLoggerI : public Logger +{ +public: + + OSLogLoggerI(const std::string&); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual LoggerPtr cloneWithPrefix(const std::string&); + +private: + + const std::string _prefix; + IceInternal::UniqueRef _log; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/Object.h b/Sources/IceCpp/include/Ice/Object.h new file mode 100644 index 0000000..7fb3afd --- /dev/null +++ b/Sources/IceCpp/include/Ice/Object.h @@ -0,0 +1,507 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBJECT_H +#define ICE_OBJECT_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +} + +namespace IceInternal +{ + +class Incoming; +class Direct; +class GCVisitor; + +} + +namespace Ice +{ + +/** A default-initialized Current instance. */ +ICE_API extern const Current emptyCurrent; + +#ifndef ICE_CPP11_MAPPING +/** + * Abstract callback class for an asynchronous dispatch interceptor. + * \headerfile Ice/Ice.h + */ +class ICE_API DispatchInterceptorAsyncCallback : public virtual IceUtil::Shared +{ +public: + + virtual ~DispatchInterceptorAsyncCallback(); + + /** Called when the dispatch completes successfully. */ + virtual bool response() = 0; + + /** + * Called when the dispatch fails with an exception. + * @param ex The exception that caused the failure. + */ + virtual bool exception(const std::exception& ex) = 0; + + /** + * Called when the dispatch fails with an unknown exception. + */ + virtual bool exception() = 0; +}; +ICE_DEFINE_PTR(DispatchInterceptorAsyncCallbackPtr, DispatchInterceptorAsyncCallback); +#endif + +/** + * Encapsulates details about a dispatch request. + * \headerfile Ice/Ice.h + */ +class ICE_API Request +{ +public: + + virtual ~Request(); + + /** + * Obtains the Current object associated with the request. + * @return The Current object. + */ + virtual const Current& getCurrent() = 0; +}; + +#ifdef ICE_CPP11_MAPPING +/** + * The base class for servants. + * \headerfile Ice/Ice.h + */ +class ICE_API Object +{ +public: + + virtual ~Object() = default; + + /** + * Tests whether this object supports a specific Slice interface. + * @param s The type ID of the Slice interface to test against. + * @param current The Current object for the invocation. + * @return True if this object has the interface + * specified by s or derives from the interface + * specified by s. + */ + virtual bool ice_isA(std::string s, const Current& current) const; + /// \cond INTERNAL + bool _iceD_ice_isA(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Tests whether this object can be reached. + * @param current The Current object for the invocation. + */ + virtual void ice_ping(const Current& current) const; + /// \cond INTERNAL + bool _iceD_ice_ping(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Returns the Slice type IDs of the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type IDs of the interfaces supported by this object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + virtual std::vector< std::string> ice_ids(const Current& current) const; + /// \cond INTERNAL + bool _iceD_ice_ids(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Returns the Slice type ID of the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + virtual std::string ice_id(const Current& current) const; + /// \cond INTERNAL + bool _iceD_ice_id(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Obtains the Slice type ID of this type. + * @return The return value is always "::Ice::Object". + */ + static const std::string& ice_staticId(); + + /** + * Dispatches an invocation to a servant. This method is used by dispatch interceptors to forward an invocation + * to a servant (or to another interceptor). + * @param request The details of the invocation. + * @param response A function that should return true if Ice should send the response to the client. A null + * value is equivalent to a function that returns true. + * @param error A function that should return true if Ice should send the exception to the client. A null + * value is equivalent to a function that returns true. + * @return True if the request completed synchronously, false if the request will be completed asynchronously. + * @throws UserException A user exception that propagates out of this method will be marshaled as the result. + */ + virtual bool ice_dispatch(Ice::Request& request, + std::function response = nullptr, + std::function error = nullptr); + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Holds the results of a call to ice_invoke. + */ + struct Ice_invokeResult + { + /** + * Indicates whether the invocation resulted in success (true) or a user exception (false). + */ + bool returnValue; + + /** + * Holds an encapsulation of the encoded results. If returnValue is true, this contains the encoded + * out parameters. If returnValue is false, this contains the encoded user exception. + */ + std::vector<::Ice::Byte> outParams; + }; + +protected: + + /// \cond INTERNAL + static void _iceCheckMode(OperationMode, OperationMode); + /// \endcond +}; +#else +/** + * The base class for servants. + * \headerfile Ice/Ice.h + */ +class ICE_API Object : public virtual IceUtil::Shared +{ +public: + + virtual bool operator==(const Object&) const; + virtual bool operator<(const Object&) const; + + /** + * Tests whether this object supports a specific Slice interface. + * @param s The type ID of the Slice interface to test against. + * @param current The Current object for the invocation. + * @return True if this object has the interface + * specified by s or derives from the interface + * specified by s. + */ + virtual bool ice_isA(const std::string& s, const Current& current = Ice::emptyCurrent) const; + /// \cond INTERNAL + bool _iceD_ice_isA(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Tests whether this object can be reached. + * @param current The Current object for the invocation. + */ + virtual void ice_ping(const Current& current = Ice::emptyCurrent) const; + /// \cond INTERNAL + bool _iceD_ice_ping(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Returns the Slice type IDs of the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type IDs of the interfaces supported by this object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + virtual std::vector< std::string> ice_ids(const Current& current = Ice::emptyCurrent) const; + /// \cond INTERNAL + bool _iceD_ice_ids(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Returns the Slice type ID of the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + virtual const std::string& ice_id(const Current& current = Ice::emptyCurrent) const; + /// \cond INTERNAL + bool _iceD_ice_id(IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Returns the Freeze metadata attributes for an operation. + * + * @param operation The name of the operation. + * @return The least significant bit indicates whether the operation is a read + * or write operation. If the bit is set, the operation is a write operation. + * The expression ice_operationAttributes("op") & 0x1 is true if + * the operation has a ["freeze:write"] metadata directive. + *

+ * The second and third least significant bit indicate the transactional mode + * of the operation. The expression ice_operationAttributes("op") & 0x6 >> 1 + * indicates the transactional mode as follows: + *

+ *
0
+ *
["freeze:read:supports"]
+ *
1
+ *
["freeze:read:mandatory"] or ["freeze:write:mandatory"]
+ *
2
+ *
["freeze:read:required"] or ["freeze:write:required"]
+ *
3
+ *
["freeze:read:never"]
+ *
+ * + * Refer to the Freeze manual for more information on the TransactionalEvictor. + */ + virtual Int ice_operationAttributes(const std::string& operation) const; + + /// \cond STREAM + virtual void _iceWrite(Ice::OutputStream*) const; + virtual void _iceRead(Ice::InputStream*); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceGcVisit(IceInternal::GCVisitor&) { return false; } + /// \endcond + + /** + * Determines whether this object, and by extension the graph of all objects reachable from this object, + * are eligible for garbage collection when all external references to the graph have been released. + * @param b True if the object is eligible, false otherwise. + */ + virtual void ice_collectable(bool b); + + /** + * The Ice run time invokes this method prior to marshaling an object's data members. This allows a subclass + * to override this method in order to validate its data members. + */ + virtual void ice_preMarshal(); + + /** + * The Ice run time invokes this method vafter unmarshaling an object's data members. This allows a + * subclass to override this method in order to perform additional initialization. + */ + virtual void ice_postUnmarshal(); + + /** + * Obtains the Slice type ID of this type. + * @return The return value is always "::Ice::Object". + */ + static const std::string& ice_staticId(); + + /** + * Returns a shallow copy of the object. + * @return The cloned object. + */ + virtual ObjectPtr ice_clone() const; + + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the value has a preserved-slice base class and has been sliced during + * unmarshaling of the value, nil otherwise. + */ + virtual SlicedDataPtr ice_getSlicedData() const; + + /** + * Dispatches an invocation to a servant. This method is used by dispatch interceptors to forward an invocation + * to a servant (or to another interceptor). + * @param request The details of the invocation. + * @param cb The asynchronous callback object. + * @return True if the request completed synchronously, false if the request will be completed asynchronously. + * @throws UserException A user exception that propagates out of this method will be marshaled as the result. + */ + virtual bool ice_dispatch(Ice::Request& request, const DispatchInterceptorAsyncCallbackPtr& cb = 0); + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + Object() {} // This class is abstract. +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-copy-dtor" +#endif + virtual ~Object() {} +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(Ice::OutputStream*) const {} + virtual void _iceReadImpl(Ice::InputStream*) {} + /// \endcond + + /// \cond INTERNAL + static void _iceCheckMode(OperationMode, OperationMode); + /// \endcond +}; +#endif + +/** + * Base class for dynamic dispatch servants. A server application derives a concrete servant class + * from Blobject that implements the ice_invoke method. + * \headerfile Ice/Ice.h + */ +class ICE_API Blobject : public virtual Object +{ +public: + + /** + * Dispatch an incoming request. + * + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param outEncaps An encapsulation containing the encoded results for the operation. + * @param current The Current object for the invocation. + * @return True if the operation completed successfully, in which case outEncaps contains + * an encapsulation of the encoded results, or false if the operation raised a user exception, + * in which case outEncaps contains an encapsulation of the encoded user exception. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual bool ice_invoke(ICE_IN(std::vector) inEncaps, std::vector& outEncaps, + const Current& current) = 0; + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond +}; + +/** + * Base class for dynamic dispatch servants that uses the array mapping. A server application + * derives a concrete servant class from Blobject that implements the ice_invoke method. + * \headerfile Ice/Ice.h + */ +class ICE_API BlobjectArray : public virtual Object +{ +public: + + /** + * Dispatch an incoming request. + * + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param outEncaps An encapsulation containing the encoded results for the operation. + * @param current The Current object for the invocation. + * @return True if the operation completed successfully, in which case outEncaps contains + * an encapsulation of the encoded results, or false if the operation raised a user exception, + * in which case outEncaps contains an encapsulation of the encoded user exception. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual bool ice_invoke(ICE_IN(std::pair) inEncaps, std::vector& outEncaps, + const Current& current) = 0; + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond +}; + +/** + * Base class for asynchronous dynamic dispatch servants. A server application derives a concrete + * servant class from Blobject that implements the ice_invokeAsync method. + * \headerfile Ice/Ice.h + */ +class ICE_API BlobjectAsync : public virtual Object +{ +public: + +#ifdef ICE_CPP11_MAPPING + /** + * Dispatch an incoming request asynchronously. + * + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param response A callback the implementation should invoke when the invocation completes + * successfully or with a user exception. See the description of Blobject::ice_invoke for + * the semantics. + * @param error A callback the implementation should invoke when the invocation completes + * with an exception. + * @param current The Current object for the invocation. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual void ice_invokeAsync(std::vector inEncaps, + std::function&)> response, + std::function error, + const Current& current) = 0; +#else + /** + * Dispatch an incoming request asynchronously. + * + * @param cb The callback to invoke when the invocation completes. + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param current The Current object for the invocation. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual void ice_invoke_async(const AMD_Object_ice_invokePtr& cb, const std::vector& inEncaps, + const Current& current) = 0; +#endif + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond +}; + +/** + * Base class for asynchronous dynamic dispatch servants that uses the array mapping. A server application + * derives a concrete servant class from Blobject that implements the ice_invokeAsync method. + * \headerfile Ice/Ice.h + */ +class ICE_API BlobjectArrayAsync : public virtual Object +{ +public: + +#ifdef ICE_CPP11_MAPPING + /** + * Dispatch an incoming request asynchronously. + * + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param response A callback the implementation should invoke when the invocation completes + * successfully or with a user exception. See the description of Blobject::ice_invoke for + * the semantics. + * @param error A callback the implementation should invoke when the invocation completes + * with an exception. + * @param current The Current object for the invocation. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual void ice_invokeAsync(std::pair inEncaps, + std::function&)> response, + std::function error, + const Current& current) = 0; +#else + /** + * Dispatch an incoming request asynchronously. + * + * @param cb The callback to invoke when the invocation completes. + * @param inEncaps An encapsulation containing the encoded in-parameters for the operation. + * @param current The Current object for the invocation. + * @throws UserException A user exception can be raised directly and the + * run time will marshal it. + */ + virtual void ice_invoke_async(const AMD_Object_ice_invokePtr& cb, + const std::pair& inEncaps, + const Current& current) = 0; +#endif + + /// \cond INTERNAL + virtual bool _iceDispatch(IceInternal::Incoming&, const Current&); + /// \endcond +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectAdapter.h b/Sources/IceCpp/include/Ice/ObjectAdapter.h new file mode 100644 index 0000000..fe685c5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectAdapter.h @@ -0,0 +1,1185 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapter.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ObjectAdapter_h__ +#define __Ice_ObjectAdapter_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ObjectAdapter; + +} + +namespace Ice +{ + +/** + * The object adapter provides an up-call interface from the Ice + * run time to the implementation of Ice objects. + * + * The object adapter is responsible for receiving requests + * from endpoints, and for mapping between servants, identities, and + * proxies. + * @see Communicator + * @see ServantLocator + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectAdapter +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectAdapter(); + + /** + * Get the name of this object adapter. + * @return This object adapter's name. + */ + virtual ::std::string getName() const noexcept = 0; + + /** + * Get the communicator this object adapter belongs to. + * @return This object adapter's communicator. + * @see Communicator + */ + virtual ::std::shared_ptr<::Ice::Communicator> getCommunicator() const noexcept = 0; + + /** + * Activate all endpoints that belong to this object adapter. + * After activation, the object adapter can dispatch requests + * received through its endpoints. + * @see #hold + * @see #deactivate + */ + virtual void activate() = 0; + + /** + * Temporarily hold receiving and dispatching requests. The object + * adapter can be reactivated with the {@link #activate} operation. + * + *

Holding is not immediate, i.e., after {@link #hold} + * returns, the object adapter might still be active for some + * time. You can use {@link #waitForHold} to wait until holding is + * complete. + * @see #activate + * @see #deactivate + * @see #waitForHold + */ + virtual void hold() = 0; + + /** + * Wait until the object adapter holds requests. Calling {@link #hold} + * initiates holding of requests, and {@link #waitForHold} only returns + * when holding of requests has been completed. + * @see #hold + * @see #waitForDeactivate + * @see Communicator#waitForShutdown + */ + virtual void waitForHold() = 0; + + /** + * Deactivate all endpoints that belong to this object adapter. + * After deactivation, the object adapter stops receiving + * requests through its endpoints. Object adapters that have been + * deactivated must not be reactivated again, and cannot be used + * otherwise. Attempts to use a deactivated object adapter raise + * {@link ObjectAdapterDeactivatedException} however, attempts to + * {@link #deactivate} an already deactivated object adapter are + * ignored and do nothing. Once deactivated, it is possible to + * destroy the adapter to clean up resources and then create and + * activate a new adapter with the same name. + * + *

After {@link #deactivate} returns, no new requests + * are processed by the object adapter. However, requests that + * have been started before {@link #deactivate} was called might + * still be active. You can use {@link #waitForDeactivate} to wait + * for the completion of all requests for this object adapter. + * @see #activate + * @see #hold + * @see #waitForDeactivate + * @see Communicator#shutdown + */ + virtual void deactivate() noexcept = 0; + + /** + * Wait until the object adapter has deactivated. Calling + * {@link #deactivate} initiates object adapter deactivation, and + * {@link #waitForDeactivate} only returns when deactivation has + * been completed. + * @see #deactivate + * @see #waitForHold + * @see Communicator#waitForShutdown + */ + virtual void waitForDeactivate() noexcept = 0; + + /** + * Check whether object adapter has been deactivated. + * @return Whether adapter has been deactivated. + * @see Communicator#shutdown + */ + virtual bool isDeactivated() const noexcept = 0; + + /** + * Destroys the object adapter and cleans up all resources held by + * the object adapter. If the object adapter has not yet been + * deactivated, destroy implicitly initiates the deactivation + * and waits for it to finish. Subsequent calls to destroy are + * ignored. Once destroy has returned, it is possible to create + * another object adapter with the same name. + * @see #deactivate + * @see #waitForDeactivate + * @see Communicator#destroy + */ + virtual void destroy() noexcept = 0; + + /** + * Add a servant to this object adapter's Active Servant Map. Note + * that one servant can implement several Ice objects by registering + * the servant with multiple identities. Adding a servant with an + * identity that is in the map already throws {@link AlreadyRegisteredException}. + * @param servant The servant to add. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @return A proxy that matches the given identity and this object + * adapter. + * @see Identity + * @see #addFacet + * @see #addWithUUID + * @see #remove + * @see #find + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> add(const ::std::shared_ptr& servant, const Identity& id) = 0; + + /** + * Like {@link #add}, but with a facet. Calling add(servant, id) + * is equivalent to calling {@link #addFacet} with an empty facet. + * @param servant The servant to add. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @param facet The facet. An empty facet means the default facet. + * @return A proxy that matches the given identity, facet, and + * this object adapter. + * @see Identity + * @see #add + * @see #addFacetWithUUID + * @see #removeFacet + * @see #findFacet + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> addFacet(const ::std::shared_ptr& servant, const Identity& id, const ::std::string& facet) = 0; + + /** + * Add a servant to this object adapter's Active Servant Map, + * using an automatically generated UUID as its identity. Note that + * the generated UUID identity can be accessed using the proxy's + * ice_getIdentity operation. + * @param servant The servant to add. + * @return A proxy that matches the generated UUID identity and + * this object adapter. + * @see Identity + * @see #add + * @see #addFacetWithUUID + * @see #remove + * @see #find + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> addWithUUID(const ::std::shared_ptr& servant) = 0; + + /** + * Like {@link #addWithUUID}, but with a facet. Calling + * addWithUUID(servant) is equivalent to calling + * {@link #addFacetWithUUID} with an empty facet. + * @param servant The servant to add. + * @param facet The facet. An empty facet means the default + * facet. + * @return A proxy that matches the generated UUID identity, + * facet, and this object adapter. + * @see Identity + * @see #addFacet + * @see #addWithUUID + * @see #removeFacet + * @see #findFacet + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> addFacetWithUUID(const ::std::shared_ptr& servant, const ::std::string& facet) = 0; + + /** + * Add a default servant to handle requests for a specific + * category. Adding a default servant for a category for + * which a default servant is already registered throws + * {@link AlreadyRegisteredException}. To dispatch operation + * calls on servants, the object adapter tries to find a servant + * for a given Ice object identity and facet in the following + * order: + * + *
    + * + *
  1. The object adapter tries to find a servant for the identity + * and facet in the Active Servant Map.
  2. + * + *
  3. If no servant has been found in the Active Servant Map, the + * object adapter tries to find a default servant for the category + * component of the identity.
  4. + * + *
  5. If no servant has been found by any of the preceding steps, + * the object adapter tries to find a default servant for an empty + * category, regardless of the category contained in the identity.
  6. + * + *
  7. If no servant has been found by any of the preceding steps, + * the object adapter gives up and the caller receives + * {@link ObjectNotExistException} or {@link FacetNotExistException}.
  8. + * + *
+ * @param servant The default servant. + * @param category The category for which the default servant is + * registered. An empty category means it will handle all categories. + * @see #removeDefaultServant + * @see #findDefaultServant + */ + virtual void addDefaultServant(const ::std::shared_ptr& servant, const ::std::string& category) = 0; + + /** + * Remove a servant (that is, the default facet) from the object + * adapter's Active Servant Map. + * @param id The identity of the Ice object that is implemented by + * the servant. If the servant implements multiple Ice objects, + * {@link #remove} has to be called for all those Ice objects. + * Removing an identity that is not in the map throws + * {@link NotRegisteredException}. + * @return The removed servant. + * @see Identity + * @see #add + * @see #addWithUUID + */ + virtual ::std::shared_ptr<::Ice::Object> remove(const Identity& id) = 0; + + /** + * Like {@link #remove}, but with a facet. Calling remove(id) + * is equivalent to calling {@link #removeFacet} with an empty facet. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @param facet The facet. An empty facet means the default facet. + * @return The removed servant. + * @see Identity + * @see #addFacet + * @see #addFacetWithUUID + */ + virtual ::std::shared_ptr<::Ice::Object> removeFacet(const Identity& id, const ::std::string& facet) = 0; + + /** + * Remove all facets with the given identity from the Active + * Servant Map. The operation completely removes the Ice object, + * including its default facet. Removing an identity that + * is not in the map throws {@link NotRegisteredException}. + * @param id The identity of the Ice object to be removed. + * @return A collection containing all the facet names and + * servants of the removed Ice object. + * @see #remove + * @see #removeFacet + */ + virtual ::Ice::FacetMap removeAllFacets(const Identity& id) = 0; + + /** + * Remove the default servant for a specific category. Attempting + * to remove a default servant for a category that is not + * registered throws {@link NotRegisteredException}. + * @param category The category of the default servant to remove. + * @return The default servant. + * @see #addDefaultServant + * @see #findDefaultServant + */ + virtual ::std::shared_ptr<::Ice::Object> removeDefaultServant(const ::std::string& category) = 0; + + /** + * Look up a servant in this object adapter's Active Servant Map + * by the identity of the Ice object it implements. + * + *

This operation only tries to look up a servant in + * the Active Servant Map. It does not attempt to find a servant + * by using any installed {@link ServantLocator}. + * @param id The identity of the Ice object for which the servant + * should be returned. + * @return The servant that implements the Ice object with the + * given identity, or null if no such servant has been found. + * @see Identity + * @see #findFacet + * @see #findByProxy + */ + virtual ::std::shared_ptr<::Ice::Object> find(const Identity& id) const = 0; + + /** + * Like {@link #find}, but with a facet. Calling find(id) + * is equivalent to calling {@link #findFacet} with an empty + * facet. + * @param id The identity of the Ice object for which the + * servant should be returned. + * @param facet The facet. An empty facet means the default + * facet. + * @return The servant that implements the Ice object with the + * given identity and facet, or null if no such servant has been + * found. + * @see Identity + * @see #find + * @see #findByProxy + */ + virtual ::std::shared_ptr<::Ice::Object> findFacet(const Identity& id, const ::std::string& facet) const = 0; + + /** + * Find all facets with the given identity in the Active Servant + * Map. + * @param id The identity of the Ice object for which the facets + * should be returned. + * @return A collection containing all the facet names and + * servants that have been found, or an empty map if there is no + * facet for the given identity. + * @see #find + * @see #findFacet + */ + virtual ::Ice::FacetMap findAllFacets(const Identity& id) const = 0; + + /** + * Look up a servant in this object adapter's Active Servant Map, + * given a proxy. + * + *

This operation only tries to lookup a servant in + * the Active Servant Map. It does not attempt to find a servant + * by using any installed {@link ServantLocator}. + * @param proxy The proxy for which the servant should be returned. + * @return The servant that matches the proxy, or null if no such + * servant has been found. + * @see #find + * @see #findFacet + */ + virtual ::std::shared_ptr<::Ice::Object> findByProxy(const ::std::shared_ptr& proxy) const = 0; + + /** + * Add a Servant Locator to this object adapter. Adding a servant + * locator for a category for which a servant locator is already + * registered throws {@link AlreadyRegisteredException}. To dispatch + * operation calls on servants, the object adapter tries to find a + * servant for a given Ice object identity and facet in the + * following order: + * + *

    + * + *
  1. The object adapter tries to find a servant for the identity + * and facet in the Active Servant Map.
  2. + * + *
  3. If no servant has been found in the Active Servant Map, + * the object adapter tries to find a servant locator for the + * category component of the identity. If a locator is found, the + * object adapter tries to find a servant using this locator.
  4. + * + *
  5. If no servant has been found by any of the preceding steps, + * the object adapter tries to find a locator for an empty category, + * regardless of the category contained in the identity. If a + * locator is found, the object adapter tries to find a servant + * using this locator.
  6. + * + *
  7. If no servant has been found by any of the preceding steps, + * the object adapter gives up and the caller receives + * {@link ObjectNotExistException} or {@link FacetNotExistException}.
  8. + * + *
+ * + *

Only one locator for the empty category can be + * installed. + * @param locator The locator to add. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @see Identity + * @see #removeServantLocator + * @see #findServantLocator + * @see ServantLocator + */ + virtual void addServantLocator(const ::std::shared_ptr& locator, const ::std::string& category) = 0; + + /** + * Remove a Servant Locator from this object adapter. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @return The Servant Locator, or throws {@link NotRegisteredException} + * if no Servant Locator was found for the given category. + * @see Identity + * @see #addServantLocator + * @see #findServantLocator + * @see ServantLocator + */ + virtual ::std::shared_ptr<::Ice::ServantLocator> removeServantLocator(const ::std::string& category) = 0; + + /** + * Find a Servant Locator installed with this object adapter. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @return The Servant Locator, or null if no Servant Locator was + * found for the given category. + * @see Identity + * @see #addServantLocator + * @see #removeServantLocator + * @see ServantLocator + */ + virtual ::std::shared_ptr<::Ice::ServantLocator> findServantLocator(const ::std::string& category) const = 0; + + /** + * Find the default servant for a specific category. + * @param category The category of the default servant to find. + * @return The default servant or null if no default servant was + * registered for the category. + * @see #addDefaultServant + * @see #removeDefaultServant + */ + virtual ::std::shared_ptr<::Ice::Object> findDefaultServant(const ::std::string& category) const = 0; + + /** + * Create a proxy for the object with the given identity. If this + * object adapter is configured with an adapter id, the return + * value is an indirect proxy that refers to the adapter id. If + * a replica group id is also defined, the return value is an + * indirect proxy that refers to the replica group id. Otherwise, + * if no adapter id is defined, the return value is a direct + * proxy containing this object adapter's published endpoints. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> createProxy(const Identity& id) const = 0; + + /** + * Create a direct proxy for the object with the given identity. + * The returned proxy contains this object adapter's published + * endpoints. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> createDirectProxy(const Identity& id) const = 0; + + /** + * Create an indirect proxy for the object with the given identity. + * If this object adapter is configured with an adapter id, the + * return value refers to the adapter id. Otherwise, the return + * value contains only the object identity. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ::std::shared_ptr<::Ice::ObjectPrx> createIndirectProxy(const Identity& id) const = 0; + + /** + * Set an Ice locator for this object adapter. By doing so, the + * object adapter will register itself with the locator registry + * when it is activated for the first time. Furthermore, the proxies + * created by this object adapter will contain the adapter identifier + * instead of its endpoints. The adapter identifier must be configured + * using the AdapterId property. + * @param loc The locator used by this object adapter. + * @see #createDirectProxy + * @see Locator + * @see LocatorRegistry + */ + virtual void setLocator(const ::std::shared_ptr& loc) = 0; + + /** + * Get the Ice locator used by this object adapter. + * @return The locator used by this object adapter, or null if no locator is + * used by this object adapter. + * @see Locator + * @see #setLocator + */ + virtual ::std::shared_ptr<::Ice::LocatorPrx> getLocator() const noexcept = 0; + + /** + * Get the set of endpoints configured with this object adapter. + * @return The set of endpoints. + * @see Endpoint + */ + virtual ::Ice::EndpointSeq getEndpoints() const noexcept = 0; + + /** + * Refresh the set of published endpoints. The run time re-reads + * the PublishedEndpoints property if it is set and re-reads the + * list of local interfaces if the adapter is configured to listen + * on all endpoints. This operation is useful to refresh the endpoint + * information that is published in the proxies that are created by + * an object adapter if the network interfaces used by a host changes. + */ + virtual void refreshPublishedEndpoints() = 0; + + /** + * Get the set of endpoints that proxies created by this object + * adapter will contain. + * @return The set of published endpoints. + * @see #refreshPublishedEndpoints + * @see Endpoint + */ + virtual ::Ice::EndpointSeq getPublishedEndpoints() const noexcept = 0; + + /** + * Set of the endpoints that proxies created by this object + * adapter will contain. + * @param newEndpoints The new set of endpoints that the object adapter will embed in proxies. + * @see #refreshPublishedEndpoints + * @see Endpoint + */ + virtual void setPublishedEndpoints(const EndpointSeq& newEndpoints) = 0; + + virtual dispatch_queue_t getDispatchQueue() const = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ObjectAdapterPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +} + +namespace Ice +{ + +class ObjectAdapter; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ObjectAdapter*); +/// \endcond +typedef ::IceInternal::Handle< ObjectAdapter> ObjectAdapterPtr; + +} + +/// \cond INTERNAL +namespace IceAsync +{ + +} +/// \endcond + +namespace IceProxy +{ + +} + +namespace Ice +{ + +/** + * The object adapter provides an up-call interface from the Ice + * run time to the implementation of Ice objects. + * + * The object adapter is responsible for receiving requests + * from endpoints, and for mapping between servants, identities, and + * proxies. + * @see Communicator + * @see ServantLocator + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectAdapter : public virtual LocalObject +{ +public: + + typedef ObjectAdapterPtr PointerType; + + virtual ~ObjectAdapter(); + +#ifdef ICE_CPP11_COMPILER + ObjectAdapter() = default; + ObjectAdapter(const ObjectAdapter&) = default; + ObjectAdapter& operator=(const ObjectAdapter&) = default; +#endif + + /** + * Get the name of this object adapter. + * @return This object adapter's name. + */ + virtual ::std::string getName() const ICE_NOEXCEPT = 0; + + /** + * Get the communicator this object adapter belongs to. + * @return This object adapter's communicator. + * @see Communicator + */ + virtual CommunicatorPtr getCommunicator() const ICE_NOEXCEPT = 0; + + /** + * Activate all endpoints that belong to this object adapter. + * After activation, the object adapter can dispatch requests + * received through its endpoints. + * @see #hold + * @see #deactivate + */ + virtual void activate() = 0; + + /** + * Temporarily hold receiving and dispatching requests. The object + * adapter can be reactivated with the {@link #activate} operation. + * + *

Holding is not immediate, i.e., after {@link #hold} + * returns, the object adapter might still be active for some + * time. You can use {@link #waitForHold} to wait until holding is + * complete. + * @see #activate + * @see #deactivate + * @see #waitForHold + */ + virtual void hold() = 0; + + /** + * Wait until the object adapter holds requests. Calling {@link #hold} + * initiates holding of requests, and {@link #waitForHold} only returns + * when holding of requests has been completed. + * @see #hold + * @see #waitForDeactivate + * @see Communicator#waitForShutdown + */ + virtual void waitForHold() = 0; + + /** + * Deactivate all endpoints that belong to this object adapter. + * After deactivation, the object adapter stops receiving + * requests through its endpoints. Object adapters that have been + * deactivated must not be reactivated again, and cannot be used + * otherwise. Attempts to use a deactivated object adapter raise + * {@link ObjectAdapterDeactivatedException} however, attempts to + * {@link #deactivate} an already deactivated object adapter are + * ignored and do nothing. Once deactivated, it is possible to + * destroy the adapter to clean up resources and then create and + * activate a new adapter with the same name. + * + *

After {@link #deactivate} returns, no new requests + * are processed by the object adapter. However, requests that + * have been started before {@link #deactivate} was called might + * still be active. You can use {@link #waitForDeactivate} to wait + * for the completion of all requests for this object adapter. + * @see #activate + * @see #hold + * @see #waitForDeactivate + * @see Communicator#shutdown + */ + virtual void deactivate() ICE_NOEXCEPT = 0; + + /** + * Wait until the object adapter has deactivated. Calling + * {@link #deactivate} initiates object adapter deactivation, and + * {@link #waitForDeactivate} only returns when deactivation has + * been completed. + * @see #deactivate + * @see #waitForHold + * @see Communicator#waitForShutdown + */ + virtual void waitForDeactivate() ICE_NOEXCEPT = 0; + + /** + * Check whether object adapter has been deactivated. + * @return Whether adapter has been deactivated. + * @see Communicator#shutdown + */ + virtual bool isDeactivated() const ICE_NOEXCEPT = 0; + + /** + * Destroys the object adapter and cleans up all resources held by + * the object adapter. If the object adapter has not yet been + * deactivated, destroy implicitly initiates the deactivation + * and waits for it to finish. Subsequent calls to destroy are + * ignored. Once destroy has returned, it is possible to create + * another object adapter with the same name. + * @see #deactivate + * @see #waitForDeactivate + * @see Communicator#destroy + */ + virtual void destroy() ICE_NOEXCEPT = 0; + + /** + * Add a servant to this object adapter's Active Servant Map. Note + * that one servant can implement several Ice objects by registering + * the servant with multiple identities. Adding a servant with an + * identity that is in the map already throws {@link AlreadyRegisteredException}. + * @param servant The servant to add. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @return A proxy that matches the given identity and this object + * adapter. + * @see Identity + * @see #addFacet + * @see #addWithUUID + * @see #remove + * @see #find + */ + virtual ObjectPrx add(const ObjectPtr& servant, const Identity& id) = 0; + + /** + * Like {@link #add}, but with a facet. Calling add(servant, id) + * is equivalent to calling {@link #addFacet} with an empty facet. + * @param servant The servant to add. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @param facet The facet. An empty facet means the default facet. + * @return A proxy that matches the given identity, facet, and + * this object adapter. + * @see Identity + * @see #add + * @see #addFacetWithUUID + * @see #removeFacet + * @see #findFacet + */ + virtual ObjectPrx addFacet(const ObjectPtr& servant, const Identity& id, const ::std::string& facet) = 0; + + /** + * Add a servant to this object adapter's Active Servant Map, + * using an automatically generated UUID as its identity. Note that + * the generated UUID identity can be accessed using the proxy's + * ice_getIdentity operation. + * @param servant The servant to add. + * @return A proxy that matches the generated UUID identity and + * this object adapter. + * @see Identity + * @see #add + * @see #addFacetWithUUID + * @see #remove + * @see #find + */ + virtual ObjectPrx addWithUUID(const ObjectPtr& servant) = 0; + + /** + * Like {@link #addWithUUID}, but with a facet. Calling + * addWithUUID(servant) is equivalent to calling + * {@link #addFacetWithUUID} with an empty facet. + * @param servant The servant to add. + * @param facet The facet. An empty facet means the default + * facet. + * @return A proxy that matches the generated UUID identity, + * facet, and this object adapter. + * @see Identity + * @see #addFacet + * @see #addWithUUID + * @see #removeFacet + * @see #findFacet + */ + virtual ObjectPrx addFacetWithUUID(const ObjectPtr& servant, const ::std::string& facet) = 0; + + /** + * Add a default servant to handle requests for a specific + * category. Adding a default servant for a category for + * which a default servant is already registered throws + * {@link AlreadyRegisteredException}. To dispatch operation + * calls on servants, the object adapter tries to find a servant + * for a given Ice object identity and facet in the following + * order: + * + *

    + * + *
  1. The object adapter tries to find a servant for the identity + * and facet in the Active Servant Map.
  2. + * + *
  3. If no servant has been found in the Active Servant Map, the + * object adapter tries to find a default servant for the category + * component of the identity.
  4. + * + *
  5. If no servant has been found by any of the preceding steps, + * the object adapter tries to find a default servant for an empty + * category, regardless of the category contained in the identity.
  6. + * + *
  7. If no servant has been found by any of the preceding steps, + * the object adapter gives up and the caller receives + * {@link ObjectNotExistException} or {@link FacetNotExistException}.
  8. + * + *
+ * @param servant The default servant. + * @param category The category for which the default servant is + * registered. An empty category means it will handle all categories. + * @see #removeDefaultServant + * @see #findDefaultServant + */ + virtual void addDefaultServant(const ObjectPtr& servant, const ::std::string& category) = 0; + + /** + * Remove a servant (that is, the default facet) from the object + * adapter's Active Servant Map. + * @param id The identity of the Ice object that is implemented by + * the servant. If the servant implements multiple Ice objects, + * {@link #remove} has to be called for all those Ice objects. + * Removing an identity that is not in the map throws + * {@link NotRegisteredException}. + * @return The removed servant. + * @see Identity + * @see #add + * @see #addWithUUID + */ + virtual ObjectPtr remove(const Identity& id) = 0; + + /** + * Like {@link #remove}, but with a facet. Calling remove(id) + * is equivalent to calling {@link #removeFacet} with an empty facet. + * @param id The identity of the Ice object that is implemented by + * the servant. + * @param facet The facet. An empty facet means the default facet. + * @return The removed servant. + * @see Identity + * @see #addFacet + * @see #addFacetWithUUID + */ + virtual ObjectPtr removeFacet(const Identity& id, const ::std::string& facet) = 0; + + /** + * Remove all facets with the given identity from the Active + * Servant Map. The operation completely removes the Ice object, + * including its default facet. Removing an identity that + * is not in the map throws {@link NotRegisteredException}. + * @param id The identity of the Ice object to be removed. + * @return A collection containing all the facet names and + * servants of the removed Ice object. + * @see #remove + * @see #removeFacet + */ + virtual FacetMap removeAllFacets(const Identity& id) = 0; + + /** + * Remove the default servant for a specific category. Attempting + * to remove a default servant for a category that is not + * registered throws {@link NotRegisteredException}. + * @param category The category of the default servant to remove. + * @return The default servant. + * @see #addDefaultServant + * @see #findDefaultServant + */ + virtual ObjectPtr removeDefaultServant(const ::std::string& category) = 0; + + /** + * Look up a servant in this object adapter's Active Servant Map + * by the identity of the Ice object it implements. + * + *

This operation only tries to look up a servant in + * the Active Servant Map. It does not attempt to find a servant + * by using any installed {@link ServantLocator}. + * @param id The identity of the Ice object for which the servant + * should be returned. + * @return The servant that implements the Ice object with the + * given identity, or null if no such servant has been found. + * @see Identity + * @see #findFacet + * @see #findByProxy + */ + virtual ObjectPtr find(const Identity& id) const = 0; + + /** + * Like {@link #find}, but with a facet. Calling find(id) + * is equivalent to calling {@link #findFacet} with an empty + * facet. + * @param id The identity of the Ice object for which the + * servant should be returned. + * @param facet The facet. An empty facet means the default + * facet. + * @return The servant that implements the Ice object with the + * given identity and facet, or null if no such servant has been + * found. + * @see Identity + * @see #find + * @see #findByProxy + */ + virtual ObjectPtr findFacet(const Identity& id, const ::std::string& facet) const = 0; + + /** + * Find all facets with the given identity in the Active Servant + * Map. + * @param id The identity of the Ice object for which the facets + * should be returned. + * @return A collection containing all the facet names and + * servants that have been found, or an empty map if there is no + * facet for the given identity. + * @see #find + * @see #findFacet + */ + virtual FacetMap findAllFacets(const Identity& id) const = 0; + + /** + * Look up a servant in this object adapter's Active Servant Map, + * given a proxy. + * + *

This operation only tries to lookup a servant in + * the Active Servant Map. It does not attempt to find a servant + * by using any installed {@link ServantLocator}. + * @param proxy The proxy for which the servant should be returned. + * @return The servant that matches the proxy, or null if no such + * servant has been found. + * @see #find + * @see #findFacet + */ + virtual ObjectPtr findByProxy(const ObjectPrx& proxy) const = 0; + + /** + * Add a Servant Locator to this object adapter. Adding a servant + * locator for a category for which a servant locator is already + * registered throws {@link AlreadyRegisteredException}. To dispatch + * operation calls on servants, the object adapter tries to find a + * servant for a given Ice object identity and facet in the + * following order: + * + *

    + * + *
  1. The object adapter tries to find a servant for the identity + * and facet in the Active Servant Map.
  2. + * + *
  3. If no servant has been found in the Active Servant Map, + * the object adapter tries to find a servant locator for the + * category component of the identity. If a locator is found, the + * object adapter tries to find a servant using this locator.
  4. + * + *
  5. If no servant has been found by any of the preceding steps, + * the object adapter tries to find a locator for an empty category, + * regardless of the category contained in the identity. If a + * locator is found, the object adapter tries to find a servant + * using this locator.
  6. + * + *
  7. If no servant has been found by any of the preceding steps, + * the object adapter gives up and the caller receives + * {@link ObjectNotExistException} or {@link FacetNotExistException}.
  8. + * + *
+ * + *

Only one locator for the empty category can be + * installed. + * @param locator The locator to add. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @see Identity + * @see #removeServantLocator + * @see #findServantLocator + * @see ServantLocator + */ + virtual void addServantLocator(const ServantLocatorPtr& locator, const ::std::string& category) = 0; + + /** + * Remove a Servant Locator from this object adapter. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @return The Servant Locator, or throws {@link NotRegisteredException} + * if no Servant Locator was found for the given category. + * @see Identity + * @see #addServantLocator + * @see #findServantLocator + * @see ServantLocator + */ + virtual ServantLocatorPtr removeServantLocator(const ::std::string& category) = 0; + + /** + * Find a Servant Locator installed with this object adapter. + * @param category The category for which the Servant Locator can + * locate servants, or an empty string if the Servant Locator does + * not belong to any specific category. + * @return The Servant Locator, or null if no Servant Locator was + * found for the given category. + * @see Identity + * @see #addServantLocator + * @see #removeServantLocator + * @see ServantLocator + */ + virtual ServantLocatorPtr findServantLocator(const ::std::string& category) const = 0; + + /** + * Find the default servant for a specific category. + * @param category The category of the default servant to find. + * @return The default servant or null if no default servant was + * registered for the category. + * @see #addDefaultServant + * @see #removeDefaultServant + */ + virtual ObjectPtr findDefaultServant(const ::std::string& category) const = 0; + + /** + * Create a proxy for the object with the given identity. If this + * object adapter is configured with an adapter id, the return + * value is an indirect proxy that refers to the adapter id. If + * a replica group id is also defined, the return value is an + * indirect proxy that refers to the replica group id. Otherwise, + * if no adapter id is defined, the return value is a direct + * proxy containing this object adapter's published endpoints. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ObjectPrx createProxy(const Identity& id) const = 0; + + /** + * Create a direct proxy for the object with the given identity. + * The returned proxy contains this object adapter's published + * endpoints. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ObjectPrx createDirectProxy(const Identity& id) const = 0; + + /** + * Create an indirect proxy for the object with the given identity. + * If this object adapter is configured with an adapter id, the + * return value refers to the adapter id. Otherwise, the return + * value contains only the object identity. + * @param id The object's identity. + * @return A proxy for the object with the given identity. + * @see Identity + */ + virtual ObjectPrx createIndirectProxy(const Identity& id) const = 0; + + /** + * Set an Ice locator for this object adapter. By doing so, the + * object adapter will register itself with the locator registry + * when it is activated for the first time. Furthermore, the proxies + * created by this object adapter will contain the adapter identifier + * instead of its endpoints. The adapter identifier must be configured + * using the AdapterId property. + * @param loc The locator used by this object adapter. + * @see #createDirectProxy + * @see Locator + * @see LocatorRegistry + */ + virtual void setLocator(const LocatorPrx& loc) = 0; + + /** + * Get the Ice locator used by this object adapter. + * @return The locator used by this object adapter, or null if no locator is + * used by this object adapter. + * @see Locator + * @see #setLocator + */ + virtual LocatorPrx getLocator() const ICE_NOEXCEPT = 0; + + /** + * Get the set of endpoints configured with this object adapter. + * @return The set of endpoints. + * @see Endpoint + */ + virtual EndpointSeq getEndpoints() const ICE_NOEXCEPT = 0; + + /** + * Refresh the set of published endpoints. The run time re-reads + * the PublishedEndpoints property if it is set and re-reads the + * list of local interfaces if the adapter is configured to listen + * on all endpoints. This operation is useful to refresh the endpoint + * information that is published in the proxies that are created by + * an object adapter if the network interfaces used by a host changes. + */ + virtual void refreshPublishedEndpoints() = 0; + + /** + * Get the set of endpoints that proxies created by this object + * adapter will contain. + * @return The set of published endpoints. + * @see #refreshPublishedEndpoints + * @see Endpoint + */ + virtual EndpointSeq getPublishedEndpoints() const ICE_NOEXCEPT = 0; + + /** + * Set of the endpoints that proxies created by this object + * adapter will contain. + * @param newEndpoints The new set of endpoints that the object adapter will embed in proxies. + * @see #refreshPublishedEndpoints + * @see Endpoint + */ + virtual void setPublishedEndpoints(const EndpointSeq& newEndpoints) = 0; + + virtual LocalObjectPtr getDispatchQueue() const = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ObjectAdapter& lhs, const ObjectAdapter& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ObjectAdapter& lhs, const ObjectAdapter& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectAdapterF.h b/Sources/IceCpp/include/Ice/ObjectAdapterF.h new file mode 100644 index 0000000..cb278de --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectAdapterF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectAdapterF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ObjectAdapterF_h__ +#define __Ice_ObjectAdapterF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ObjectAdapter; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ObjectAdapterPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ObjectAdapter; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ObjectAdapter*); +/// \endcond +typedef ::IceInternal::Handle< ObjectAdapter> ObjectAdapterPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectAdapterFactory.h b/Sources/IceCpp/include/Ice/ObjectAdapterFactory.h new file mode 100644 index 0000000..b8e971f --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectAdapterFactory.h @@ -0,0 +1,53 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBJECT_ADAPTER_FACTORY_H +#define ICE_OBJECT_ADAPTER_FACTORY_H + +#include +#include +#include + +#include + +namespace IceInternal +{ + +class ObjectAdapterFactory : public ::IceUtil::Monitor< ::IceUtil::RecMutex>, +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public virtual IceUtil::Shared +#endif +{ +public: + + void shutdown(); + void waitForShutdown(); + bool isShutdown() const; + void destroy(); + + void updateObservers(void (Ice::ObjectAdapterI::*)()); + + ::Ice::ObjectAdapterPtr createObjectAdapter(const std::string&, const Ice::RouterPrxPtr&); + ::Ice::ObjectAdapterPtr findObjectAdapter(const ::Ice::ObjectPrxPtr&); + void removeObjectAdapter(const ::Ice::ObjectAdapterPtr&); + void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, ::Ice::CompressBatch) const; + + ObjectAdapterFactory(const InstancePtr&, const ::Ice::CommunicatorPtr&); + virtual ~ObjectAdapterFactory(); + +private: + + friend class Instance; + + InstancePtr _instance; + ::Ice::CommunicatorPtr _communicator; + std::set _adapterNamesInUse; + std::list _adapters; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectAdapterFactoryF.h b/Sources/IceCpp/include/Ice/ObjectAdapterFactoryF.h new file mode 100644 index 0000000..38c7bc5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectAdapterFactoryF.h @@ -0,0 +1,25 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBJECT_ADAPTER_FACTORY_F_H +#define ICE_OBJECT_ADAPTER_FACTORY_F_H + +#include + +#include + +namespace IceInternal +{ + +class ObjectAdapterFactory; +#ifdef ICE_CPP11_MAPPING +using ObjectAdapterFactoryPtr = ::std::shared_ptr; +#else +IceUtil::Shared* upCast(ObjectAdapterFactory*); +typedef IceInternal::Handle ObjectAdapterFactoryPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectAdapterI.h b/Sources/IceCpp/include/Ice/ObjectAdapterI.h new file mode 100644 index 0000000..c467618 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectAdapterI.h @@ -0,0 +1,159 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBJECT_ADAPTER_I_H +#define ICE_OBJECT_ADAPTER_I_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class ObjectAdapterI; +ICE_DEFINE_PTR(ObjectAdapterIPtr, ObjectAdapterI); + +class ObjectAdapterI : public ObjectAdapter, + public IceUtil::Monitor +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif + +{ +public: + + virtual std::string getName() const ICE_NOEXCEPT; + + virtual CommunicatorPtr getCommunicator() const ICE_NOEXCEPT; + + virtual void activate(); + virtual void hold(); + virtual void waitForHold(); + virtual void deactivate() ICE_NOEXCEPT; + virtual void waitForDeactivate() ICE_NOEXCEPT; + virtual bool isDeactivated() const ICE_NOEXCEPT; + virtual void destroy() ICE_NOEXCEPT; + + virtual ObjectPrxPtr add(const ObjectPtr&, const Identity&); + virtual ObjectPrxPtr addFacet(const ObjectPtr&, const Identity&, const std::string&); + virtual ObjectPrxPtr addWithUUID(const ObjectPtr&); + virtual ObjectPrxPtr addFacetWithUUID(const ObjectPtr&, const std::string&); + virtual void addDefaultServant(const ObjectPtr&, const std::string&); + virtual ObjectPtr remove(const Identity&); + virtual ObjectPtr removeFacet(const Identity&, const std::string&); + virtual FacetMap removeAllFacets(const Identity&); + virtual ObjectPtr removeDefaultServant(const std::string&); + virtual ObjectPtr find(const Identity&) const; + virtual ObjectPtr findFacet(const Identity&, const std::string&) const; + virtual FacetMap findAllFacets(const Identity&) const; + virtual ObjectPtr findByProxy(const ObjectPrxPtr&) const; + virtual ObjectPtr findDefaultServant(const std::string&) const; + + virtual void addServantLocator(const ServantLocatorPtr&, const std::string&); + virtual ServantLocatorPtr removeServantLocator(const std::string&); + virtual ServantLocatorPtr findServantLocator(const std::string&) const; + + virtual ObjectPrxPtr createProxy(const Identity&) const; + virtual ObjectPrxPtr createDirectProxy(const Identity&) const; + virtual ObjectPrxPtr createIndirectProxy(const Identity&) const; + + virtual void setLocator(const LocatorPrxPtr&); + virtual Ice::LocatorPrxPtr getLocator() const ICE_NOEXCEPT; + virtual EndpointSeq getEndpoints() const ICE_NOEXCEPT; + + virtual void refreshPublishedEndpoints(); + virtual EndpointSeq getPublishedEndpoints() const ICE_NOEXCEPT; + virtual void setPublishedEndpoints(const EndpointSeq&); + +#ifdef ICE_SWIFT + virtual dispatch_queue_t getDispatchQueue() const; +#endif + + bool isLocal(const ObjectPrxPtr&) const; + + void flushAsyncBatchRequests(const IceInternal::CommunicatorFlushBatchAsyncPtr&, CompressBatch); + + void updateConnectionObservers(); + void updateThreadObservers(); + + void incDirectCount(); + void decDirectCount(); + + IceInternal::ThreadPoolPtr getThreadPool() const; + IceInternal::ServantManagerPtr getServantManager() const; + IceInternal::ACMConfig getACM() const; + void setAdapterOnConnection(const Ice::ConnectionIPtr&); + size_t messageSizeMax() const { return _messageSizeMax; } + + ObjectAdapterI(const IceInternal::InstancePtr&, const CommunicatorPtr&, + const IceInternal::ObjectAdapterFactoryPtr&, const std::string&, bool); + virtual ~ObjectAdapterI(); + +private: + + void initialize(const RouterPrxPtr&); + friend class IceInternal::ObjectAdapterFactory; + + ObjectPrxPtr newProxy(const Identity&, const std::string&) const; + ObjectPrxPtr newDirectProxy(const Identity&, const std::string&) const; + ObjectPrxPtr newIndirectProxy(const Identity&, const std::string&, const std::string&) const; + void checkForDeactivation() const; + std::vector parseEndpoints(const std::string&, bool) const; + std::vector computePublishedEndpoints(); + void updateLocatorRegistry(const IceInternal::LocatorInfoPtr&, const Ice::ObjectPrxPtr&); + bool filterProperties(Ice::StringSeq&); + + enum State + { + StateUninitialized, + StateHeld, + StateActivating, + StateActive, + StateDeactivating, + StateDeactivated, + StateDestroying, + StateDestroyed + }; + State _state; + IceInternal::InstancePtr _instance; + CommunicatorPtr _communicator; + IceInternal::ObjectAdapterFactoryPtr _objectAdapterFactory; + IceInternal::ThreadPoolPtr _threadPool; + IceInternal::ACMConfig _acm; + IceInternal::ServantManagerPtr _servantManager; + const std::string _name; + const std::string _id; + const std::string _replicaGroupId; + IceInternal::ReferencePtr _reference; + std::vector _incomingConnectionFactories; + IceInternal::RouterInfoPtr _routerInfo; + std::vector _publishedEndpoints; + IceInternal::LocatorInfoPtr _locatorInfo; + int _directCount; // The number of direct proxies dispatching on this object adapter. + bool _noConfig; + size_t _messageSizeMax; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectF.h b/Sources/IceCpp/include/Ice/ObjectF.h new file mode 100644 index 0000000..980df75 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectF.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBJECT_F_H +#define ICE_OBJECT_F_H + +#include +#include + +namespace Ice +{ + +class Object; +#ifdef ICE_CPP11_MAPPING +/// \cond INTERNAL +using ObjectPtr = ::std::shared_ptr; +/// \endcond +#else +ICE_API Object* upCast(Object*); +typedef IceInternal::Handle ObjectPtr; +typedef ObjectPtr ValuePtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ObjectPtr&, const ObjectPtr&); +/// \endcond +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ObjectFactory.h b/Sources/IceCpp/include/Ice/ObjectFactory.h new file mode 100644 index 0000000..ffa99e1 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObjectFactory.h @@ -0,0 +1,203 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ObjectFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ObjectFactory_h__ +#define __Ice_ObjectFactory_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ObjectFactory; + +} + +namespace Ice +{ + +/** + * A factory for objects. Object factories are used when receiving "objects by value". + * An object factory must be implemented by the application writer and registered + * with the communicator. + * + * @deprecated ObjectFactory has been deprecated, use ValueFactory instead. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ObjectFactory +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ObjectFactory(); + + /** + * Create a new object for a given object type. The type is the + * absolute Slice type id, i.e., the id relative to the + * unnamed top-level Slice module. For example, the absolute + * Slice type id for interfaces of type Bar in the module + * Foo is "::Foo::Bar". + * + *

The leading "::" is required. + * @param type The object type. + * @return The object created for the given type, or nil if the + * factory is unable to create the object. + */ + ICE_DEPRECATED_API("ObjectFactory has been deprecated, use ValueFactory instead.") virtual ::std::shared_ptr<::Ice::Value> create(const ::std::string& type) = 0; + + /** + * Called when the factory is removed from the communicator, or if + * the communicator is destroyed. + * @see Communicator#destroy + */ + ICE_DEPRECATED_API("ObjectFactory has been deprecated, use ValueFactory instead.") virtual void destroy() = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ObjectFactoryPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ObjectFactory; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ObjectFactory*); +/// \endcond +typedef ::IceInternal::Handle< ObjectFactory> ObjectFactoryPtr; + +} + +namespace Ice +{ + +/** + * A factory for objects. Object factories are used when receiving "objects by value". + * An object factory must be implemented by the application writer and registered + * with the communicator. + * + * @deprecated ObjectFactory has been deprecated, use ValueFactory instead. + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectFactory : public virtual LocalObject +{ +public: + + typedef ObjectFactoryPtr PointerType; + + virtual ~ObjectFactory(); + +#ifdef ICE_CPP11_COMPILER + ObjectFactory() = default; + ObjectFactory(const ObjectFactory&) = default; + ObjectFactory& operator=(const ObjectFactory&) = default; +#endif + + /** + * Create a new object for a given object type. The type is the + * absolute Slice type id, i.e., the id relative to the + * unnamed top-level Slice module. For example, the absolute + * Slice type id for interfaces of type Bar in the module + * Foo is "::Foo::Bar". + * + *

The leading "::" is required. + * @param type The object type. + * @return The object created for the given type, or nil if the + * factory is unable to create the object. + */ + ICE_DEPRECATED_API("ObjectFactory has been deprecated, use ValueFactory instead.") virtual ValuePtr create(const ::std::string& type) = 0; + + /** + * Called when the factory is removed from the communicator, or if + * the communicator is destroyed. + * @see Communicator#destroy + */ + ICE_DEPRECATED_API("ObjectFactory has been deprecated, use ValueFactory instead.") virtual void destroy() = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ObjectFactory& lhs, const ObjectFactory& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ObjectFactory& lhs, const ObjectFactory& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ObserverHelper.h b/Sources/IceCpp/include/Ice/ObserverHelper.h new file mode 100644 index 0000000..7a4919f --- /dev/null +++ b/Sources/IceCpp/include/Ice/ObserverHelper.h @@ -0,0 +1,182 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OBSERVERHELPER_H +#define ICE_OBSERVERHELPER_H + +#include +#include +#include + +namespace IceInternal +{ + +template class ObserverHelperT +{ +public: + +#ifdef ICE_CPP11_MAPPING + using TPtr = ::std::shared_ptr; +#else + typedef IceInternal::Handle TPtr; +#endif + + ObserverHelperT() + { + } + + ~ObserverHelperT() + { + if(_observer) + { + _observer->detach(); + } + } + + operator bool() const + { + return _observer != ICE_NULLPTR; + } + + T* operator->() const + { + return _observer.get(); + } + + void + attach(const TPtr& o) + { + // + // Don't detach the existing observer. The observer is being + // replaced and the observed object is still being observed! + // + // if(_observer) + // { + // _observer->detach(); + // } + _observer = o; + if(_observer) + { + _observer->attach(); + } + } + +#ifdef ICE_CPP11_MAPPING + TPtr get() const + { + return _observer; + } +#else + T* get() const + { + return _observer.get(); + } +#endif + void adopt(ObserverHelperT& other) + { + _observer = other._observer; + other._observer = 0; + } + + void detach() + { + if(_observer) + { + _observer->detach(); + _observer = 0; + } + } + + void failed(const std::string& reason) + { + if(_observer) + { + _observer->failed(reason); + } + } + +protected: + + TPtr _observer; +}; + +class ICE_API DispatchObserver : public ObserverHelperT +{ +public: + + void userException() + { + if(_observer) + { + _observer->userException(); + } + } + + void reply(Ice::Int size) + { + if(_observer) + { + _observer->reply(size); + } + } +}; + +class ICE_API InvocationObserver : public ObserverHelperT +{ +public: + + InvocationObserver(const Ice::ObjectPrxPtr&, const std::string&, const Ice::Context&); + InvocationObserver(Instance*, const std::string&); + InvocationObserver() + { + } + + void attach(const Ice::ObjectPrxPtr&, const std::string&, const Ice::Context&); + void attach(Instance*, const std::string&); + + void retried() + { + if(_observer) + { + _observer->retried(); + } + } + + ::Ice::Instrumentation::ChildInvocationObserverPtr + getRemoteObserver(const Ice::ConnectionInfoPtr& con, const Ice::EndpointPtr& endpt, int requestId, int size) + { + if(_observer) + { + return _observer->getRemoteObserver(con, endpt, requestId, size); + } + return ICE_NULLPTR; + } + + ::Ice::Instrumentation::ChildInvocationObserverPtr + getCollocatedObserver(const Ice::ObjectAdapterPtr& adapter, int requestId, int size) + { + if(_observer) + { + return _observer->getCollocatedObserver(adapter, requestId, size); + } + return ICE_NULLPTR; + } + + void + userException() + { + if(_observer) + { + _observer->userException(); + } + } + +private: + + using ObserverHelperT::attach; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/OpaqueEndpointI.h b/Sources/IceCpp/include/Ice/OpaqueEndpointI.h new file mode 100644 index 0000000..3a19a36 --- /dev/null +++ b/Sources/IceCpp/include/Ice/OpaqueEndpointI.h @@ -0,0 +1,74 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UNKNOWN_ENDPOINT_I_H +#define ICE_UNKNOWN_ENDPOINT_I_H + +#include +#include + +namespace IceInternal +{ + +class OpaqueEndpointI : public EndpointI +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + OpaqueEndpointI(std::vector&); + OpaqueEndpointI(Ice::Short, Ice::InputStream*); + + virtual void streamWrite(Ice::OutputStream*) const; + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; + + virtual Ice::Int timeout() const; + virtual EndpointIPtr timeout(Ice::Int) const; + virtual const std::string& connectionId() const; + virtual EndpointIPtr connectionId(const ::std::string&) const; + virtual bool compress() const; + virtual EndpointIPtr compress(bool) const; + virtual bool datagram() const; + virtual bool secure() const; + + virtual TransceiverPtr transceiver() const; + virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; + virtual AcceptorPtr acceptor(const std::string&) const; + virtual std::vector expandIfWildcard() const; + virtual std::vector expandHost(EndpointIPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; + virtual Ice::Int hash() const; + virtual std::string options() const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + + using EndpointI::connectionId; + +protected: + + virtual void streamWriteImpl(Ice::OutputStream*) const; + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + +private: + + // + // All members are const, because endpoints are immutable. + // + Ice::Short _type; + Ice::EncodingVersion _rawEncoding; // The encoding used for _rawBytes + const std::vector _rawBytes; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Optional.h b/Sources/IceCpp/include/Ice/Optional.h new file mode 100644 index 0000000..4c5bd85 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Optional.h @@ -0,0 +1,1114 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// +// Ice::optional is a placeholder for std::optional: +// http://en.cppreference.com/w/cpp/utility/optional/optional +// +// This implementation is a slighly modified version of Optional.hpp, +// published at https://github.com/akrzemi1/Optional +// commit 25713110f55813b2c5619ec1230edf8d3b00bdde + +// Copyright (C) 2011-2016 Andrzej Krzemienski +// +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The idea and interface is based on Boost.Optional library +// authored by Fernando Luis Cacciola Carballal + +#ifndef ICE_OPTIONAL_H +#define ICE_OPTIONAL_H + +#ifdef ICE_CPP11_MAPPING + +# include +# include +# include +# include +# include +# include +# include + +# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false + +# if defined __GNUC__ // NOTE: GNUC is also defined for Clang +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___ +# endif +# +# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# elif (__GNUC__ > 4) +# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# endif +# endif +# +# if defined __clang_major__ +# if (__clang_major__ == 3 && __clang_minor__ >= 5) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# elif (__clang_major__ > 3) +# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# endif +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2) +# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ +# endif +# endif +# +# if defined _MSC_VER +# if (_MSC_VER >= 1900) +# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# endif +# endif + +# if defined __clang__ +# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9) +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif +# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ +# define OPTIONAL_HAS_THIS_RVALUE_REFS 1 +# else +# define OPTIONAL_HAS_THIS_RVALUE_REFS 0 +# endif + +# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___ +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1 +# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr +# else +# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0 +# define OPTIONAL_CONSTEXPR_INIT_LIST +# endif + +# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L) +# define OPTIONAL_HAS_MOVE_ACCESSORS 1 +# else +# define OPTIONAL_HAS_MOVE_ACCESSORS 0 +# endif + +# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr +# if (defined __cplusplus) && (__cplusplus == 201103L) +# define OPTIONAL_MUTABLE_CONSTEXPR +# else +# define OPTIONAL_MUTABLE_CONSTEXPR constexpr +# endif + +namespace std{ + +namespace experimental{ + +// +// Add namespace Ice to avoid conflict with other std::experimental::optional +// implementation +// +namespace Ice{ + +// BEGIN workaround for missing is_trivially_destructible +# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it: it is already there +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + template + using is_trivially_destructible = std::has_trivial_destructor; +# endif +// END workaround for missing is_trivially_destructible + +# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_ + // leave it; our metafunctions are already defined. +# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___ + // leave it: it is already there +# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS + // leave it: the user doesn't want it +# else + +// workaround for missing traits in GCC and CLANG +template +struct is_nothrow_move_constructible +{ + constexpr static bool value = std::is_nothrow_constructible::value; +}; + +template +struct is_assignable +{ + template + constexpr static bool has_assign(...) { return false; } + + template () = std::declval(), true)) > + // the comma operator is necessary for the cases where operator= returns void + constexpr static bool has_assign(bool) { return true; } + + constexpr static bool value = has_assign(true); +}; + +template +struct is_nothrow_move_assignable +{ + template + struct has_nothrow_move_assign { + constexpr static bool value = false; + }; + + template + struct has_nothrow_move_assign { + constexpr static bool value = noexcept( std::declval() = std::declval() ); + }; + + constexpr static bool value = has_nothrow_move_assign::value>::value; +}; +// end workaround + +# endif + +// 20.5.4, optional for object types +template class optional; + +// 20.5.5, optional for lvalue reference types +template class optional; + +// workaround: std utility functions aren't constexpr yet +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type& t) noexcept +{ + return static_cast(t); +} + +template inline constexpr T&& constexpr_forward(typename std::remove_reference::type&& t) noexcept +{ + static_assert(!std::is_lvalue_reference::value, "!!"); + return static_cast(t); +} + +template inline constexpr typename std::remove_reference::type&& constexpr_move(T&& t) noexcept +{ + return static_cast::type&&>(t); +} + +#if defined NDEBUG +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR) +#else +# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(false && #CHECK);}(), (EXPR))) +#endif + +namespace detail_ +{ + +// static_addressof: a constexpr version of addressof +template +struct has_overloaded_addressof +{ + template + constexpr static bool has_overload(...) { return false; } + + template ().operator&()) > + constexpr static bool has_overload(bool) { return true; } + + constexpr static bool value = has_overload(true); +}; + +template )> +constexpr T* static_addressof(T& ref) +{ + return &ref; +} + +template )> +T* static_addressof(T& ref) +{ + return std::addressof(ref); +} + +// the call to convert(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A +template +constexpr U convert(U v) { return v; } + +} // namespace detail + +constexpr struct trivial_init_t{} trivial_init{}; + +// 20.5.6, In-place construction +constexpr struct in_place_t{} in_place{}; + +// 20.5.7, Disengaged state indicator +struct nullopt_t +{ + struct init{}; + constexpr explicit nullopt_t(init){} +}; +constexpr nullopt_t nullopt{nullopt_t::init()}; + +// 20.5.8, class bad_optional_access +class bad_optional_access : public logic_error { +public: + explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {} + explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {} +}; + +template +union storage_t +{ + unsigned char dummy_; + T value_; + + constexpr storage_t( trivial_init_t ) noexcept : dummy_() {} + + template + constexpr storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~storage_t(){} +}; + +template +union constexpr_storage_t +{ + unsigned char dummy_; + T value_; + + constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {} + + template + constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward(args)...) {} + + ~constexpr_storage_t() = default; +}; + +template +struct optional_base +{ + bool init_; + storage_t storage_; + + constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {} + + explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + explicit optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~optional_base() { if (init_) storage_.value_.T::~T(); } +}; + +template +struct constexpr_optional_base +{ + bool init_; + constexpr_storage_t storage_; + + constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {} + + explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {} + + explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {} + + template explicit constexpr constexpr_optional_base(in_place_t, Args&&... args) + : init_(true), storage_(constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list il, Args&&... args) + : init_(true), storage_(il, std::forward(args)...) {} + + ~constexpr_optional_base() = default; +}; + +template +using OptionalBase = typename std::conditional< + is_trivially_destructible::value, // if possible + constexpr_optional_base::type>, // use base with trivial destructor + optional_base::type> +>::type; + +template +class optional : private OptionalBase +{ + static_assert( !std::is_same::type, nullopt_t>::value, "bad T" ); + static_assert( !std::is_same::type, in_place_t>::value, "bad T" ); + + constexpr bool initialized() const noexcept { return OptionalBase::init_; } + typename std::remove_const::type* dataptr() { return std::addressof(OptionalBase::storage_.value_); } + constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase::storage_.value_); } + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + constexpr const T& contained_val() const& { return OptionalBase::storage_.value_; } +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } + OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase::storage_.value_; } +# else + T& contained_val() & { return OptionalBase::storage_.value_; } + T&& contained_val() && { return std::move(OptionalBase::storage_.value_); } +# endif +# else + constexpr const T& contained_val() const { return OptionalBase::storage_.value_; } + T& contained_val() { return OptionalBase::storage_.value_; } +# endif + + void clear() noexcept { + if (initialized()) dataptr()->T::~T(); + OptionalBase::init_ = false; + } + + template + void initialize(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(std::forward(args)...); + OptionalBase::init_ = true; + } + + template + void initialize(std::initializer_list il, Args&&... args) noexcept(noexcept(T(il, std::forward(args)...))) + { + assert(!OptionalBase::init_); + ::new (static_cast(dataptr())) T(il, std::forward(args)...); + OptionalBase::init_ = true; + } + +public: + typedef T value_type; + + // 20.5.5.1, constructors + constexpr optional() noexcept : OptionalBase() {} + constexpr optional(nullopt_t) noexcept : OptionalBase() {} + + optional(const optional& rhs) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(*rhs); + OptionalBase::init_ = true; + } + } + + optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value) + : OptionalBase() + { + if (rhs.initialized()) { + ::new (static_cast(dataptr())) T(std::move(*rhs)); + OptionalBase::init_ = true; + } + } + + constexpr optional(const T& v) : OptionalBase(v) {} + + constexpr optional(T&& v) : OptionalBase(constexpr_move(v)) {} + + template + explicit constexpr optional(in_place_t, Args&&... args) + : OptionalBase(in_place_t{}, constexpr_forward(args)...) {} + + template >)> + OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list il, Args&&... args) + : OptionalBase(in_place_t{}, il, constexpr_forward(args)...) {} + + // 20.5.4.2, Destructor + ~optional() = default; + + // 20.5.4.3, assignment + optional& operator=(nullopt_t) noexcept + { + clear(); + return *this; + } + + optional& operator=(const optional& rhs) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(*rhs); + else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs; + return *this; + } + + optional& operator=(optional&& rhs) + noexcept(is_nothrow_move_assignable::value && is_nothrow_move_constructible::value) + { + if (initialized() == true && rhs.initialized() == false) clear(); + else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs)); + else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs); + return *this; + } + + template + auto operator=(U&& v) + -> typename enable_if + < + is_same::type, T>::value, + optional& + >::type + { + if (initialized()) { contained_val() = std::forward(v); } + else { initialize(std::forward(v)); } + return *this; + } + + template + void emplace(Args&&... args) + { + clear(); + initialize(std::forward(args)...); + } + + template + void emplace(initializer_list il, Args&&... args) + { + clear(); + initialize(il, std::forward(args)...); + } + + // 20.5.4.4, Swap + void swap(optional& rhs) noexcept(is_nothrow_move_constructible::value && noexcept(swap(declval(), declval()))) + { + if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); } + else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); } + else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); } + } + + // 20.5.4.5, Observers + + explicit constexpr operator bool() const noexcept { return initialized(); } + constexpr bool has_value() const noexcept { return initialized(); } + + constexpr T const* operator ->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr()); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() { + assert (initialized()); + return dataptr(); + } + + constexpr T const& operator *() const& { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & { + assert (initialized()); + return contained_val(); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && { + assert (initialized()); + return constexpr_move(contained_val()); + } + + constexpr T const& value() const& { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T& value() & { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + OPTIONAL_MUTABLE_CONSTEXPR T&& value() && { + if (!initialized()) throw bad_optional_access("bad optional access"); + return std::move(contained_val()); + } + +# else + + T* operator ->() { + assert (initialized()); + return dataptr(); + } + + // + // WORKAROUND error: implicit conversion turns string literal into bool + // +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wconversion" +#endif + constexpr T const& operator *() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val()); + } + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + + T& operator *() { + assert (initialized()); + return contained_val(); + } + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4702) // unreachable code +#endif + constexpr T const& value() const { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + + T& value() { + return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val()); + } + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +# endif + +# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1 + + template + constexpr T value_or(V&& v) const& + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# if OPTIONAL_HAS_MOVE_ACCESSORS == 1 + + template + OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# else + + template + T value_or(V&& v) && + { + return *this ? constexpr_move(const_cast&>(*this).contained_val()) : detail_::convert(constexpr_forward(v)); + } + +# endif + +# else + + template + constexpr T value_or(V&& v) const + { + return *this ? **this : detail_::convert(constexpr_forward(v)); + } + +# endif + + // 20.6.3.6, modifiers + void reset() noexcept { clear(); } +}; + +template +class optional +{ + static_assert( !std::is_same::value, "bad T" ); + static_assert( !std::is_same::value, "bad T" ); + T* ref; + +public: + + // 20.5.5.1, construction/destruction + constexpr optional() noexcept : ref(nullptr) {} + + constexpr optional(nullopt_t) noexcept : ref(nullptr) {} + + constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {} + + optional(T&&) = delete; + + constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {} + + explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {} + + explicit optional(in_place_t, T&&) = delete; + + ~optional() = default; + + // 20.5.5.2, mutation + optional& operator=(nullopt_t) noexcept { + ref = nullptr; + return *this; + } + + // optional& operator=(const optional& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + // optional& operator=(optional&& rhs) noexcept { + // ref = rhs.ref; + // return *this; + // } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + is_same::type, optional>::value, + optional& + >::type + { + ref = rhs.ref; + return *this; + } + + template + auto operator=(U&& rhs) noexcept + -> typename enable_if + < + !is_same::type, optional>::value, + optional& + >::type + = delete; + + void emplace(T& v) noexcept { + ref = detail_::static_addressof(v); + } + + void emplace(T&&) = delete; + + void swap(optional& rhs) noexcept + { + std::swap(ref, rhs.ref); + } + + // 20.5.5.3, observers + constexpr T* operator->() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref); + } + + constexpr T& operator*() const { + return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref); + } + + constexpr T& value() const { + return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref); + } + + explicit constexpr operator bool() const noexcept { + return ref != nullptr; + } + + constexpr bool has_value() const noexcept { + return ref != nullptr; + } + + template + constexpr typename decay::type value_or(V&& v) const + { + return *this ? **this : detail_::convert::type>(constexpr_forward(v)); + } + + // x.x.x.x, modifiers + void reset() noexcept { ref = nullptr; } +}; + +template +class optional +{ + static_assert( sizeof(T) == 0, "optional rvalue references disallowed" ); +}; + +// 20.5.8, Relational operators +template constexpr bool operator==(const optional& x, const optional& y) +{ + return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y; +} + +template constexpr bool operator!=(const optional& x, const optional& y) +{ + return !(x == y); +} + +template constexpr bool operator<(const optional& x, const optional& y) +{ + return (!y) ? false : (!x) ? true : *x < *y; +} + +template constexpr bool operator>(const optional& x, const optional& y) +{ + return (y < x); +} + +template constexpr bool operator<=(const optional& x, const optional& y) +{ + return !(y < x); +} + +template constexpr bool operator>=(const optional& x, const optional& y) +{ + return !(x < y); +} + +// 20.5.9, Comparison with nullopt +template constexpr bool operator==(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator==(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + +template constexpr bool operator!=(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator!=(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<(const optional&, nullopt_t) noexcept +{ + return false; +} + +template constexpr bool operator<(nullopt_t, const optional& x) noexcept +{ + return bool(x); +} + +template constexpr bool operator<=(const optional& x, nullopt_t) noexcept +{ + return (!x); +} + +template constexpr bool operator<=(nullopt_t, const optional&) noexcept +{ + return true; +} + +template constexpr bool operator>(const optional& x, nullopt_t) noexcept +{ + return bool(x); +} + +template constexpr bool operator>(nullopt_t, const optional&) noexcept +{ + return false; +} + +template constexpr bool operator>=(const optional&, nullopt_t) noexcept +{ + return true; +} + +template constexpr bool operator>=(nullopt_t, const optional& x) noexcept +{ + return (!x); +} + +// 20.5.10, Comparison with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + +// Comparison of optional with T +template constexpr bool operator==(const optional& x, const T& v) +{ + return bool(x) ? *x == v : false; +} + +template constexpr bool operator==(const T& v, const optional& x) +{ + return bool(x) ? v == *x : false; +} + +template constexpr bool operator!=(const optional& x, const T& v) +{ + return bool(x) ? *x != v : true; +} + +template constexpr bool operator!=(const T& v, const optional& x) +{ + return bool(x) ? v != *x : true; +} + +template constexpr bool operator<(const optional& x, const T& v) +{ + return bool(x) ? *x < v : true; +} + +template constexpr bool operator>(const T& v, const optional& x) +{ + return bool(x) ? v > *x : true; +} + +template constexpr bool operator>(const optional& x, const T& v) +{ + return bool(x) ? *x > v : false; +} + +template constexpr bool operator<(const T& v, const optional& x) +{ + return bool(x) ? v < *x : false; +} + +template constexpr bool operator>=(const optional& x, const T& v) +{ + return bool(x) ? *x >= v : false; +} + +template constexpr bool operator<=(const T& v, const optional& x) +{ + return bool(x) ? v <= *x : false; +} + +template constexpr bool operator<=(const optional& x, const T& v) +{ + return bool(x) ? *x <= v : true; +} + +template constexpr bool operator>=(const T& v, const optional& x) +{ + return bool(x) ? v >= *x : true; +} + +// 20.5.12, Specialized algorithms +template +void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))) +{ + x.swap(y); +} + +template +constexpr optional::type> make_optional(T&& v) +{ + return optional::type>(constexpr_forward(v)); +} + +template +constexpr optional make_optional(reference_wrapper v) +{ + return optional(v.get()); +} + +} // namespace Ice +} // namespace experimental +} // namespace std + +namespace std +{ + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::Ice::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; + + template + struct hash> + { + typedef typename hash::result_type result_type; + typedef std::experimental::Ice::optional argument_type; + + constexpr result_type operator()(argument_type const& arg) const { + return arg ? std::hash{}(*arg) : result_type{}; + } + }; +} + +# undef TR2_OPTIONAL_REQUIRES +# undef TR2_OPTIONAL_ASSERTED_EXPRESSION + +namespace Ice +{ + +/** + * Ice::optional is a placeholder for std::optional. + * Refer to http://en.cppreference.com/w/cpp/utility/optional for more information. + */ +template using optional = std::experimental::Ice::optional; + +using std::experimental::Ice::operator==; +using std::experimental::Ice::operator!=; +using std::experimental::Ice::operator<; +using std::experimental::Ice::operator<=; +using std::experimental::Ice::operator>; +using std::experimental::Ice::operator>=; + +/** Creates an optional object. */ +using std::experimental::Ice::make_optional; +/** Exchanges the state of an optional object with another one. */ +using std::experimental::Ice::swap; + +/** This type indicates that no value is provided. */ +using nullopt_t = std::experimental::Ice::nullopt_t; +/** An instance of nullopt_t used as a marker value to indicate that no value is provided. */ +using std::experimental::Ice::nullopt; + +/** Raised when accessing an optional that doesn't contain a value. */ +using bad_optional_access = std::experimental::Ice::bad_optional_access; + +/** This type indicates that an optional value should be constructed in place. */ +using in_place_t = std::experimental::Ice::in_place_t; +/** An instance of in_place_t that indicates that an optional value should be constructed in place. */ +using std::experimental::Ice::in_place; + +} + +namespace IceUtil +{ + +/** + * For compatibility with the Ice C++98 mapping, do not use in new code: + */ +template using Optional = std::experimental::Ice::optional; +/** + * For compatibility with the Ice C++98 mapping, do not use in new code: + */ +constexpr std::experimental::Ice::nullopt_t None{std::experimental::Ice::nullopt_t::init()}; + +} + +#else // C++98 mapping + +# include + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/OutgoingAsync.h b/Sources/IceCpp/include/Ice/OutgoingAsync.h new file mode 100644 index 0000000..29a5192 --- /dev/null +++ b/Sources/IceCpp/include/Ice/OutgoingAsync.h @@ -0,0 +1,856 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OUTGOING_ASYNC_H +#define ICE_OUTGOING_ASYNC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_CPP11_MAPPING +# include +#endif + +#include + +namespace IceInternal +{ + +class RetryException; +class CollocatedRequestHandler; + +class ICE_API OutgoingAsyncCompletionCallback +{ +public: + virtual ~OutgoingAsyncCompletionCallback(); + +protected: + + virtual bool handleSent(bool, bool) = 0; + virtual bool handleException(const Ice::Exception&) = 0; + virtual bool handleResponse(bool) = 0; + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const = 0; + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const = 0; + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const = 0; +}; + +// +// Base class for handling asynchronous invocations. This class is +// responsible for the handling of the output stream and the child +// invocation observer. +// +class ICE_API OutgoingAsyncBase : public virtual OutgoingAsyncCompletionCallback, +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public Ice::AsyncResult +#endif +{ +public: + + virtual bool sent(); + virtual bool exception(const Ice::Exception&); + virtual bool response(); + + void invokeSentAsync(); + void invokeExceptionAsync(); + void invokeResponseAsync(); + + void invokeSent(); + void invokeException(); + void invokeResponse(); + + virtual void cancelable(const IceInternal::CancellationHandlerPtr&); + void cancel(); + +#ifndef ICE_CPP11_MAPPING + virtual Ice::Int getHash() const; + + virtual Ice::CommunicatorPtr getCommunicator() const; + virtual Ice::ConnectionPtr getConnection() const; + virtual Ice::ObjectPrx getProxy() const; + + virtual Ice::LocalObjectPtr getCookie() const; + virtual const std::string& getOperation() const; + + virtual bool isCompleted() const; + virtual void waitForCompleted(); + + virtual bool isSent() const; + virtual void waitForSent(); + + virtual bool sentSynchronously() const; + + virtual void throwLocalException() const; + + virtual bool _waitForResponse(); + virtual Ice::InputStream* _startReadParams(); + virtual void _endReadParams(); + virtual void _readEmptyParams(); + virtual void _readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&); + virtual void _throwUserException(); + + virtual void _scheduleCallback(const CallbackPtr&); +#endif + + void attachRemoteObserver(const Ice::ConnectionInfoPtr& c, const Ice::EndpointPtr& endpt, Ice::Int requestId) + { + const Ice::Int size = static_cast(_os.b.size() - headerSize - 4); + _childObserver.attach(getObserver().getRemoteObserver(c, endpt, requestId, size)); + } + + void attachCollocatedObserver(const Ice::ObjectAdapterPtr& adapter, Ice::Int requestId) + { + const Ice::Int size = static_cast(_os.b.size() - headerSize - 4); + _childObserver.attach(getObserver().getCollocatedObserver(adapter, requestId, size)); + } + + Ice::OutputStream* getOs() + { + return &_os; + } + + Ice::InputStream* getIs() + { + return &_is; + } + +protected: + + OutgoingAsyncBase(const InstancePtr&); + + bool sentImpl(bool); + bool exceptionImpl(const Ice::Exception&); + bool responseImpl(bool, bool); + + void cancel(const Ice::LocalException&); + void checkCanceled(); + + void warning(const std::exception&) const; + void warning() const; + + // + // This virtual method is necessary for the communicator flush + // batch requests implementation. + // + virtual IceInternal::InvocationObserver& getObserver() + { + return _observer; + } + + const InstancePtr _instance; + Ice::ConnectionPtr _cachedConnection; + bool _sentSynchronously; + bool _doneInSent; + unsigned char _state; + +#ifdef ICE_CPP11_MAPPING + std::mutex _m; + using Lock = std::lock_guard; +#else + IceUtil::Monitor _m; + typedef IceUtil::Monitor::Lock Lock; + Ice::LocalObjectPtr _cookie; +#endif + + IceInternal::UniquePtr _ex; + IceInternal::UniquePtr _cancellationException; + + InvocationObserver _observer; + ObserverHelperT _childObserver; + + Ice::OutputStream _os; + Ice::InputStream _is; + + CancellationHandlerPtr _cancellationHandler; + + static const unsigned char OK; + static const unsigned char Sent; +#ifndef ICE_CPP11_MAPPING + static const unsigned char Done; + static const unsigned char EndCalled; +#endif +}; + +// +// Base class for proxy based invocations. This class handles the +// retry for proxy invocations. It also ensures the child observer is +// correct notified of failures and make sure the retry task is +// correctly canceled when the invocation completes. +// +class ICE_API ProxyOutgoingAsyncBase : public OutgoingAsyncBase, + public IceUtil::TimerTask +{ +public: + + virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool) = 0; + virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*) = 0; + + virtual bool exception(const Ice::Exception&); + virtual void cancelable(const CancellationHandlerPtr&); + + void retryException(const Ice::Exception&); + void retry(); + void abort(const Ice::Exception&); + +#ifdef ICE_CPP11_MAPPING + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(OutgoingAsyncBase::shared_from_this()); + } +#else + virtual Ice::ObjectPrx getProxy() const; + virtual Ice::CommunicatorPtr getCommunicator() const; +#endif + +protected: + + ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&); + ~ProxyOutgoingAsyncBase(); + + void invokeImpl(bool); + bool sentImpl(bool); + bool exceptionImpl(const Ice::Exception&); + bool responseImpl(bool, bool); + + virtual void runTimerTask(); + + const Ice::ObjectPrxPtr _proxy; + RequestHandlerPtr _handler; + Ice::OperationMode _mode; + +private: + + int _cnt; + bool _sent; +}; + +// +// Class for handling Slice operation invocations +// +class ICE_API OutgoingAsync : public ProxyOutgoingAsyncBase +{ +public: + + OutgoingAsync(const Ice::ObjectPrxPtr&, bool); + + void prepare(const std::string&, Ice::OperationMode, const Ice::Context&); + + virtual bool sent(); + virtual bool response(); + + virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); + virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); + + void abort(const Ice::Exception&); + void invoke(const std::string&); +#ifdef ICE_CPP11_MAPPING + void invoke(const std::string&, Ice::OperationMode, Ice::FormatType, const Ice::Context&, + std::function); + void throwUserException(); +#endif + + Ice::OutputStream* startWriteParams(Ice::FormatType format) + { + _os.startEncapsulation(_encoding, format); + return &_os; + } + void endWriteParams() + { + _os.endEncapsulation(); + } + void writeEmptyParams() + { + _os.writeEmptyEncapsulation(_encoding); + } + void writeParamEncaps(const ::Ice::Byte* encaps, ::Ice::Int size) + { + if(size == 0) + { + _os.writeEmptyEncapsulation(_encoding); + } + else + { + _os.writeEncapsulation(encaps, size); + } + } + +protected: + + const Ice::EncodingVersion _encoding; + +#ifdef ICE_CPP11_MAPPING + std::function _userException; +#endif + + bool _synchronous; +}; + +} + +namespace IceInternal +{ + +#ifdef ICE_CPP11_MAPPING + +class ICE_API LambdaInvoke : public virtual OutgoingAsyncCompletionCallback +{ +public: + + LambdaInvoke(std::function exception, std::function sent) : + _exception(std::move(exception)), _sent(std::move(sent)) + { + } + +protected: + + virtual bool handleSent(bool, bool) override; + virtual bool handleException(const Ice::Exception&) override; + virtual bool handleResponse(bool) override; + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override; + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override; + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override; + + std::function _exception; + std::function _sent; + std::function _response; +}; + +template +class PromiseInvoke : public virtual OutgoingAsyncCompletionCallback +{ +public: + + auto + getFuture() -> decltype(std::declval().get_future()) + { + return _promise.get_future(); + } + +protected: + + Promise _promise; + std::function _response; + +private: + + virtual bool handleSent(bool, bool) override + { + return false; + } + + virtual bool handleException(const Ice::Exception& ex) override + { + try + { + ex.ice_throw(); + } + catch(const Ice::Exception&) + { + _promise.set_exception(std::current_exception()); + } + return false; + } + + virtual bool handleResponse(bool ok) override + { + _response(ok); + return false; + } + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override + { + assert(false); + } + + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override + { + assert(false); + } + + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override + { + assert(false); + } +}; + +template +class OutgoingAsyncT : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& ctx, + std::function write, + std::function userException) + { + _read = [](Ice::InputStream* stream) + { + T v; + stream->read(v); + return v; + }; + _userException = std::move(userException); + OutgoingAsync::invoke(operation, mode, format, ctx, std::move(write)); + } + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& ctx, + std::function write, + std::function userException, + std::function read) + { + _read = std::move(read); + _userException = std::move(userException); + OutgoingAsync::invoke(operation, mode, format, ctx, std::move(write)); + } + +protected: + + std::function _read; +}; + +template<> +class OutgoingAsyncT : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& ctx, + std::function write, + std::function userException) + { + _userException = std::move(userException); + OutgoingAsync::invoke(operation, mode, format, ctx, std::move(write)); + } +}; + +template +class LambdaOutgoing : public OutgoingAsyncT, public LambdaInvoke +{ +public: + + LambdaOutgoing(const std::shared_ptr& proxy, + std::function response, + std::function ex, + std::function sent) : + OutgoingAsyncT(proxy, false), LambdaInvoke(std::move(ex), std::move(sent)) + { +#if ICE_CPLUSPLUS >= 201402L + // Move capture with C++14 + _response = [this, response = std::move(response)](bool ok) +#else + _response = [this, response](bool ok) +#endif + { + if(!ok) + { + this->throwUserException(); + } + else if(response) + { + assert(this->_read); + this->_is.startEncapsulation(); + R v = this->_read(&this->_is); + this->_is.endEncapsulation(); + try + { + response(std::move(v)); + } + catch(...) + { + throw std::current_exception(); + } + } + }; + } +}; + +template<> +class LambdaOutgoing : public OutgoingAsyncT, public LambdaInvoke +{ +public: + + LambdaOutgoing(const std::shared_ptr& proxy, + std::function response, + std::function ex, + std::function sent) : + OutgoingAsyncT(proxy, false), LambdaInvoke(std::move(ex), std::move(sent)) + { +#if ICE_CPLUSPLUS >= 201402L + // Move capture with C++14 + _response = [this, response = std::move(response)](bool ok) +#else + _response = [this, response](bool ok) +#endif + { + if(!ok) + { + this->throwUserException(); + } + else if(response) + { + if(!this->_is.b.empty()) + { + this->_is.skipEmptyEncapsulation(); + } + + try + { + response(); + } + catch(...) + { + throw std::current_exception(); + } + } + }; + } +}; + +class CustomLambdaOutgoing : public OutgoingAsync, public LambdaInvoke +{ +public: + + CustomLambdaOutgoing(const std::shared_ptr& proxy, + std::function read, + std::function ex, + std::function sent) : + OutgoingAsync(proxy, false), LambdaInvoke(std::move(ex), std::move(sent)) + { +#if ICE_CPLUSPLUS >= 201402L + // Move capture with C++14 + _response = [this, read = std::move(read)](bool ok) +#else + _response = [this, read](bool ok) +#endif + { + if(!ok) + { + this->throwUserException(); + } + else if(read) + { + // + // Read and respond + // + read(&this->_is); + } + }; + } + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + Ice::FormatType format, + const Ice::Context& ctx, + std::function write, + std::function userException) + { + _userException = std::move(userException); + OutgoingAsync::invoke(operation, mode, format, ctx, std::move(write)); + } +}; + +template +class PromiseOutgoing : public OutgoingAsyncT, public PromiseInvoke

+{ +public: + + PromiseOutgoing(const std::shared_ptr& proxy, bool sync) : + OutgoingAsyncT(proxy, sync) + { + this->_response = [this](bool ok) + { + if(ok) + { + assert(this->_read); + this->_is.startEncapsulation(); + R v = this->_read(&this->_is); + this->_is.endEncapsulation(); + this->_promise.set_value(std::move(v)); + } + else + { + this->throwUserException(); + } + }; + } +}; + +template +class PromiseOutgoing : public OutgoingAsyncT, public PromiseInvoke

+{ +public: + + PromiseOutgoing(const std::shared_ptr& proxy, bool sync) : + OutgoingAsyncT(proxy, sync) + { + this->_response = [&](bool ok) + { + if(this->_is.b.empty()) + { + // + // If there's no response (oneway, batch-oneway proxies), we just set the promise + // on completion without reading anything from the input stream. This is required for + // batch invocations. + // + this->_promise.set_value(); + } + else if(ok) + { + this->_is.skipEmptyEncapsulation(); + this->_promise.set_value(); + } + else + { + this->throwUserException(); + } + }; + } + + virtual bool handleSent(bool done, bool) override + { + if(done) + { + PromiseInvoke

::_promise.set_value(); + } + return false; + } +}; + +#else + +// +// Base class for all callbacks. +// +class ICE_API CallbackBase : public IceUtil::Shared +{ +public: + + virtual ~CallbackBase(); + + void checkCallback(bool, bool); + + virtual void completed(const ::Ice::AsyncResultPtr&) const = 0; + virtual IceUtil::Handle verify(const ::Ice::LocalObjectPtr&) = 0; + virtual void sent(const ::Ice::AsyncResultPtr&) const = 0; + virtual bool hasSentCallback() const = 0; +}; +typedef IceUtil::Handle CallbackBasePtr; + +// +// Base class for generic callbacks. +// +class ICE_API GenericCallbackBase : public virtual CallbackBase +{ +public: + + virtual ~GenericCallbackBase(); +}; + +// +// See comments in OutgoingAsync.cpp +// +extern ICE_API CallbackBasePtr dummyCallback ICE_GLOBAL_VAR_SUFFIX; + +// +// Generic callback template that requires the caller to down-cast the +// proxy and the cookie that are obtained from the AsyncResult. +// +template +class AsyncCallback : public GenericCallbackBase +{ +public: + + typedef T callback_type; + typedef IceUtil::Handle TPtr; + + typedef void (T::*Callback)(const ::Ice::AsyncResultPtr&); + + AsyncCallback(const TPtr& instance, Callback cb, Callback sentcb = 0) : + _callback(instance), _completed(cb), _sent(sentcb) + { + checkCallback(instance, cb != 0); + } + + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + (_callback.get()->*_completed)(result); + } + + virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr&) + { + return this; // Nothing to do, the cookie is not type-safe. + } + + virtual void sent(const ::Ice::AsyncResultPtr& result) const + { + if(_sent) + { + (_callback.get()->*_sent)(result); + } + } + + virtual bool hasSentCallback() const + { + return _sent != 0; + } + +private: + + TPtr _callback; + Callback _completed; + Callback _sent; +}; + +class CallbackCompletion : public virtual OutgoingAsyncCompletionCallback +{ +public: + + CallbackCompletion(const CallbackBasePtr& cb, const Ice::LocalObjectPtr& cookie) : _callback(cb) + { + if(!_callback) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__); + } + const_cast(_callback) = _callback->verify(cookie); + } + + virtual bool handleSent(bool, bool alreadySent) + { + return _callback && _callback->hasSentCallback() && !alreadySent; + } + + virtual bool handleException(const Ice::Exception&) + { + return _callback; + } + + virtual bool handleResponse(bool) + { + return _callback; + } + + virtual void handleInvokeSent(bool, OutgoingAsyncBase* outAsync) const + { + _callback->sent(outAsync); + } + + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase* outAsync) const + { + _callback->completed(outAsync); + } + + virtual void handleInvokeResponse(bool, OutgoingAsyncBase* outAsync) const + { + _callback->completed(outAsync); + } + +private: + + const CallbackBasePtr _callback; +}; + +class CallbackOutgoing : public OutgoingAsync, public CallbackCompletion +{ +public: + + CallbackOutgoing(const Ice::ObjectPrx& proxy, + const std::string& operation, + const CallbackBasePtr& cb, + const Ice::LocalObjectPtr& cookie, + bool sync) : + OutgoingAsync(proxy, sync), CallbackCompletion(cb, cookie), _operation(operation) + { + _cookie = cookie; + } + + virtual const std::string& + getOperation() const + { + return _operation; + } + +private: + + const std::string& _operation; +}; + +#endif + +} + +#ifndef ICE_CPP11_MAPPING + +namespace Ice +{ + +typedef IceUtil::Handle< ::IceInternal::GenericCallbackBase> CallbackPtr; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The completion callback. + * @param sentcb The sent callback. + * @return A callback object that can be passed to an asynchronous invocation. + */ +template CallbackPtr +newCallback(const IceUtil::Handle& instance, + void (T::*cb)(const AsyncResultPtr&), + void (T::*sentcb)(const AsyncResultPtr&) = 0) +{ + return new ::IceInternal::AsyncCallback(instance, cb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The completion callback. + * @param sentcb The sent callback. + * @return A callback object that can be passed to an asynchronous invocation. + */ +template CallbackPtr +newCallback(T* instance, + void (T::*cb)(const AsyncResultPtr&), + void (T::*sentcb)(const AsyncResultPtr&) = 0) +{ + return new ::IceInternal::AsyncCallback(instance, cb, sentcb); +} + +} + +// +// Operation callbacks are specified in Proxy.h +// + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/OutgoingAsyncF.h b/Sources/IceCpp/include/Ice/OutgoingAsyncF.h new file mode 100644 index 0000000..86885db --- /dev/null +++ b/Sources/IceCpp/include/Ice/OutgoingAsyncF.h @@ -0,0 +1,39 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OUTGOING_ASYNC_F_H +#define ICE_OUTGOING_ASYNC_F_H + +#include +#include + +namespace IceInternal +{ + +class OutgoingAsyncBase; +class OutgoingAsync; +class ProxyOutgoingAsyncBase; +class CommunicatorFlushBatchAsync; + +#ifdef ICE_CPP11_MAPPING +using OutgoingAsyncBasePtr = ::std::shared_ptr; +using OutgoingAsyncPtr = ::std::shared_ptr; +using ProxyOutgoingAsyncBasePtr = ::std::shared_ptr; +using CommunicatorFlushBatchAsyncPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(OutgoingAsyncBase*); +typedef IceInternal::Handle OutgoingAsyncBasePtr; + +ICE_API IceUtil::Shared* upCast(OutgoingAsync*); +typedef IceInternal::Handle OutgoingAsyncPtr; + +ICE_API IceUtil::Shared* upCast(ProxyOutgoingAsyncBase*); +typedef IceInternal::Handle ProxyOutgoingAsyncBasePtr; + +ICE_API IceUtil::Shared* upCast(CommunicatorFlushBatchAsync*); +typedef IceInternal::Handle CommunicatorFlushBatchAsyncPtr; +#endif +} + +#endif diff --git a/Sources/IceCpp/include/Ice/OutputStream.h b/Sources/IceCpp/include/Ice/OutputStream.h new file mode 100644 index 0000000..886ec28 --- /dev/null +++ b/Sources/IceCpp/include/Ice/OutputStream.h @@ -0,0 +1,1092 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_OUTPUT_STREAM_H +#define ICE_OUTPUT_STREAM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class UserException; + +/** + * Interface for output streams used to create a sequence of bytes from Slice types. + * \headerfile Ice/Ice.h + */ +class ICE_API OutputStream : public IceInternal::Buffer +{ +public: + + typedef size_t size_type; + + /** + * Constructs an OutputStream using the latest encoding version, the default format for + * class encoding, and the process string converters. You can supply a communicator later + * by calling initialize(). + */ + OutputStream(); + + /** + * Constructs a stream using the communicator's default encoding version. + * @param communicator The communicator to use for marshaling tasks. + */ + OutputStream(const CommunicatorPtr& communicator); + + /** + * Constructs a stream using the given communicator and encoding version. + * @param communicator The communicator to use for marshaling tasks. + * @param version The encoding version used to encode the data. + */ + OutputStream(const CommunicatorPtr& communicator, const EncodingVersion& version); + + /** + * Constructs a stream using the given communicator and encoding version. + * @param communicator The communicator to use for marshaling tasks. + * @param version The encoding version used to encode the data. + * @param bytes Application-supplied memory that the stream uses as its initial marshaling buffer. The + * stream will reallocate if the size of the marshaled data exceeds the application's buffer. + */ + OutputStream(const CommunicatorPtr& communicator, const EncodingVersion& version, + const std::pair& bytes); + + ~OutputStream() + { + // Inlined for performance reasons. + + if(_currentEncaps != &_preAllocatedEncaps) + { + clear(); // Not inlined. + } + } + + /** + * Initializes the stream to use the communicator's default encoding version, class + * encoding format and string converters. Use this method if you originally constructed + * the stream without a communicator. + * @param communicator The communicator to use for marshaling tasks. + */ + void initialize(const CommunicatorPtr& communicator); + + /** + * Initializes the stream to use the given encoding version and the communicator's + * default class encoding format and string converters. Use this method if you + * originally constructed the stream without a communicator. + * @param communicator The communicator to use for marshaling tasks. + * @param version The encoding version used to encode the data. + */ + void initialize(const CommunicatorPtr& communicator, const EncodingVersion& version); + + /** + * Releases any data retained by encapsulations. + */ + void clear(); + + /// \cond INTERNAL + // + // Must return Instance*, because we don't hold an InstancePtr for + // optimization reasons (see comments below). + // + IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons. + /// \endcond + + /** + * Sets the class encoding format. + * @param format The encoding format. + */ + void setFormat(FormatType format); + + /** + * Obtains the closure data associated with this stream. + * @return The data as a void pointer. + */ + void* getClosure() const; + + /** + * Associates closure data with this stream. + * @param p The data as a void pointer. + * @return The previous closure data, or nil. + */ + void* setClosure(void* p); + + /** + * Swaps the contents of one stream with another. + * + * @param other The other stream. + */ + void swap(OutputStream& other); + + /// \cond INTERNAL + void resetEncapsulation(); + /// \endcond + + /** + * Resizes the stream to a new size. + * + * @param sz The new size. + */ + void resize(Container::size_type sz) + { + b.resize(sz); + } + + /** + * Marks the start of a class instance. + * @param data Contains the marshaled form of unknown slices from this instance. If not nil, + * these slices will be marshaled with the instance. + */ + void startValue(const SlicedDataPtr& data) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startInstance(ValueSlice, data); + } + + /** + * Marks the end of a class instance. + */ + void endValue() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endInstance(); + } + + /** + * Marks the start of an exception instance. + * @param data Contains the marshaled form of unknown slices from this instance. If not nil, + * these slices will be marshaled with the instance. + */ + void startException(const SlicedDataPtr& data) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startInstance(ExceptionSlice, data); + } + + /** + * Marks the end of an exception instance. + */ + void endException() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endInstance(); + } + + /** + * Writes the start of an encapsulation using the default encoding version and + * class encoding format. + */ + void startEncapsulation(); + + /** + * Writes the start of an encapsulation using the given encoding version and + * class encoding format. + * @param encoding The encoding version to use for the encapsulation. + * @param format The class format to use for the encapsulation. + */ + void startEncapsulation(const EncodingVersion& encoding, FormatType format) + { + IceInternal::checkSupportedEncoding(encoding); + + Encaps* oldEncaps = _currentEncaps; + if(!oldEncaps) // First allocated encaps? + { + _currentEncaps = &_preAllocatedEncaps; + } + else + { + _currentEncaps = new Encaps(); + _currentEncaps->previous = oldEncaps; + } + _currentEncaps->format = format; + _currentEncaps->encoding = encoding; + _currentEncaps->start = b.size(); + + write(Int(0)); // Placeholder for the encapsulation length. + write(_currentEncaps->encoding); + } + + /** + * Ends the current encapsulation. + */ + void endEncapsulation() + { + assert(_currentEncaps); + + // Size includes size and version. + const Int sz = static_cast(b.size() - _currentEncaps->start); + write(sz, &(*(b.begin() + _currentEncaps->start))); + + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + if(oldEncaps == &_preAllocatedEncaps) + { + oldEncaps->reset(); + } + else + { + delete oldEncaps; + } + } + + /** + * Writes an empty encapsulation using the given encoding version. + * @param encoding The encoding version to use for the encapsulation. + */ + void writeEmptyEncapsulation(const EncodingVersion& encoding) + { + IceInternal::checkSupportedEncoding(encoding); + write(Int(6)); // Size + write(encoding); + } + + /** + * Copies the marshaled form of an encapsulation to the buffer. + * @param v The start of the buffer. + * @param sz The number of bytes to copy. + */ + void writeEncapsulation(const Byte* v, Int sz) + { + if(sz < 6) + { + throwEncapsulationException(__FILE__, __LINE__); + } + + Container::size_type position = b.size(); + resize(position + static_cast(sz)); + memcpy(&b[position], &v[0], static_cast(sz)); + } + + /** + * Determines the current encoding version. + * + * @return The encoding version. + */ + const EncodingVersion& getEncoding() const + { + return _currentEncaps ? _currentEncaps->encoding : _encoding; + } + + /** + * Writes the start of a value or exception slice. + * + * @param typeId The Slice type ID for this slice. + * @param compactId The compact ID corresponding to the type, or -1 if no compact ID is used. + * @param last True if this is the last slice, false otherwise. + */ + void startSlice(const std::string& typeId, int compactId, bool last) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startSlice(typeId, compactId, last); + } + + /** + * Marks the end of a value or exception slice. + */ + void endSlice() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endSlice(); + } + + /** + * Encodes the state of class instances whose insertion was delayed during a previous + * call to write. This member function must only be called once. For backward + * compatibility with encoding version 1.0, this function must only be called when + * non-optional data members or parameters use class types. + */ + void writePendingValues(); + + /** + * Writes a size value. + * @param v A non-negative integer. + */ + void writeSize(Int v) // Inlined for performance reasons. + { + assert(v >= 0); + if(v > 254) + { + write(Byte(255)); + write(v); + } + else + { + write(static_cast(v)); + } + } + + /** + * Replaces a size value at the given destination in the stream. This function + * does not change the stream's current position. + * @param v A non-negative integer representing the size. + * @param dest The buffer destination for the size. + */ + void rewriteSize(Int v, Container::iterator dest) + { + assert(v >= 0); + if(v > 254) + { + *dest++ = Byte(255); + write(v, dest); + } + else + { + *dest = static_cast(v); + } + } + + /** + * Writes a placeholder value for the size and returns the starting position of the + * size value; after writing the data, call endSize to patch the placeholder with + * the actual size at the given position. + * @return The starting position of the size value. + */ + size_type startSize() + { + size_type position = b.size(); + write(Int(0)); + return position; + } + + /** + * Updates the size value at the given position to contain a size based on the + * stream's current position. + * @param position The starting position of the size value as returned by startSize. + */ + void endSize(size_type position) + { + rewrite(static_cast(b.size() - position) - 4, position); + } + + /** + * Copies the specified blob of bytes to the stream without modification. + * @param v The bytes to be copied. + */ + void writeBlob(const std::vector& v); + + /** + * Copies the specified blob of bytes to the stream without modification. + * @param v The start of the buffer to be copied. + * @param sz The number of bytes to be copied. + */ + void writeBlob(const Byte* v, Container::size_type sz) + { + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + sz); + memcpy(&b[position], &v[0], sz); + } + } + + /** + * Writes a data value to the stream. + * @param v The data value to be written. + */ + template void write(const T& v) + { + StreamHelper::helper>::write(this, v); + } + + /** + * Writes an optional data value to the stream. + * @param tag The tag ID. + * @param v The data value to be written (if any). + */ + template void write(Int tag, const IceUtil::Optional& v) + { + if(!v) + { + return; // Optional not set + } + + if(writeOptional(tag, StreamOptionalHelper::helper, + StreamableTraits::fixedLength>::optionalFormat)) + { + StreamOptionalHelper::helper, + StreamableTraits::fixedLength>::write(this, *v); + } + } + + /** + * Writes a sequence of data values to the stream. + * @param v The sequence to be written. + */ + template void write(const std::vector& v) + { + if(v.empty()) + { + writeSize(0); + } + else + { + write(&v[0], &v[0] + v.size()); + } + } + + /** + * Writes a sequence of data values to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + template void write(const T* begin, const T* end) + { + writeSize(static_cast(end - begin)); + for(const T* p = begin; p != end; ++p) + { + write(*p); + } + } + +#ifdef ICE_CPP11_MAPPING + + /** + * Writes a list of mandatory data values. + */ + template void writeAll(const T& v) + { + write(v); + } + + /** + * Writes a list of mandatory data values. + */ + template void writeAll(const T& v, const Te&... ve) + { + write(v); + writeAll(ve...); + } + + /** + * Writes a list of mandatory data values. + */ + template + typename std::enable_if::type + writeAll(std::tuple) + { + // Do nothing. Either tuple is empty or we are at the end. + } + + /** + * Writes a list of mandatory data values. + */ + template + typename std::enable_if::type + writeAll(std::tuple tuple) + { + write(std::get(tuple)); + writeAll(tuple); + } + + /** + * Writes a list of optional data values. + */ + template + void writeAll(std::initializer_list tags, const IceUtil::Optional& v) + { + write(*(tags.begin() + tags.size() - 1), v); + } + + /** + * Writes a list of optional data values. + */ + template + void writeAll(std::initializer_list tags, const IceUtil::Optional& v, const IceUtil::Optional&... ve) + { + size_t index = tags.size() - sizeof...(ve) - 1; + write(*(tags.begin() + index), v); + writeAll(tags, ve...); + } + +#endif + + /** + * Writes the tag and format of an optional value. + * @param tag The optional tag ID. + * @param format The optional format. + * @return True if the current encoding version supports optional values, false otherwise. + * If true, the data associated with the optional value must be written next. + */ + bool writeOptional(Int tag, OptionalFormat format) + { + assert(_currentEncaps); + if(_currentEncaps->encoder) + { + return _currentEncaps->encoder->writeOptional(tag, format); + } + else + { + return writeOptImpl(tag, format); + } + } + + /** + * Writes a byte to the stream. + * @param v The byte to write. + */ + void write(Byte v) + { + b.push_back(v); + } + + /** + * Writes a byte sequence to the stream. + * @param start The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Byte* start, const Byte* end); + + /** + * Writes a boolean to the stream. + * @param v The boolean to write. + */ + void write(bool v) + { + b.push_back(static_cast(v)); + } + + /** + * Writes a byte sequence to the stream. + * @param v The sequence to be written. + */ + void write(const std::vector& v); + + /** + * Writes a byte sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const bool* begin, const bool* end); + + /** + * Writes a short to the stream. + * @param v The short to write. + */ + void write(Short v); + + /** + * Writes a short sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Short* begin, const Short* end); + + /** + * Writes an int to the stream. + * @param v The int to write. + */ + void write(Int v) // Inlined for performance reasons. + { + Container::size_type position = b.size(); + resize(position + sizeof(Int)); + write(v, &b[position]); + } + + /** + * Overwrites a 32-bit integer value at the given destination in the stream. + * This function does not change the stream's current position. + * @param v The integer value to be written. + * @param dest The buffer destination for the integer value. + */ + void write(Int v, Container::iterator dest) + { +#ifdef ICE_BIG_ENDIAN + const Byte* src = reinterpret_cast(&v) + sizeof(Int) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#else + const Byte* src = reinterpret_cast(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif + } + + /** + * Writes an int sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Int* begin, const Int* end); + + /** + * Writes a long to the stream. + * @param v The long to write. + */ + void write(Long v); + + /** + * Writes a long sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Long* begin, const Long* end); + + /** + * Writes a float to the stream. + * @param v The float to write. + */ + void write(Float v); + + /** + * Writes a float sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Float* begin, const Float* end); + + /** + * Writes a double to the stream. + * @param v The double to write. + */ + void write(Double v); + + /** + * Writes a double sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const Double* begin, const Double* end); + + /** + * Writes a string to the stream. + * @param v The string to write. + * @param convert Determines whether the string is processed by the narrow string converter, + * if one has been configured. The default behavior is to convert the strings. + */ + void write(const std::string& v, bool convert = true) + { + Int sz = static_cast(v.size()); + if(convert && sz > 0) + { + writeConverted(v.data(), static_cast(sz)); + } + else + { + writeSize(sz); + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + static_cast(sz)); + memcpy(&b[position], v.data(), static_cast(sz)); + } + } + } + + /** + * Writes a string to the stream. + * @param vdata The string to write. + * @param vsize The size of the string. + * @param convert Determines whether the string is processed by the narrow string converter, + * if one has been configured. The default behavior is to convert the strings. + */ + void write(const char* vdata, size_t vsize, bool convert = true) + { + Int sz = static_cast(vsize); + if(convert && sz > 0) + { + writeConverted(vdata, vsize); + } + else + { + writeSize(sz); + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + static_cast(sz)); + memcpy(&b[position], vdata, vsize); + } + } + } + + /** + * Writes a string to the stream. + * @param vdata The null-terminated string to write. + * @param convert Determines whether the string is processed by the narrow string converter, + * if one has been configured. The default behavior is to convert the strings. + */ + void write(const char* vdata, bool convert = true) + { + write(vdata, strlen(vdata), convert); + } + + /** + * Writes a string sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + * @param convert Determines whether the string is processed by the narrow string converter, + * if one has been configured. The default behavior is to convert the strings. + */ + void write(const std::string* begin, const std::string* end, bool convert = true); + + /** + * Writes a wide string to the stream. + * @param v The wide string to write. + */ + void write(const std::wstring& v); + + /** + * Writes a wide string sequence to the stream. + * @param begin The beginning of the sequence. + * @param end The end of the sequence. + */ + void write(const std::wstring* begin, const std::wstring* end); + +#ifdef ICE_CPP11_MAPPING + /** + * Writes a proxy to the stream. + * @param v The proxy to be written. + */ + void writeProxy(const ::std::shared_ptr& v); + + /** + * Writes a proxy to the stream. + * @param v The proxy to be written. + */ + template::value>::type* = nullptr> + void write(const ::std::shared_ptr& v) + { + writeProxy(::std::static_pointer_cast(v)); + } +#else + /** + * Writes a proxy to the stream. + * @param v The proxy to be written. + */ + void write(const ObjectPrx& v); + + /** + * Writes a proxy to the stream. + * @param v The proxy to be written. + */ + template void write(const IceInternal::ProxyHandle& v) + { + write(ObjectPrx(upCast(v.get()))); + } +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + /** + * Writes a value instance to the stream. + * @param v The value to be written. + */ + template::value>::type* = nullptr> + void write(const ::std::shared_ptr& v) + { + initEncaps(); + _currentEncaps->encoder->write(v); + } +#else // C++98 mapping + /** + * Writes a value instance to the stream. + * @param v The value to be written. + */ + void write(const ObjectPtr& v) + { + initEncaps(); + _currentEncaps->encoder->write(v); + } + + /** + * Writes a value instance to the stream. + * @param v The value to be written. + */ + template void write(const IceInternal::Handle& v) + { + write(ObjectPtr(upCast(v.get()))); + } +#endif + + /** + * Writes an enumerator to the stream. + * @param v The enumerator to be written. + * @param maxValue The maximum value of all enumerators in this enumeration. + */ + void writeEnum(Int v, Int maxValue); + + /** + * Writes an exception to the stream. + * @param v The exception to be written. + */ + void writeException(const UserException& v); + + /** + * Obtains the current position of the stream. + * @return The current position. + */ + size_type pos() + { + return b.size(); + } + + /** + * Overwrite a 32-bit integer value at the given position in the stream. + * This function does not change the stream's current position. + * @param v The value to be written. + * @param pos The buffer position for the value. + */ + void rewrite(Int v, size_type pos) + { + write(v, b.begin() + pos); + } + + /** + * Indicates that marshaling is complete. This function must only be called once. + * @param v Filled with a copy of the encoded data. + */ + void finished(std::vector& v); + + /** + * Indicates that marshaling is complete. This function must only be called once. + * @return A pair of pointers into the internal marshaling buffer. These pointers are + * valid for the lifetime of the stream. + */ + std::pair finished(); + + /// \cond INTERNAL + OutputStream(IceInternal::Instance*, const EncodingVersion&); + void initialize(IceInternal::Instance*, const EncodingVersion&); + + // Optionals + bool writeOptImpl(Int, OptionalFormat); + /// \endcond + +private: + + // + // String + // + void writeConverted(const char*, size_t); + + // + // We can't throw this exception from inline functions from within + // this file, because we cannot include the header with the + // exceptions. Doing so would screw up the whole include file + // ordering. + // + void throwEncapsulationException(const char*, int); + + // + // Optimization. The instance may not be deleted while a + // stack-allocated stream still holds it. + // + IceInternal::Instance* _instance; + + // + // The public stream API needs to attach data to a stream. + // + void* _closure; + + class Encaps; + enum SliceType { NoSlice, ValueSlice, ExceptionSlice }; + + typedef std::vector ValueList; + + class ICE_API EncapsEncoder : private ::IceUtil::noncopyable + { + public: + + virtual ~EncapsEncoder(); + + virtual void write(const ValuePtr&) = 0; + virtual void write(const UserException&) = 0; + + virtual void startInstance(SliceType, const SlicedDataPtr&) = 0; + virtual void endInstance() = 0; + virtual void startSlice(const std::string&, int, bool) = 0; + virtual void endSlice() = 0; + + virtual bool writeOptional(Int, OptionalFormat) + { + return false; + } + + virtual void writePendingValues() + { + } + + protected: + + EncapsEncoder(OutputStream* stream, Encaps* encaps) : _stream(stream), _encaps(encaps), _typeIdIndex(0) + { + } + + Int registerTypeId(const std::string&); + + OutputStream* _stream; + Encaps* _encaps; + + typedef std::map PtrToIndexMap; + typedef std::map TypeIdMap; + + // Encapsulation attributes for value marshaling. + PtrToIndexMap _marshaledMap; + + private: + + // Encapsulation attributes for value marshaling. + TypeIdMap _typeIdMap; + Int _typeIdIndex; + }; + + class ICE_API EncapsEncoder10 : public EncapsEncoder + { + public: + + EncapsEncoder10(OutputStream* stream, Encaps* encaps) : + EncapsEncoder(stream, encaps), _sliceType(NoSlice), _valueIdIndex(0) + { + } + + virtual void write(const ValuePtr&); + virtual void write(const UserException&); + + virtual void startInstance(SliceType, const SlicedDataPtr&); + virtual void endInstance(); + virtual void startSlice(const std::string&, int, bool); + virtual void endSlice(); + + virtual void writePendingValues(); + + private: + + Int registerValue(const ValuePtr&); + + // Instance attributes + SliceType _sliceType; + + // Slice attributes + Container::size_type _writeSlice; // Position of the slice data members + + // Encapsulation attributes for value marshaling. + Int _valueIdIndex; + PtrToIndexMap _toBeMarshaledMap; + }; + + class ICE_API EncapsEncoder11 : public EncapsEncoder + { + public: + + EncapsEncoder11(OutputStream* stream, Encaps* encaps) : + EncapsEncoder(stream, encaps), _preAllocatedInstanceData(0), _current(0), _valueIdIndex(1) + { + } + + virtual void write(const ValuePtr&); + virtual void write(const UserException&); + + virtual void startInstance(SliceType, const SlicedDataPtr&); + virtual void endInstance(); + virtual void startSlice(const std::string&, int, bool); + virtual void endSlice(); + + virtual bool writeOptional(Int, OptionalFormat); + + private: + + void writeSlicedData(const SlicedDataPtr&); + void writeInstance(const ValuePtr&); + + struct InstanceData + { + InstanceData(InstanceData* p) : previous(p), next(0) + { + if(previous) + { + previous->next = this; + } + } + + ~InstanceData() + { + if(next) + { + delete next; + } + } + + // Instance attributes + SliceType sliceType; + bool firstSlice; + + // Slice attributes + Byte sliceFlags; + Container::size_type writeSlice; // Position of the slice data members + Container::size_type sliceFlagsPos; // Position of the slice flags + PtrToIndexMap indirectionMap; + ValueList indirectionTable; + + InstanceData* previous; + InstanceData* next; + }; + InstanceData _preAllocatedInstanceData; + InstanceData* _current; + + Int _valueIdIndex; // The ID of the next value to marhsal + }; + + class Encaps : private ::IceUtil::noncopyable + { + + public: + + Encaps() : format(ICE_ENUM(FormatType, DefaultFormat)), encoder(0), previous(0) + { + // Inlined for performance reasons. + } + ~Encaps() + { + // Inlined for performance reasons. + delete encoder; + } + void reset() + { + // Inlined for performance reasons. + delete encoder; + encoder = 0; + + previous = 0; + } + + Container::size_type start; + EncodingVersion encoding; + FormatType format; + + EncapsEncoder* encoder; + + Encaps* previous; + }; + + // + // The encoding version to use when there's no encapsulation to + // read from or write to. This is for example used to read message + // headers or when the user is using the streaming API with no + // encapsulation. + // + EncodingVersion _encoding; + + FormatType _format; + + Encaps* _currentEncaps; + + void initEncaps(); + + Encaps _preAllocatedEncaps; +}; + +} // End namespace Ice + +#endif diff --git a/Sources/IceCpp/include/Ice/Plugin.h b/Sources/IceCpp/include/Ice/Plugin.h new file mode 100644 index 0000000..b7098d2 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Plugin.h @@ -0,0 +1,318 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Plugin.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Plugin_h__ +#define __Ice_Plugin_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Plugin; +class PluginManager; + +} + +namespace Ice +{ + +/** + * A communicator plug-in. A plug-in generally adds a feature to a + * communicator, such as support for a protocol. + * + * The communicator loads its plug-ins in two stages: the first stage + * creates the plug-ins, and the second stage invokes {@link Plugin#initialize} on + * each one. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Plugin +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Plugin(); + + /** + * Perform any necessary initialization steps. + */ + virtual void initialize() = 0; + + /** + * Called when the communicator is being destroyed. + */ + virtual void destroy() = 0; +}; + +/** + * Each communicator has a plug-in manager to administer the set of + * plug-ins. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) PluginManager +{ +public: + + ICE_MEMBER(ICE_API) virtual ~PluginManager(); + + /** + * Initialize the configured plug-ins. The communicator automatically initializes + * the plug-ins by default, but an application may need to interact directly with + * a plug-in prior to initialization. In this case, the application must set + * Ice.InitPlugins=0 and then invoke {@link #initializePlugins} + * manually. The plug-ins are initialized in the order in which they are loaded. + * If a plug-in raises an exception during initialization, the communicator + * invokes destroy on the plug-ins that have already been initialized. + * @throws InitializationException Raised if the plug-ins have already been initialized. + */ + virtual void initializePlugins() = 0; + + /** + * Get a list of plugins installed. + * @return The names of the plugins installed. + * @see #getPlugin + */ + virtual ::Ice::StringSeq getPlugins() noexcept = 0; + + /** + * Obtain a plug-in by name. + * @param name The plug-in's name. + * @return The plug-in. + * @throws NotRegisteredException Raised if no plug-in is found with the given name. + */ + virtual ::std::shared_ptr<::Ice::Plugin> getPlugin(const ::std::string& name) = 0; + + /** + * Install a new plug-in. + * @param name The plug-in's name. + * @param pi The plug-in. + * @throws AlreadyRegisteredException Raised if a plug-in already exists with the given name. + */ + virtual void addPlugin(const ::std::string& name, const ::std::shared_ptr& pi) = 0; + + /** + * Called when the communicator is being destroyed. + */ + virtual void destroy() noexcept = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using PluginPtr = ::std::shared_ptr; + +using PluginManagerPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class Plugin; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Plugin*); +/// \endcond +typedef ::IceInternal::Handle< Plugin> PluginPtr; + +class PluginManager; +/// \cond INTERNAL +ICE_API LocalObject* upCast(PluginManager*); +/// \endcond +typedef ::IceInternal::Handle< PluginManager> PluginManagerPtr; + +} + +namespace Ice +{ + +/** + * A communicator plug-in. A plug-in generally adds a feature to a + * communicator, such as support for a protocol. + * + * The communicator loads its plug-ins in two stages: the first stage + * creates the plug-ins, and the second stage invokes {@link Plugin#initialize} on + * each one. + * \headerfile Ice/Ice.h + */ +class ICE_API Plugin : public virtual LocalObject +{ +public: + + typedef PluginPtr PointerType; + + virtual ~Plugin(); + +#ifdef ICE_CPP11_COMPILER + Plugin() = default; + Plugin(const Plugin&) = default; + Plugin& operator=(const Plugin&) = default; +#endif + + /** + * Perform any necessary initialization steps. + */ + virtual void initialize() = 0; + + /** + * Called when the communicator is being destroyed. + */ + virtual void destroy() = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Plugin& lhs, const Plugin& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Plugin& lhs, const Plugin& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * Each communicator has a plug-in manager to administer the set of + * plug-ins. + * \headerfile Ice/Ice.h + */ +class ICE_API PluginManager : public virtual LocalObject +{ +public: + + typedef PluginManagerPtr PointerType; + + virtual ~PluginManager(); + +#ifdef ICE_CPP11_COMPILER + PluginManager() = default; + PluginManager(const PluginManager&) = default; + PluginManager& operator=(const PluginManager&) = default; +#endif + + /** + * Initialize the configured plug-ins. The communicator automatically initializes + * the plug-ins by default, but an application may need to interact directly with + * a plug-in prior to initialization. In this case, the application must set + * Ice.InitPlugins=0 and then invoke {@link #initializePlugins} + * manually. The plug-ins are initialized in the order in which they are loaded. + * If a plug-in raises an exception during initialization, the communicator + * invokes destroy on the plug-ins that have already been initialized. + * @throws InitializationException Raised if the plug-ins have already been initialized. + */ + virtual void initializePlugins() = 0; + + /** + * Get a list of plugins installed. + * @return The names of the plugins installed. + * @see #getPlugin + */ + virtual StringSeq getPlugins() ICE_NOEXCEPT = 0; + + /** + * Obtain a plug-in by name. + * @param name The plug-in's name. + * @return The plug-in. + * @throws NotRegisteredException Raised if no plug-in is found with the given name. + */ + virtual PluginPtr getPlugin(const ::std::string& name) = 0; + + /** + * Install a new plug-in. + * @param name The plug-in's name. + * @param pi The plug-in. + * @throws AlreadyRegisteredException Raised if a plug-in already exists with the given name. + */ + virtual void addPlugin(const ::std::string& name, const PluginPtr& pi) = 0; + + /** + * Called when the communicator is being destroyed. + */ + virtual void destroy() ICE_NOEXCEPT = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const PluginManager& lhs, const PluginManager& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const PluginManager& lhs, const PluginManager& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/PluginF.h b/Sources/IceCpp/include/Ice/PluginF.h new file mode 100644 index 0000000..1b8dcfc --- /dev/null +++ b/Sources/IceCpp/include/Ice/PluginF.h @@ -0,0 +1,110 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PluginF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_PluginF_h__ +#define __Ice_PluginF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Plugin; +class PluginManager; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using PluginPtr = ::std::shared_ptr; + +using PluginManagerPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class Plugin; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Plugin*); +/// \endcond +typedef ::IceInternal::Handle< Plugin> PluginPtr; + +class PluginManager; +/// \cond INTERNAL +ICE_API LocalObject* upCast(PluginManager*); +/// \endcond +typedef ::IceInternal::Handle< PluginManager> PluginManagerPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/PluginManagerI.h b/Sources/IceCpp/include/Ice/PluginManagerI.h new file mode 100644 index 0000000..d853d5b --- /dev/null +++ b/Sources/IceCpp/include/Ice/PluginManagerI.h @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PLUGIN_MANAGER_I_H +#define ICE_PLUGIN_MANAGER_I_H + +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +typedef Ice::Plugin* (*PluginFactory)(const ::Ice::CommunicatorPtr&, const std::string&, const ::Ice::StringSeq&); + +class PluginManagerI : public PluginManager, public IceUtil::Mutex +{ +public: + + static void registerPluginFactory(const std::string&, PluginFactory, bool); + + virtual void initializePlugins(); + virtual StringSeq getPlugins() ICE_NOEXCEPT; + virtual PluginPtr getPlugin(const std::string&); + virtual void addPlugin(const std::string&, const PluginPtr&); + virtual void destroy() ICE_NOEXCEPT; + PluginManagerI(const CommunicatorPtr&, const IceInternal::DynamicLibraryListPtr&); + +private: + + friend class IceInternal::Instance; + + void loadPlugins(int&, const char*[]); + void loadPlugin(const std::string&, const std::string&, StringSeq&); + + PluginPtr findPlugin(const std::string&) const; + + CommunicatorPtr _communicator; + IceInternal::DynamicLibraryListPtr _libraries; + + struct PluginInfo + { + std::string name; + PluginPtr plugin; + }; + typedef std::vector PluginInfoList; + + PluginInfoList _plugins; + bool _initialized; + static const char * const _kindOfObject; +}; +typedef IceUtil::Handle PluginManagerIPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Process.h b/Sources/IceCpp/include/Ice/Process.h new file mode 100644 index 0000000..f91bc34 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Process.h @@ -0,0 +1,977 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Process.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Process_h__ +#define __Ice_Process_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Process; +class ProcessPrx; + +} + +namespace Ice +{ + +/** + * An administrative interface for process management. Managed servers must + * implement this interface. + * + *

A servant implementing this interface is a potential target + * for denial-of-service attacks, therefore proper security precautions + * should be taken. For example, the servant can use a UUID to make its + * identity harder to guess, and be registered in an object adapter with + * a secured endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_API Process : public virtual Object +{ +public: + + using ProxyType = ProcessPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Initiate a graceful shut-down. + * @param current The Current object for the invocation. + * @see Communicator#shutdown + */ + virtual void shutdown(const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_shutdown(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param current The Current object for the invocation. + */ + virtual void writeMessage(::std::string message, int fd, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_writeMessage(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * An administrative interface for process management. Managed servers must + * implement this interface. + * + *

A servant implementing this interface is a potential target + * for denial-of-service attacks, therefore proper security precautions + * should be taken. For example, the servant can use a UUID to make its + * identity harder to guess, and be registered in an object adapter with + * a secured endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ProcessPrx : public virtual Proxy +{ +public: + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @see Communicator#shutdown + */ + void shutdown(const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &ProcessPrx::_iceI_shutdown, context).get(); + } + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + * @see Communicator#shutdown + */ + template class P = ::std::promise> + auto shutdownAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &ProcessPrx::_iceI_shutdown, context); + } + + /** + * Initiate a graceful shut-down. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + * @see Communicator#shutdown + */ + ::std::function + shutdownAsync(::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::ProcessPrx::_iceI_shutdown, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_shutdown(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const Context&); + /// \endcond + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + */ + void writeMessage(const ::std::string& message, int fd, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &ProcessPrx::_iceI_writeMessage, message, fd, context).get(); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto writeMessageAsync(const ::std::string& message, int fd, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &ProcessPrx::_iceI_writeMessage, message, fd, context); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + writeMessageAsync(const ::std::string& message, int fd, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::ProcessPrx::_iceI_writeMessage, message, fd, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_writeMessage(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, int, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + ProcessPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ProcessPtr = ::std::shared_ptr; +using ProcessPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class Process; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Process>&); +ICE_API ::IceProxy::Ice::Object* upCast(Process*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Process; +/// \cond INTERNAL +ICE_API Object* upCast(Process*); +/// \endcond +typedef ::IceInternal::Handle< Process> ProcessPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Process> ProcessPrx; +typedef ProcessPrx ProcessPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ProcessPtr&, const ObjectPtr&); +/// \endcond + +} + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Process::begin_shutdown. + * Create a wrapper instance by calling ::Ice::newCallback_Process_shutdown. + */ +class Callback_Process_shutdown_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Process_shutdown_Base> Callback_Process_shutdownPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Process::begin_writeMessage. + * Create a wrapper instance by calling ::Ice::newCallback_Process_writeMessage. + */ +class Callback_Process_writeMessage_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Process_writeMessage_Base> Callback_Process_writeMessagePtr; + +} + +namespace IceProxy +{ + +namespace Ice +{ + +class ICE_CLASS(ICE_API) Process : public virtual ::Ice::Proxy +{ +public: + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @see Communicator#shutdown + */ + ICE_MEMBER(ICE_API) void shutdown(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_shutdown(_iceI_begin_shutdown(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + * @see Communicator#shutdown + */ + ::Ice::AsyncResultPtr begin_shutdown(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_shutdown(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Initiate a graceful shut-down. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + * @see Communicator#shutdown + */ + ::Ice::AsyncResultPtr begin_shutdown(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_shutdown(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + * @see Communicator#shutdown + */ + ::Ice::AsyncResultPtr begin_shutdown(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_shutdown(context, cb, cookie); + } + + /** + * Initiate a graceful shut-down. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + * @see Communicator#shutdown + */ + ::Ice::AsyncResultPtr begin_shutdown(const ::Ice::Callback_Process_shutdownPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_shutdown(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Initiate a graceful shut-down. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + * @see Communicator#shutdown + */ + ::Ice::AsyncResultPtr begin_shutdown(const ::Ice::Context& context, const ::Ice::Callback_Process_shutdownPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_shutdown(context, cb, cookie); + } + + /** + * Completes an invocation of begin_shutdown. + * @param result The asynchronous result object for the invocation. + */ + ICE_MEMBER(ICE_API) void end_shutdown(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_shutdown(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + */ + ICE_MEMBER(ICE_API) void writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_writeMessage(_iceI_begin_writeMessage(message, fd, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_writeMessage(message, fd, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_writeMessage(message, fd, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_writeMessage(message, fd, context, cb, cookie); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::Callback_Process_writeMessagePtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_writeMessage(message, fd, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_writeMessage(const ::std::string& message, ::Ice::Int fd, const ::Ice::Context& context, const ::Ice::Callback_Process_writeMessagePtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_writeMessage(message, fd, context, cb, cookie); + } + + /** + * Completes an invocation of begin_writeMessage. + * @param result The asynchronous result object for the invocation. + */ + ICE_MEMBER(ICE_API) void end_writeMessage(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_writeMessage(const ::std::string&, ::Ice::Int, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace Ice +{ + +/** + * An administrative interface for process management. Managed servers must + * implement this interface. + * + *

A servant implementing this interface is a potential target + * for denial-of-service attacks, therefore proper security precautions + * should be taken. For example, the servant can use a UUID to make its + * identity harder to guess, and be registered in an object adapter with + * a secured endpoint. + * \headerfile Ice/Ice.h + */ +class ICE_API Process : public virtual Object +{ +public: + + typedef ProcessPrx ProxyType; + typedef ProcessPtr PointerType; + + virtual ~Process(); + +#ifdef ICE_CPP11_COMPILER + Process() = default; + Process(const Process&) = default; + Process& operator=(const Process&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Initiate a graceful shut-down. + * @param current The Current object for the invocation. + * @see Communicator#shutdown + */ + virtual void shutdown(const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_shutdown(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Write a message on the process' stdout or stderr. + * @param message The message. + * @param fd 1 for stdout, 2 for stderr. + * @param current The Current object for the invocation. + */ + virtual void writeMessage(const ::std::string& message, Int fd, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_writeMessage(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const Process& lhs, const Process& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Process& lhs, const Process& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Process::begin_shutdown. + * Create a wrapper instance by calling ::Ice::newCallback_Process_shutdown. + */ +template +class CallbackNC_Process_shutdown : public Callback_Process_shutdown_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Process_shutdown(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_shutdown(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_shutdown(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_shutdown(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_shutdown(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Process::begin_shutdown. + * Create a wrapper instance by calling ::Ice::newCallback_Process_shutdown. + */ +template +class Callback_Process_shutdown : public Callback_Process_shutdown_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Process_shutdown(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_shutdown(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_shutdown(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_shutdown(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_shutdown. + */ +template Callback_Process_shutdownPtr +newCallback_Process_shutdown(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_shutdown(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Process::begin_writeMessage. + * Create a wrapper instance by calling ::Ice::newCallback_Process_writeMessage. + */ +template +class CallbackNC_Process_writeMessage : public Callback_Process_writeMessage_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Process_writeMessage(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_writeMessage(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_writeMessage(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_writeMessage(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Process_writeMessage(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Process::begin_writeMessage. + * Create a wrapper instance by calling ::Ice::newCallback_Process_writeMessage. + */ +template +class Callback_Process_writeMessage : public Callback_Process_writeMessage_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Process_writeMessage(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_writeMessage(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_writeMessage(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_writeMessage(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Process::begin_writeMessage. + */ +template Callback_Process_writeMessagePtr +newCallback_Process_writeMessage(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Process_writeMessage(instance, 0, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ProcessF.h b/Sources/IceCpp/include/Ice/ProcessF.h new file mode 100644 index 0000000..44f3e73 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProcessF.h @@ -0,0 +1,125 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ProcessF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ProcessF_h__ +#define __Ice_ProcessF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Process; +class ProcessPrx; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ProcessPtr = ::std::shared_ptr; +using ProcessPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class Process; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Process>&); +ICE_API ::IceProxy::Ice::Object* upCast(Process*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Process; +/// \cond INTERNAL +ICE_API Object* upCast(Process*); +/// \endcond +typedef ::IceInternal::Handle< Process> ProcessPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Process> ProcessPrx; +typedef ProcessPrx ProcessPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(ProcessPtr&, const ObjectPtr&); +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/Properties.h b/Sources/IceCpp/include/Ice/Properties.h new file mode 100644 index 0000000..0a25aa9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Properties.h @@ -0,0 +1,452 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Properties.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Properties_h__ +#define __Ice_Properties_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Properties; + +} + +namespace Ice +{ + +/** + * A property set used to configure Ice and Ice applications. + * Properties are key/value pairs, with both keys and values + * being strings. By convention, property keys should have the form + * application-name[.category[.sub-category]].name. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) Properties +{ +public: + + ICE_MEMBER(ICE_API) virtual ~Properties(); + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @return The property value. + * @see #setProperty + */ + virtual ::std::string getProperty(const ::std::string& key) noexcept = 0; + + /** + * Get a property by key. If the property is not set, the + * given default value is returned. + * @param key The property key. + * @param value The default value to use if the property does not + * exist. + * @return The property value or the default value. + * @see #setProperty + */ + virtual ::std::string getPropertyWithDefault(const ::std::string& key, const ::std::string& value) noexcept = 0; + + /** + * Get a property as an integer. If the property is not set, 0 + * is returned. + * @param key The property key. + * @return The property value interpreted as an integer. + * @see #setProperty + */ + virtual int getPropertyAsInt(const ::std::string& key) noexcept = 0; + + /** + * Get a property as an integer. If the property is not set, the + * given default value is returned. + * @param key The property key. + * @param value The default value to use if the property does not + * exist. + * @return The property value interpreted as an integer, or the + * default value. + * @see #setProperty + */ + virtual int getPropertyAsIntWithDefault(const ::std::string& key, int value) noexcept = 0; + + /** + * Get a property as a list of strings. The strings must be + * separated by whitespace or comma. If the property is not set, + * an empty list is returned. The strings in the list can contain + * whitespace and commas if they are enclosed in single or double + * quotes. If quotes are mismatched, an empty list is returned. + * Within single quotes or double quotes, you can escape the + * quote in question with a backslash, e.g. O'Reilly can be written as + * O'Reilly, "O'Reilly" or 'O\'Reilly'. + * @param key The property key. + * @return The property value interpreted as a list of strings. + * @see #setProperty + */ + virtual ::Ice::StringSeq getPropertyAsList(const ::std::string& key) noexcept = 0; + + /** + * Get a property as a list of strings. The strings must be + * separated by whitespace or comma. If the property is not set, + * the default list is returned. The strings in the list can contain + * whitespace and commas if they are enclosed in single or double + * quotes. If quotes are mismatched, the default list is returned. + * Within single quotes or double quotes, you can escape the + * quote in question with a backslash, e.g. O'Reilly can be written as + * O'Reilly, "O'Reilly" or 'O\'Reilly'. + * @param key The property key. + * @param value The default value to use if the property is not set. + * @return The property value interpreted as list of strings, or the + * default value. + * @see #setProperty + */ + virtual ::Ice::StringSeq getPropertyAsListWithDefault(const ::std::string& key, const StringSeq& value) noexcept = 0; + + /** + * Get all properties whose keys begins with + * prefix. If + * prefix is an empty string, + * then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @return The matching property set. + */ + virtual ::Ice::PropertyDict getPropertiesForPrefix(const ::std::string& prefix) noexcept = 0; + + /** + * Set a property. To unset a property, set it to + * the empty string. + * @param key The property key. + * @param value The property value. + * @see #getProperty + */ + virtual void setProperty(const ::std::string& key, const ::std::string& value) = 0; + + /** + * Get a sequence of command-line options that is equivalent to + * this property set. Each element of the returned sequence is + * a command-line option of the form + * --key=value. + * @return The command line options for this property set. + */ + virtual ::Ice::StringSeq getCommandLineOptions() noexcept = 0; + + /** + * Convert a sequence of command-line options into properties. + * All options that begin with + * --prefix. are + * converted into properties. If the prefix is empty, all options + * that begin with -- are converted to properties. + * @param prefix The property prefix, or an empty string to + * convert all options starting with --. + * @param options The command-line options. + * @return The command-line options that do not start with the specified + * prefix, in their original order. + */ + virtual ::Ice::StringSeq parseCommandLineOptions(const ::std::string& prefix, const StringSeq& options) = 0; + + /** + * Convert a sequence of command-line options into properties. + * All options that begin with one of the following prefixes + * are converted into properties: --Ice, --IceBox, --IceGrid, + * --IcePatch2, --IceSSL, --IceStorm, --Freeze, and --Glacier2. + * @param options The command-line options. + * @return The command-line options that do not start with one of + * the listed prefixes, in their original order. + */ + virtual ::Ice::StringSeq parseIceCommandLineOptions(const StringSeq& options) = 0; + + /** + * Load properties from a file. + * @param file The property file. + */ + virtual void load(const ::std::string& file) = 0; + + /** + * Create a copy of this property set. + * @return A copy of this property set. + */ + virtual ::std::shared_ptr<::Ice::Properties> clone() noexcept = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using PropertiesPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +} + +namespace Ice +{ + +class Properties; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Properties*); +/// \endcond +typedef ::IceInternal::Handle< Properties> PropertiesPtr; + +} + +namespace IceProxy +{ + +} + +namespace Ice +{ + +/** + * A property set used to configure Ice and Ice applications. + * Properties are key/value pairs, with both keys and values + * being strings. By convention, property keys should have the form + * application-name[.category[.sub-category]].name. + * \headerfile Ice/Ice.h + */ +class ICE_API Properties : public virtual LocalObject +{ +public: + + typedef PropertiesPtr PointerType; + + virtual ~Properties(); + +#ifdef ICE_CPP11_COMPILER + Properties() = default; + Properties(const Properties&) = default; + Properties& operator=(const Properties&) = default; +#endif + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @return The property value. + * @see #setProperty + */ + virtual ::std::string getProperty(const ::std::string& key) ICE_NOEXCEPT = 0; + + /** + * Get a property by key. If the property is not set, the + * given default value is returned. + * @param key The property key. + * @param value The default value to use if the property does not + * exist. + * @return The property value or the default value. + * @see #setProperty + */ + virtual ::std::string getPropertyWithDefault(const ::std::string& key, const ::std::string& value) ICE_NOEXCEPT = 0; + + /** + * Get a property as an integer. If the property is not set, 0 + * is returned. + * @param key The property key. + * @return The property value interpreted as an integer. + * @see #setProperty + */ + virtual Int getPropertyAsInt(const ::std::string& key) ICE_NOEXCEPT = 0; + + /** + * Get a property as an integer. If the property is not set, the + * given default value is returned. + * @param key The property key. + * @param value The default value to use if the property does not + * exist. + * @return The property value interpreted as an integer, or the + * default value. + * @see #setProperty + */ + virtual Int getPropertyAsIntWithDefault(const ::std::string& key, Int value) ICE_NOEXCEPT = 0; + + /** + * Get a property as a list of strings. The strings must be + * separated by whitespace or comma. If the property is not set, + * an empty list is returned. The strings in the list can contain + * whitespace and commas if they are enclosed in single or double + * quotes. If quotes are mismatched, an empty list is returned. + * Within single quotes or double quotes, you can escape the + * quote in question with a backslash, e.g. O'Reilly can be written as + * O'Reilly, "O'Reilly" or 'O\'Reilly'. + * @param key The property key. + * @return The property value interpreted as a list of strings. + * @see #setProperty + */ + virtual StringSeq getPropertyAsList(const ::std::string& key) ICE_NOEXCEPT = 0; + + /** + * Get a property as a list of strings. The strings must be + * separated by whitespace or comma. If the property is not set, + * the default list is returned. The strings in the list can contain + * whitespace and commas if they are enclosed in single or double + * quotes. If quotes are mismatched, the default list is returned. + * Within single quotes or double quotes, you can escape the + * quote in question with a backslash, e.g. O'Reilly can be written as + * O'Reilly, "O'Reilly" or 'O\'Reilly'. + * @param key The property key. + * @param value The default value to use if the property is not set. + * @return The property value interpreted as list of strings, or the + * default value. + * @see #setProperty + */ + virtual StringSeq getPropertyAsListWithDefault(const ::std::string& key, const StringSeq& value) ICE_NOEXCEPT = 0; + + /** + * Get all properties whose keys begins with + * prefix. If + * prefix is an empty string, + * then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @return The matching property set. + */ + virtual PropertyDict getPropertiesForPrefix(const ::std::string& prefix) ICE_NOEXCEPT = 0; + + /** + * Set a property. To unset a property, set it to + * the empty string. + * @param key The property key. + * @param value The property value. + * @see #getProperty + */ + virtual void setProperty(const ::std::string& key, const ::std::string& value) = 0; + + /** + * Get a sequence of command-line options that is equivalent to + * this property set. Each element of the returned sequence is + * a command-line option of the form + * --key=value. + * @return The command line options for this property set. + */ + virtual StringSeq getCommandLineOptions() ICE_NOEXCEPT = 0; + + /** + * Convert a sequence of command-line options into properties. + * All options that begin with + * --prefix. are + * converted into properties. If the prefix is empty, all options + * that begin with -- are converted to properties. + * @param prefix The property prefix, or an empty string to + * convert all options starting with --. + * @param options The command-line options. + * @return The command-line options that do not start with the specified + * prefix, in their original order. + */ + virtual StringSeq parseCommandLineOptions(const ::std::string& prefix, const StringSeq& options) = 0; + + /** + * Convert a sequence of command-line options into properties. + * All options that begin with one of the following prefixes + * are converted into properties: --Ice, --IceBox, --IceGrid, + * --IcePatch2, --IceSSL, --IceStorm, --Freeze, and --Glacier2. + * @param options The command-line options. + * @return The command-line options that do not start with one of + * the listed prefixes, in their original order. + */ + virtual StringSeq parseIceCommandLineOptions(const StringSeq& options) = 0; + + /** + * Load properties from a file. + * @param file The property file. + */ + virtual void load(const ::std::string& file) = 0; + + /** + * Create a copy of this property set. + * @return A copy of this property set. + */ + virtual PropertiesPtr clone() ICE_NOEXCEPT = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const Properties& lhs, const Properties& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Properties& lhs, const Properties& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/PropertiesAdmin.h b/Sources/IceCpp/include/Ice/PropertiesAdmin.h new file mode 100644 index 0000000..663ced1 --- /dev/null +++ b/Sources/IceCpp/include/Ice/PropertiesAdmin.h @@ -0,0 +1,1366 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesAdmin.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_PropertiesAdmin_h__ +#define __Ice_PropertiesAdmin_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class PropertiesAdmin; +class PropertiesAdminPrx; + +} + +namespace Ice +{ + +/** + * A simple collection of properties, represented as a dictionary of + * key/value pairs. Both key and value are strings. + * @see Properties#getPropertiesForPrefix + */ +using PropertyDict = ::std::map<::std::string, ::std::string>; + +} + +namespace Ice +{ + +/** + * The PropertiesAdmin interface provides remote access to the properties + * of a communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API PropertiesAdmin : public virtual Object +{ +public: + + using ProxyType = PropertiesAdminPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param current The Current object for the invocation. + * @return The property value. + */ + virtual ::std::string getProperty(::std::string key, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getProperty(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param current The Current object for the invocation. + * @return The matching property set. + */ + virtual PropertyDict getPropertiesForPrefix(::std::string prefix, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getPropertiesForPrefix(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param current The Current object for the invocation. + */ + virtual void setProperties(PropertyDict newProperties, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_setProperties(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * The PropertiesAdmin interface provides remote access to the properties + * of a communicator. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) PropertiesAdminPrx : public virtual Proxy +{ +public: + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @return The property value. + */ + ::std::string getProperty(const ::std::string& key, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::string>(true, this, &PropertiesAdminPrx::_iceI_getProperty, key, context).get(); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getPropertyAsync(const ::std::string& key, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing<::std::string, P>(false, this, &PropertiesAdminPrx::_iceI_getProperty, key, context); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getPropertyAsync(const ::std::string& key, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::string>(std::move(response), std::move(ex), std::move(sent), this, &Ice::PropertiesAdminPrx::_iceI_getProperty, key, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getProperty(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::string>>&, const ::std::string&, const Context&); + /// \endcond + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @return The matching property set. + */ + PropertyDict getPropertiesForPrefix(const ::std::string& prefix, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::Ice::PropertyDict>(true, this, &PropertiesAdminPrx::_iceI_getPropertiesForPrefix, prefix, context).get(); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getPropertiesForPrefixAsync(const ::std::string& prefix, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing<::Ice::PropertyDict, P>(false, this, &PropertiesAdminPrx::_iceI_getPropertiesForPrefix, prefix, context); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getPropertiesForPrefixAsync(const ::std::string& prefix, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::Ice::PropertyDict>(std::move(response), std::move(ex), std::move(sent), this, &Ice::PropertiesAdminPrx::_iceI_getPropertiesForPrefix, prefix, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getPropertiesForPrefix(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::Ice::PropertyDict>>&, const ::std::string&, const Context&); + /// \endcond + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + */ + void setProperties(const PropertyDict& newProperties, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &PropertiesAdminPrx::_iceI_setProperties, newProperties, context).get(); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto setPropertiesAsync(const PropertyDict& newProperties, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &PropertiesAdminPrx::_iceI_setProperties, newProperties, context); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + setPropertiesAsync(const PropertyDict& newProperties, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::PropertiesAdminPrx::_iceI_setProperties, newProperties, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_setProperties(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const PropertyDict&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + PropertiesAdminPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using PropertiesAdminPtr = ::std::shared_ptr; +using PropertiesAdminPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class PropertiesAdmin; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< PropertiesAdmin>&); +ICE_API ::IceProxy::Ice::Object* upCast(PropertiesAdmin*); +/// \endcond + +} + +} + +namespace Ice +{ + +class PropertiesAdmin; +/// \cond INTERNAL +ICE_API Object* upCast(PropertiesAdmin*); +/// \endcond +typedef ::IceInternal::Handle< PropertiesAdmin> PropertiesAdminPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::PropertiesAdmin> PropertiesAdminPrx; +typedef PropertiesAdminPrx PropertiesAdminPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(PropertiesAdminPtr&, const ObjectPtr&); +/// \endcond + +} + +namespace Ice +{ + +/** + * A simple collection of properties, represented as a dictionary of + * key/value pairs. Both key and value are strings. + * @see Properties#getPropertiesForPrefix + */ +typedef ::std::map< ::std::string, ::std::string> PropertyDict; + +} + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getProperty. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getProperty. + */ +class Callback_PropertiesAdmin_getProperty_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_PropertiesAdmin_getProperty_Base> Callback_PropertiesAdmin_getPropertyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getPropertiesForPrefix. + */ +class Callback_PropertiesAdmin_getPropertiesForPrefix_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_PropertiesAdmin_getPropertiesForPrefix_Base> Callback_PropertiesAdmin_getPropertiesForPrefixPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_setProperties. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_setProperties. + */ +class Callback_PropertiesAdmin_setProperties_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_PropertiesAdmin_setProperties_Base> Callback_PropertiesAdmin_setPropertiesPtr; + +} + +namespace IceProxy +{ + +namespace Ice +{ + +class ICE_CLASS(ICE_API) PropertiesAdmin : public virtual ::Ice::Proxy +{ +public: + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @return The property value. + */ + ICE_MEMBER(ICE_API) ::std::string getProperty(const ::std::string& key, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getProperty(_iceI_begin_getProperty(key, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getProperty(const ::std::string& key, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getProperty(key, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getProperty(const ::std::string& key, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getProperty(key, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getProperty(const ::std::string& key, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getProperty(key, context, cb, cookie); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getProperty(const ::std::string& key, const ::Ice::Callback_PropertiesAdmin_getPropertyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getProperty(key, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getProperty(const ::std::string& key, const ::Ice::Context& context, const ::Ice::Callback_PropertiesAdmin_getPropertyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getProperty(key, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getProperty. + * @param result The asynchronous result object for the invocation. + * @return The property value. + */ + ICE_MEMBER(ICE_API) ::std::string end_getProperty(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getProperty(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @return The matching property set. + */ + ICE_MEMBER(ICE_API) ::Ice::PropertyDict getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getPropertiesForPrefix(_iceI_begin_getPropertiesForPrefix(prefix, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getPropertiesForPrefix(prefix, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getPropertiesForPrefix(prefix, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getPropertiesForPrefix(prefix, context, cb, cookie); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::Callback_PropertiesAdmin_getPropertiesForPrefixPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getPropertiesForPrefix(prefix, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getPropertiesForPrefix(const ::std::string& prefix, const ::Ice::Context& context, const ::Ice::Callback_PropertiesAdmin_getPropertiesForPrefixPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getPropertiesForPrefix(prefix, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getPropertiesForPrefix. + * @param result The asynchronous result object for the invocation. + * @return The matching property set. + */ + ICE_MEMBER(ICE_API) ::Ice::PropertyDict end_getPropertiesForPrefix(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getPropertiesForPrefix(const ::std::string&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + */ + ICE_MEMBER(ICE_API) void setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_setProperties(_iceI_begin_setProperties(newProperties, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_setProperties(newProperties, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setProperties(newProperties, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setProperties(newProperties, context, cb, cookie); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::Callback_PropertiesAdmin_setPropertiesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setProperties(newProperties, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_setProperties(const ::Ice::PropertyDict& newProperties, const ::Ice::Context& context, const ::Ice::Callback_PropertiesAdmin_setPropertiesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_setProperties(newProperties, context, cb, cookie); + } + + /** + * Completes an invocation of begin_setProperties. + * @param result The asynchronous result object for the invocation. + */ + ICE_MEMBER(ICE_API) void end_setProperties(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_setProperties(const ::Ice::PropertyDict&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace Ice +{ + +/** + * The PropertiesAdmin interface provides remote access to the properties + * of a communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API PropertiesAdmin : public virtual Object +{ +public: + + typedef PropertiesAdminPrx ProxyType; + typedef PropertiesAdminPtr PointerType; + + virtual ~PropertiesAdmin(); + +#ifdef ICE_CPP11_COMPILER + PropertiesAdmin() = default; + PropertiesAdmin(const PropertiesAdmin&) = default; + PropertiesAdmin& operator=(const PropertiesAdmin&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get a property by key. If the property is not set, an empty + * string is returned. + * @param key The property key. + * @param current The Current object for the invocation. + * @return The property value. + */ + virtual ::std::string getProperty(const ::std::string& key, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getProperty(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Get all properties whose keys begin with prefix. If + * prefix is an empty string then all properties are returned. + * @param prefix The prefix to search for (empty string if none). + * @param current The Current object for the invocation. + * @return The matching property set. + */ + virtual PropertyDict getPropertiesForPrefix(const ::std::string& prefix, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getPropertiesForPrefix(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Update the communicator's properties with the given property set. + * @param newProperties Properties to be added, changed, or removed. + * If an entry in newProperties matches the name of an existing property, + * that property's value is replaced with the new value. If the new value + * is an empty string, the property is removed. Any existing properties + * that are not modified or removed by the entries in newProperties are + * retained with their original values. + * @param current The Current object for the invocation. + */ + virtual void setProperties(const PropertyDict& newProperties, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_setProperties(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const PropertiesAdmin& lhs, const PropertiesAdmin& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const PropertiesAdmin& lhs, const PropertiesAdmin& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getProperty. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getProperty. + */ +template +class CallbackNC_PropertiesAdmin_getProperty : public Callback_PropertiesAdmin_getProperty_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ::std::string&); + + CallbackNC_PropertiesAdmin_getProperty(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + PropertiesAdminPrx proxy = PropertiesAdminPrx::uncheckedCast(result->getProxy()); + ::std::string ret; + try + { + ret = proxy->end_getProperty(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getProperty. + */ +template Callback_PropertiesAdmin_getPropertyPtr +newCallback_PropertiesAdmin_getProperty(const IceUtil::Handle& instance, void (T::*cb)(const ::std::string&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_getProperty(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getProperty. + */ +template Callback_PropertiesAdmin_getPropertyPtr +newCallback_PropertiesAdmin_getProperty(T* instance, void (T::*cb)(const ::std::string&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_getProperty(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getProperty. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getProperty. + */ +template +class Callback_PropertiesAdmin_getProperty : public Callback_PropertiesAdmin_getProperty_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ::std::string&, const CT&); + + Callback_PropertiesAdmin_getProperty(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + PropertiesAdminPrx proxy = PropertiesAdminPrx::uncheckedCast(result->getProxy()); + ::std::string ret; + try + { + ret = proxy->end_getProperty(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getProperty. + */ +template Callback_PropertiesAdmin_getPropertyPtr +newCallback_PropertiesAdmin_getProperty(const IceUtil::Handle& instance, void (T::*cb)(const ::std::string&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_getProperty(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getProperty. + */ +template Callback_PropertiesAdmin_getPropertyPtr +newCallback_PropertiesAdmin_getProperty(T* instance, void (T::*cb)(const ::std::string&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_getProperty(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getPropertiesForPrefix. + */ +template +class CallbackNC_PropertiesAdmin_getPropertiesForPrefix : public Callback_PropertiesAdmin_getPropertiesForPrefix_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const PropertyDict&); + + CallbackNC_PropertiesAdmin_getPropertiesForPrefix(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + PropertiesAdminPrx proxy = PropertiesAdminPrx::uncheckedCast(result->getProxy()); + PropertyDict ret; + try + { + ret = proxy->end_getPropertiesForPrefix(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + */ +template Callback_PropertiesAdmin_getPropertiesForPrefixPtr +newCallback_PropertiesAdmin_getPropertiesForPrefix(const IceUtil::Handle& instance, void (T::*cb)(const PropertyDict&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_getPropertiesForPrefix(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + */ +template Callback_PropertiesAdmin_getPropertiesForPrefixPtr +newCallback_PropertiesAdmin_getPropertiesForPrefix(T* instance, void (T::*cb)(const PropertyDict&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_getPropertiesForPrefix(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_getPropertiesForPrefix. + */ +template +class Callback_PropertiesAdmin_getPropertiesForPrefix : public Callback_PropertiesAdmin_getPropertiesForPrefix_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const PropertyDict&, const CT&); + + Callback_PropertiesAdmin_getPropertiesForPrefix(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + PropertiesAdminPrx proxy = PropertiesAdminPrx::uncheckedCast(result->getProxy()); + PropertyDict ret; + try + { + ret = proxy->end_getPropertiesForPrefix(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + */ +template Callback_PropertiesAdmin_getPropertiesForPrefixPtr +newCallback_PropertiesAdmin_getPropertiesForPrefix(const IceUtil::Handle& instance, void (T::*cb)(const PropertyDict&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_getPropertiesForPrefix(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_getPropertiesForPrefix. + */ +template Callback_PropertiesAdmin_getPropertiesForPrefixPtr +newCallback_PropertiesAdmin_getPropertiesForPrefix(T* instance, void (T::*cb)(const PropertyDict&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_getPropertiesForPrefix(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_setProperties. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_setProperties. + */ +template +class CallbackNC_PropertiesAdmin_setProperties : public Callback_PropertiesAdmin_setProperties_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_PropertiesAdmin_setProperties(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_setProperties(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_setProperties(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_setProperties(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_PropertiesAdmin_setProperties(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::PropertiesAdmin::begin_setProperties. + * Create a wrapper instance by calling ::Ice::newCallback_PropertiesAdmin_setProperties. + */ +template +class Callback_PropertiesAdmin_setProperties : public Callback_PropertiesAdmin_setProperties_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_PropertiesAdmin_setProperties(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_setProperties(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_setProperties(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_setProperties(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::PropertiesAdmin::begin_setProperties. + */ +template Callback_PropertiesAdmin_setPropertiesPtr +newCallback_PropertiesAdmin_setProperties(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_PropertiesAdmin_setProperties(instance, 0, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/PropertiesAdminI.h b/Sources/IceCpp/include/Ice/PropertiesAdminI.h new file mode 100644 index 0000000..d04da8f --- /dev/null +++ b/Sources/IceCpp/include/Ice/PropertiesAdminI.h @@ -0,0 +1,64 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROPERTIES_ADMIN_I_H +#define ICE_PROPERTIES_ADMIN_I_H + +#include +#include +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING +#include +#endif + +namespace IceInternal +{ + +class PropertiesAdminI : public Ice::PropertiesAdmin, public Ice::NativePropertiesAdmin, +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this, +#endif + private IceUtil::RecMutex +{ +public: + + PropertiesAdminI(const InstancePtr&); + +#ifdef ICE_CPP11_MAPPING + virtual std::string getProperty(std::string, const Ice::Current&) override; + virtual Ice::PropertyDict getPropertiesForPrefix(std::string, const Ice::Current&) override; + virtual void setProperties(::Ice::PropertyDict, const Ice::Current&) override; + + virtual std::function addUpdateCallback(std::function) override; + void removeUpdateCallback(std::list>::iterator); + +#else + virtual std::string getProperty(const std::string&, const Ice::Current&); + virtual Ice::PropertyDict getPropertiesForPrefix(const std::string&, const Ice::Current&); + virtual void setProperties(const Ice::PropertyDict&, const Ice::Current&); + + virtual void addUpdateCallback(const Ice::PropertiesAdminUpdateCallbackPtr&); + virtual void removeUpdateCallback(const Ice::PropertiesAdminUpdateCallbackPtr&); +#endif + +private: + + const Ice::PropertiesPtr _properties; + const Ice::LoggerPtr _logger; + +#ifdef ICE_CPP11_MAPPING + std::list> _updateCallbacks; +#else + std::vector _updateCallbacks; +#endif + +}; +ICE_DEFINE_PTR(PropertiesAdminIPtr, PropertiesAdminI); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/PropertiesF.h b/Sources/IceCpp/include/Ice/PropertiesF.h new file mode 100644 index 0000000..ebb7f68 --- /dev/null +++ b/Sources/IceCpp/include/Ice/PropertiesF.h @@ -0,0 +1,134 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PropertiesF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_PropertiesF_h__ +#define __Ice_PropertiesF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Properties; +class PropertiesAdmin; +class PropertiesAdminPrx; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using PropertiesPtr = ::std::shared_ptr; + +using PropertiesAdminPtr = ::std::shared_ptr; +using PropertiesAdminPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class PropertiesAdmin; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< PropertiesAdmin>&); +ICE_API ::IceProxy::Ice::Object* upCast(PropertiesAdmin*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Properties; +/// \cond INTERNAL +ICE_API LocalObject* upCast(Properties*); +/// \endcond +typedef ::IceInternal::Handle< Properties> PropertiesPtr; + +class PropertiesAdmin; +/// \cond INTERNAL +ICE_API Object* upCast(PropertiesAdmin*); +/// \endcond +typedef ::IceInternal::Handle< PropertiesAdmin> PropertiesAdminPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::PropertiesAdmin> PropertiesAdminPrx; +typedef PropertiesAdminPrx PropertiesAdminPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(PropertiesAdminPtr&, const ObjectPtr&); +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/PropertiesI.h b/Sources/IceCpp/include/Ice/PropertiesI.h new file mode 100644 index 0000000..b78788e --- /dev/null +++ b/Sources/IceCpp/include/Ice/PropertiesI.h @@ -0,0 +1,70 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROPERTIES_I_H +#define ICE_PROPERTIES_I_H + +#include +#include +#include + +#include + +namespace Ice +{ + +class PropertiesI : public Properties, public IceUtil::Mutex +{ +public: + + virtual std::string getProperty(const std::string&) ICE_NOEXCEPT; + virtual std::string getPropertyWithDefault(const std::string&, const std::string&) ICE_NOEXCEPT; + virtual Ice::Int getPropertyAsInt(const std::string&) ICE_NOEXCEPT; + virtual Ice::Int getPropertyAsIntWithDefault(const std::string&, Ice::Int) ICE_NOEXCEPT; + virtual Ice::StringSeq getPropertyAsList(const std::string&) ICE_NOEXCEPT; + virtual Ice::StringSeq getPropertyAsListWithDefault(const std::string&, const Ice::StringSeq&) ICE_NOEXCEPT; + + virtual PropertyDict getPropertiesForPrefix(const std::string&) ICE_NOEXCEPT; + virtual void setProperty(const std::string&, const std::string&); + virtual StringSeq getCommandLineOptions() ICE_NOEXCEPT; + virtual StringSeq parseCommandLineOptions(const std::string&, const StringSeq&); + virtual StringSeq parseIceCommandLineOptions(const StringSeq&); + virtual void load(const std::string&); + virtual PropertiesPtr clone() ICE_NOEXCEPT; + + std::set getUnusedProperties(); + + PropertiesI(const PropertiesI*); + + PropertiesI(); + PropertiesI(StringSeq&, const PropertiesPtr&); + +private: + + void parseLine(const std::string&, const StringConverterPtr&); + + void loadConfig(); + + struct PropertyValue + { + PropertyValue() : + used(false) + { + } + + PropertyValue(const std::string& v, bool u) : + value(v), + used(u) + { + } + + std::string value; + bool used; + }; + std::map _properties; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/PropertyNames.h b/Sources/IceCpp/include/Ice/PropertyNames.h new file mode 100644 index 0000000..8f51beb --- /dev/null +++ b/Sources/IceCpp/include/Ice/PropertyNames.h @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Jan 7 10:30:00 2022 + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! + +#ifndef ICE_INTERNAL_PropertyNames_H +#define ICE_INTERNAL_PropertyNames_H + +#include + +namespace IceInternal +{ + +struct Property +{ + const char* pattern; + bool deprecated; + const char* deprecatedBy; + + Property(const char* n, bool d, const char* b) : + pattern(n), + deprecated(d), + deprecatedBy(b) + { + } + + Property() : + pattern(0), + deprecated(false), + deprecatedBy(0) + { + } + +}; + +struct PropertyArray +{ + const Property* properties; + const int length; + + PropertyArray(const Property* p, size_t len) : + properties(p), + length(static_cast(len)) + { + } +}; + +class PropertyNames +{ +public: + + static const PropertyArray IceProps; + static const PropertyArray IceMXProps; + static const PropertyArray IceDiscoveryProps; + static const PropertyArray IceLocatorDiscoveryProps; + static const PropertyArray IceBoxProps; + static const PropertyArray IceBoxAdminProps; + static const PropertyArray IceBridgeProps; + static const PropertyArray IceGridAdminProps; + static const PropertyArray IceGridProps; + static const PropertyArray IcePatch2Props; + static const PropertyArray IcePatch2ClientProps; + static const PropertyArray IceSSLProps; + static const PropertyArray IceStormAdminProps; + static const PropertyArray IceBTProps; + static const PropertyArray Glacier2Props; + static const PropertyArray Glacier2CryptPermissionsVerifierProps; + static const PropertyArray FreezeProps; + + static const PropertyArray validProps[]; + static const char * clPropNames[]; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Protocol.h b/Sources/IceCpp/include/Ice/Protocol.h new file mode 100644 index 0000000..6aef6ae --- /dev/null +++ b/Sources/IceCpp/include/Ice/Protocol.h @@ -0,0 +1,274 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROTOCOL_H +#define ICE_PROTOCOL_H + +#include +#include + +namespace IceInternal +{ + +// +// Size of the Ice protocol header +// +// Magic number (4 Bytes) +// Protocol version major (Byte) +// Protocol version minor (Byte) +// Encoding version major (Byte) +// Encoding version minor (Byte) +// Message type (Byte) +// Compression status (Byte) +// Message size (Int) +// +const ::Ice::Int headerSize = 14; + +// +// The magic number at the front of each message +// +extern const ::Ice::Byte magic[4]; + +// +// The current Ice protocol, protocol encoding and encoding version +// +const ::Ice::Byte protocolMajor = 1; +const ::Ice::Byte protocolMinor = 0; +const ::Ice::Byte protocolEncodingMajor = 1; +const ::Ice::Byte protocolEncodingMinor = 0; + +const ::Ice::Byte encodingMajor = 1; +const ::Ice::Byte encodingMinor = 1; + +// +// The Ice protocol message types +// +const ::Ice::Byte requestMsg = 0; +const ::Ice::Byte requestBatchMsg = 1; +const ::Ice::Byte replyMsg = 2; +const ::Ice::Byte validateConnectionMsg = 3; +const ::Ice::Byte closeConnectionMsg = 4; + +// +// The request header, batch request header and reply header. +// +extern const ::Ice::Byte requestHdr[headerSize + sizeof(Ice::Int)]; +extern const ::Ice::Byte requestBatchHdr[headerSize + sizeof(Ice::Int)]; +extern const ::Ice::Byte replyHdr[headerSize]; + +// +// IPv4/IPv6 support enumeration. +// +enum ProtocolSupport +{ + EnableIPv4, + EnableIPv6, + EnableBoth +}; + +ICE_API void stringToMajorMinor(const ::std::string&, Ice::Byte&, Ice::Byte&); + +template std::string +versionToString(const T& v) +{ + std::ostringstream os; + os << v; + return os.str(); +} + +template T +stringToVersion(const ::std::string& str) +{ + T v; + stringToMajorMinor(str, v.major, v.minor); + return v; +} + +template bool +isSupported(const T& version, const T& supported) +{ + return version.major == supported.major && version.minor <= supported.minor; +} + +ICE_API void throwUnsupportedProtocolException(const char*, int, const Ice::ProtocolVersion&, + const Ice::ProtocolVersion&); +ICE_API void throwUnsupportedEncodingException(const char*, int, const Ice::EncodingVersion&, + const Ice::EncodingVersion&); + +const ::Ice::Byte OPTIONAL_END_MARKER = 0xFF; + +const ::Ice::Byte FLAG_HAS_TYPE_ID_STRING = (1<<0); +const ::Ice::Byte FLAG_HAS_TYPE_ID_INDEX = (1<<1); +const ::Ice::Byte FLAG_HAS_TYPE_ID_COMPACT = (1<<0) | (1<<1); +const ::Ice::Byte FLAG_HAS_OPTIONAL_MEMBERS = (1<<2); +const ::Ice::Byte FLAG_HAS_INDIRECTION_TABLE = (1<<3); +const ::Ice::Byte FLAG_HAS_SLICE_SIZE = (1<<4); +const ::Ice::Byte FLAG_IS_LAST_SLICE = (1<<5); + +} + +namespace Ice +{ + +/** Identifies protocol version 1.0. */ +ICE_API extern const ProtocolVersion Protocol_1_0; + +/** Identifies encoding version 1.0. */ +ICE_API extern const EncodingVersion Encoding_1_0; + +/** Identifies encoding version 1.1. */ +ICE_API extern const EncodingVersion Encoding_1_1; + +/** Identifies the latest protocol version. */ +ICE_API extern const ProtocolVersion currentProtocol; + +/** Identifies the latest protocol encoding version. */ +ICE_API extern const EncodingVersion currentProtocolEncoding; + +/** Identifies the latest encoding version. */ +ICE_API extern const EncodingVersion currentEncoding; + +/** + * Converts a protocol version into a string. + * @param v The protocol version. + * @return A string representing the protocol version. + */ +inline ::std::string +protocolVersionToString(const Ice::ProtocolVersion& v) +{ + return IceInternal::versionToString(v); +} + +/** + * Converts a string into a protocol version. + * @param v The string containing a stringified protocol version. + * @return The protocol version. + * @throws VersionParseException If the given string is not in the X.Y format. + */ +inline ::Ice::ProtocolVersion +stringToProtocolVersion(const ::std::string& v) +{ + return IceInternal::stringToVersion(v); +} + +/** + * Converts an encoding version into a string. + * @param v The encoding version. + * @return A string representing the encoding version. + */ +inline ::std::string +encodingVersionToString(const Ice::EncodingVersion& v) +{ + return IceInternal::versionToString(v); +} + +/** + * Converts a string into an encoding version. + * @param v The string containing a stringified encoding version. + * @return The encoding version. + * @throws VersionParseException If the given string is not in the X.Y format. + */ +inline ::Ice::EncodingVersion +stringToEncodingVersion(const ::std::string& v) +{ + return IceInternal::stringToVersion(v); +} + +inline std::ostream& +operator<<(std::ostream& out, const ProtocolVersion& version) +{ + return out << static_cast(version.major) << "." << static_cast(version.minor); +} + +inline std::ostream& +operator<<(std::ostream& out, const EncodingVersion& version) +{ + return out << static_cast(version.major) << "." << static_cast(version.minor); +} + +} + +namespace IceInternal +{ + +inline void +checkSupportedProtocol(const Ice::ProtocolVersion& v) +{ + if(!isSupported(v, Ice::currentProtocol)) + { + throwUnsupportedProtocolException(__FILE__, __LINE__, v, Ice::currentProtocol); + } +} + +inline void +checkSupportedProtocolEncoding(const Ice::EncodingVersion& v) +{ + if(!isSupported(v, Ice::currentProtocolEncoding)) + { + throwUnsupportedEncodingException(__FILE__, __LINE__, v, Ice::currentProtocolEncoding); + } +} + +inline void +checkSupportedEncoding(const Ice::EncodingVersion& v) +{ + if(!isSupported(v, Ice::currentEncoding)) + { + throwUnsupportedEncodingException(__FILE__, __LINE__, v, Ice::currentEncoding); + } +} + +// +// Either return the given protocol if not compatible, or the greatest +// supported protocol otherwise. +// +inline const Ice::ProtocolVersion +getCompatibleProtocol(const Ice::ProtocolVersion& v) +{ + if(v.major != Ice::currentProtocol.major) + { + return v; // Unsupported protocol, return as is. + } + else if(v.minor < Ice::currentProtocol.minor) + { + return v; // Supported protocol. + } + else + { + // + // Unsupported but compatible, use the currently supported + // protocol, that's the best we can do. + // + return Ice::currentProtocol; + } +} + +// +// Either return the given encoding if not compatible, or the greatest +// supported encoding otherwise. +// +inline const Ice::EncodingVersion& +getCompatibleEncoding(const Ice::EncodingVersion& v) +{ + if(v.major != Ice::currentEncoding.major) + { + return v; // Unsupported encoding, return as is. + } + else if(v.minor < Ice::currentEncoding.minor) + { + return v; // Supported encoding. + } + else + { + // + // Unsupported but compatible, use the currently supported + // encoding, that's the best we can do. + // + return Ice::currentEncoding; + } +} + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProtocolInstance.h b/Sources/IceCpp/include/Ice/ProtocolInstance.h new file mode 100644 index 0000000..d180768 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProtocolInstance.h @@ -0,0 +1,93 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROTOCOL_INSTANCE_H +#define ICE_PROTOCOL_INSTANCE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API ProtocolInstance : public IceUtil::Shared +{ +public: + + virtual ~ProtocolInstance(); + + ProtocolInstance(const Ice::CommunicatorPtr&, Ice::Short, const std::string&, bool); + + int traceLevel() const + { + return _traceLevel; + } + + const std::string& traceCategory() const + { + return _traceCategory; + } + + const Ice::LoggerPtr& logger() const; + + const std::string& protocol() const + { + return _protocol; + } + + Ice::Short type() const + { + return _type; + } + + const Ice::PropertiesPtr& properties() const + { + return _properties; + } + + bool secure() const + { + return _secure; + } + + IceInternal::EndpointFactoryPtr getEndpointFactory(Ice::Short) const; + BufSizeWarnInfo getBufSizeWarn(Ice::Short type); + void setSndBufSizeWarn(Ice::Short type, int size); + void setRcvBufSizeWarn(Ice::Short type, int size); + bool preferIPv6() const; + ProtocolSupport protocolSupport() const; + const std::string& defaultHost() const; + const Address& defaultSourceAddress() const; + const Ice::EncodingVersion& defaultEncoding() const; + NetworkProxyPtr networkProxy() const; + size_t messageSizeMax() const; + int defaultTimeout() const; + + void resolve(const std::string&, int, Ice::EndpointSelectionType, const IPEndpointIPtr&, + const EndpointI_connectorsPtr&) const; + +protected: + + ProtocolInstance(const InstancePtr&, Ice::Short, const std::string&, bool); + friend class Instance; + const InstancePtr _instance; + const int _traceLevel; + const std::string _traceCategory; + const Ice::PropertiesPtr _properties; + const std::string _protocol; + const Ice::Short _type; + const bool _secure; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProtocolInstanceF.h b/Sources/IceCpp/include/Ice/ProtocolInstanceF.h new file mode 100644 index 0000000..b63532c --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProtocolInstanceF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROTOCOL_INSTANCE_F_H +#define ICE_PROTOCOL_INSTANCE_F_H + +#include + +#include + +namespace IceInternal +{ + +class ProtocolInstance; +ICE_API IceUtil::Shared* upCast(ProtocolInstance*); +typedef IceInternal::Handle ProtocolInstancePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProtocolPluginFacade.h b/Sources/IceCpp/include/Ice/ProtocolPluginFacade.h new file mode 100644 index 0000000..45fe294 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProtocolPluginFacade.h @@ -0,0 +1,64 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROTOCOL_PLUGIN_FACADE_H +#define ICE_PROTOCOL_PLUGIN_FACADE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +// +// Global function to obtain a ProtocolPluginFacade given a Communicator +// instance. +// +ICE_API ProtocolPluginFacadePtr getProtocolPluginFacade(const Ice::CommunicatorPtr&); + +// +// ProtocolPluginFacade wraps the internal operations that protocol +// plug-ins may need. +// +class ICE_API ProtocolPluginFacade : public ::IceUtil::Shared +{ +public: + + virtual ~ProtocolPluginFacade(); + + // + // Get the Communicator instance with which this facade is + // associated. + // + Ice::CommunicatorPtr getCommunicator() const; + + // + // Register an EndpointFactory. + // + void addEndpointFactory(const EndpointFactoryPtr&) const; + + // + // Get an EndpointFactory. + // + EndpointFactoryPtr getEndpointFactory(Ice::Short) const; + +private: + + ProtocolPluginFacade(const Ice::CommunicatorPtr&); + + friend ICE_API ProtocolPluginFacadePtr getProtocolPluginFacade(const Ice::CommunicatorPtr&); + + InstancePtr _instance; + Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProtocolPluginFacadeF.h b/Sources/IceCpp/include/Ice/ProtocolPluginFacadeF.h new file mode 100644 index 0000000..b050cf5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProtocolPluginFacadeF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROTOCOL_PLUGIN_FACADE_F_H +#define ICE_PROTOCOL_PLUGIN_FACADE_F_H + +#include + +#include + +namespace IceInternal +{ + +class ProtocolPluginFacade; +ICE_API IceUtil::Shared* upCast(ProtocolPluginFacade*); +typedef Handle ProtocolPluginFacadePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Proxy.h b/Sources/IceCpp/include/Ice/Proxy.h new file mode 100644 index 0000000..bc127b0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Proxy.h @@ -0,0 +1,5154 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROXY_H +#define ICE_PROXY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include // Can't include RouterF.h here, otherwise we have cyclic includes +//#include // Can't include LocatorF.h here, otherwise we have cyclic includes +#include +#include +#include +#include +#include + +namespace Ice +{ + +/** Marker value used to indicate that no explicit context was passed to a proxy invocation. */ +ICE_API extern const Context noExplicitContext; + +} + +#if defined(_MSC_VER) && (_MSC_VER <= 1600) +// +// COMPILERFIX v90 and v100 get confused with namespaces and complains that +// ::Ice::noExplicitContext isn't defined in IceProxy namespace. +// +namespace IceProxy +{ + +namespace Ice +{ + +/** Marker value used to indicate that no explicit context was passed to a proxy invocation. */ +ICE_API extern const ::Ice::Context noExplicitContext; + +} + +} +#endif + +namespace IceInternal +{ + +// +// Class for handling the proxy's begin_ice_flushBatchRequest request. +// +class ICE_API ProxyFlushBatchAsync : public ProxyOutgoingAsyncBase +{ +public: + + ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&); + + virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); + virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); + + void invoke(const std::string&); + +private: + + int _batchRequestNum; +}; +typedef IceUtil::Handle ProxyFlushBatchAsyncPtr; + +// +// Class for handling the proxy's begin_ice_getConnection request. +// +class ICE_API ProxyGetConnection : public ProxyOutgoingAsyncBase +{ +public: + + ProxyGetConnection(const Ice::ObjectPrxPtr&); + + virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); + virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); + + virtual Ice::ConnectionPtr getConnection() const; + + void invoke(const std::string&); +}; +typedef IceUtil::Handle ProxyGetConnectionPtr; + +} + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceInternal +{ + +template +::std::shared_ptr

createProxy() +{ + return ::std::shared_ptr

(new P()); +} + +inline ::std::pair +makePair(const Ice::ByteSeq& seq) +{ + if(seq.empty()) + { + return { nullptr, nullptr }; + } + else + { + return { seq.data(), seq.data() + seq.size() }; + } +} + +template +class InvokeOutgoingAsyncT : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + const ::std::pair& inParams, + const Ice::Context& context) + { + _read = [](bool ok, Ice::InputStream* stream) + { + const ::Ice::Byte* encaps; + ::Ice::Int sz; + stream->readEncapsulation(encaps, sz); + return R { ok, { encaps, encaps + sz } }; + }; + + try + { + prepare(operation, mode, context); + if(inParams.first == inParams.second) + { + _os.writeEmptyEncapsulation(_encoding); + } + else + { + _os.writeEncapsulation(inParams.first, static_cast(inParams.second - inParams.first)); + } + OutgoingAsync::invoke(operation); + } + catch(const Ice::Exception& ex) + { + abort(ex); + } + } + +protected: + + std::function _read; +}; + +template +class InvokeLambdaOutgoing : public InvokeOutgoingAsyncT, public LambdaInvoke +{ +public: + + InvokeLambdaOutgoing(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function response, + ::std::function ex, + ::std::function sent) : + InvokeOutgoingAsyncT(proxy, false), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { + if(response) + { +#if ICE_CPLUSPLUS >= 201402L + // Move capture with C++14 + _response = [this, response = std::move(response)](bool ok) +#else + _response = [this, response](bool ok) +#endif + { + if(this->_is.b.empty()) + { + response(R { ok, { 0, 0 }}); + } + else + { + response(this->_read(ok, &this->_is)); + } + }; + } + } +}; + +template +class InvokePromiseOutgoing : public InvokeOutgoingAsyncT, public PromiseInvoke

+{ +public: + + InvokePromiseOutgoing(const std::shared_ptr& proxy, bool synchronous) : + InvokeOutgoingAsyncT(proxy, false) + { + this->_synchronous = synchronous; + this->_response = [this](bool ok) + { + if(this->_is.b.empty()) + { + this->_promise.set_value(R { ok, { 0, 0 }}); + } + else + { + this->_promise.set_value(this->_read(ok, &this->_is)); + } + }; + } + + virtual bool handleSent(bool done, bool) override + { + if(done) + { + this->_promise.set_value(R { true, { 0, 0 }}); + } + return false; + } +}; + +class ProxyGetConnectionLambda : public ProxyGetConnection, public LambdaInvoke +{ +public: + + ProxyGetConnectionLambda(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function)> response, + ::std::function ex, + ::std::function sent) : + ProxyGetConnection(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { +#if ICE_CPLUSPLUS >= 201402L + _response = [&, response = std::move(response)](bool) +#else + _response = [&, response](bool) +#endif + { + response(getConnection()); + }; + } +}; + +template +class ProxyGetConnectionPromise : public ProxyGetConnection, public PromiseInvoke

+{ +public: + + ProxyGetConnectionPromise(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy) : ProxyGetConnection(proxy) + { + this->_response = [&](bool) + { + this->_promise.set_value(getConnection()); + }; + } +}; + +class ProxyFlushBatchLambda : public ProxyFlushBatchAsync, public LambdaInvoke +{ +public: + + ProxyFlushBatchLambda(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function ex, + ::std::function sent) : + ProxyFlushBatchAsync(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { + } +}; + +template +class ProxyFlushBatchPromise : public ProxyFlushBatchAsync, public PromiseInvoke

+{ +public: + + using ProxyFlushBatchAsync::ProxyFlushBatchAsync; + + virtual bool handleSent(bool, bool) override + { + this->_promise.set_value(); + return false; + } +}; + +} + +namespace Ice +{ + +class RouterPrx; +/// \cond INTERNAL +using RouterPrxPtr = ::std::shared_ptr<::Ice::RouterPrx>; +/// \endcond + +class LocatorPrx; +/// \cond INTERNAL +using LocatorPrxPtr = ::std::shared_ptr<::Ice::LocatorPrx>; +/// \endcond + +class LocalException; +class OutputStream; + +/** + * Base class of all object proxies. + * \headerfile Ice/Ice.h + */ +class ICE_API ObjectPrx : public ::std::enable_shared_from_this +{ +public: + + virtual ~ObjectPrx() = default; + + friend ICE_API bool operator<(const ObjectPrx&, const ObjectPrx&); + friend ICE_API bool operator==(const ObjectPrx&, const ObjectPrx&); + + /** + * Obtains the communicator that created this proxy. + * @return The communicator that created this proxy. + */ + ::std::shared_ptr<::Ice::Communicator> ice_getCommunicator() const; + + /** + * Obtains a stringified version of this proxy. + * @return A stringified proxy. + */ + ::std::string ice_toString() const; + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @return true if the target object has the interface + * specified by id or derives from the interface specified by id. + */ + bool + ice_isA(const ::std::string& typeId, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makePromiseOutgoing(true, this, &ObjectPrx::_iceI_isA, typeId, context).get(); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_isAAsync(const ::std::string& typeId, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, + &ObjectPrx::_iceI_isA, typeId, context); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_isAAsync(const ::std::string& typeId, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &ObjectPrx::_iceI_isA, typeId, context); + } + + /// \cond INTERNAL + void + _iceI_isA(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::Ice::Context&); + /// \endcond + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + */ + void + ice_ping(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &ObjectPrx::_iceI_ping, context).get(); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_pingAsync(::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, + &ObjectPrx::_iceI_ping, context); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> + auto ice_pingAsync(const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &ObjectPrx::_iceI_ping, context); + } + + /// \cond INTERNAL + void + _iceI_ping(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::Ice::Context&); + /// \endcond + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The Slice type IDs of the interfaces supported by the target object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + ::std::vector<::std::string> + ice_ids(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makePromiseOutgoing<::std::vector<::std::string>>(true, this, &ObjectPrx::_iceI_ids, context).get(); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_idsAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing<::std::vector<::std::string>>(std::move(response), std::move(ex), std::move(sent), + this, &ObjectPrx::_iceI_ids, context); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_idsAsync(const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::vector<::std::string>, P>(false, this, &ObjectPrx::_iceI_ids, context); + } + + /// \cond INTERNAL + void + _iceI_ids(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::vector<::std::string>>>&, const ::Ice::Context&); + /// \endcond + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + ::std::string + ice_id(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makePromiseOutgoing<::std::string>(true, this, &ObjectPrx::_iceI_id, context).get(); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_idAsync(::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing<::std::string>(std::move(response), std::move(ex), std::move(sent), this, + &ObjectPrx::_iceI_id, context); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> + auto ice_idAsync(const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>().get_future()) + { + return _makePromiseOutgoing<::std::string, P>(false, this, &ObjectPrx::_iceI_id, context); + } + + /// \cond INTERNAL + void + _iceI_id(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::string>>&, const ::Ice::Context&); + /// \endcond + + /** + * Returns the Slice type ID associated with this type. + * @return The Slice type ID. + */ + static const ::std::string& ice_staticId() + { + return ::Ice::Object::ice_staticId(); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param outParams An encapsulation containing the encoded results. + * @param context The context map for the invocation. + * @return True if the operation completed successfully, in which case outParams contains + * the encoded out parameters. False if the operation raised a user exception, in which + * case outParams contains the encoded user exception. If the operation raises a run-time + * exception, it throws it directly. + */ + bool + ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector& inParams, + ::std::vector<::Ice::Byte>& outParams, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return ice_invoke(operation, mode, ::IceInternal::makePair(inParams), outParams, context); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_invokeAsync(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector& inParams, + const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>().get_future()) + { + return ice_invokeAsync

(operation, mode, ::IceInternal::makePair(inParams), context); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_invokeAsync(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector<::Ice::Byte>& inParams, + ::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + using Outgoing = ::IceInternal::InvokeLambdaOutgoing<::Ice::Object::Ice_invokeResult>; + ::std::function r; + if(response) + { +#if ICE_CPLUSPLUS >= 201402L + r = [response = std::move(response)](::Ice::Object::Ice_invokeResult&& result) +#else + r = [response](::Ice::Object::Ice_invokeResult&& result) +#endif + { + response(result.returnValue, std::move(result.outParams)); + }; + } + auto outAsync = ::std::make_shared(shared_from_this(), std::move(r), std::move(ex), std::move(sent)); + outAsync->invoke(operation, mode, ::IceInternal::makePair(inParams), context); + return [outAsync]() { outAsync->cancel(); }; + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param outParams An encapsulation containing the encoded results. + * @param context The context map for the invocation. + * @return True if the operation completed successfully, in which case outParams contains + * the encoded out parameters. False if the operation raised a user exception, in which + * case outParams contains the encoded user exception. If the operation raises a run-time + * exception, it throws it directly. + */ + bool + ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + ::std::vector<::Ice::Byte>& outParams, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + using Outgoing = ::IceInternal::InvokePromiseOutgoing< + ::std::promise<::Ice::Object::Ice_invokeResult>, ::Ice::Object::Ice_invokeResult>; + auto outAsync = ::std::make_shared(shared_from_this(), true); + outAsync->invoke(operation, mode, inParams, context); + auto result = outAsync->getFuture().get(); + outParams.swap(result.outParams); + return result.returnValue; + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_invokeAsync(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(std::declval>().get_future()) + { + using Outgoing = + ::IceInternal::InvokePromiseOutgoing, ::Ice::Object::Ice_invokeResult>; + auto outAsync = ::std::make_shared(shared_from_this(), false); + outAsync->invoke(operation, mode, inParams, context); + return outAsync->getFuture(); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The context map for the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_invokeAsync(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + ::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + using Result = ::std::tuple>; + using Outgoing = ::IceInternal::InvokeLambdaOutgoing; + + ::std::function r; + if(response) + { +#if ICE_CPLUSPLUS >= 201402L + r = [response = std::move(response)](Result&& result) +#else + r = [response](Result&& result) +#endif + { + response(::std::get<0>(result), ::std::move(::std::get<1>(result))); + }; + } + auto outAsync = ::std::make_shared(shared_from_this(), std::move(r), std::move(ex), std::move(sent)); + outAsync->invoke(operation, mode, inParams, context); + return [outAsync]() { outAsync->cancel(); }; + } + + /** + * Obtains the identity embedded in this proxy. + * @return The identity of the target object. + */ + ::Ice::Identity ice_getIdentity() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the identity. + * @param id The identity for the new proxy. + * @return A proxy with the new identity. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_identity(const ::Ice::Identity& id) const; + + /** + * Obtains the per-proxy context for this proxy. + * @return The per-proxy context. + */ + ::Ice::Context ice_getContext() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the per-proxy context. + * @param context The context for the new proxy. + * @return A proxy with the new per-proxy context. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_context(const ::Ice::Context& context) const; + + /** + * Obtains the facet for this proxy. + * @return The facet for this proxy. If the proxy uses the default facet, the return value is the empty string. + */ + const ::std::string& ice_getFacet() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the facet. + * @param facet The facet for the new proxy. + * @return A proxy with the new facet. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_facet(const ::std::string& facet) const; + + /** + * Obtains the adapter ID for this proxy. + * @return The adapter ID. If the proxy does not have an adapter ID, the return value is the empty string. + */ + ::std::string ice_getAdapterId() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the adapter ID. + * @param id The adapter ID for the new proxy. + * @return A proxy with the new adapter ID. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_adapterId(const ::std::string& id) const; + + /** + * Obtains the endpoints used by this proxy. + * @return The endpoints used by this proxy. + */ + ::Ice::EndpointSeq ice_getEndpoints() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoints. + * @param endpoints The endpoints for the new proxy. + * @return A proxy with the new endpoints. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_endpoints(const ::Ice::EndpointSeq& endpoints) const; + + /** + * Obtains the locator cache timeout of this proxy. + * @return The locator cache timeout value (in seconds). + */ + ::Ice::Int ice_getLocatorCacheTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator cache timeout. + * @param timeout The new locator cache timeout (in seconds). + * @return A proxy with the new timeout. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_locatorCacheTimeout(::Ice::Int timeout) const; + + /** + * Determines whether this proxy caches connections. + * @return True if this proxy caches connections, false otherwise. + */ + bool ice_isConnectionCached() const; + + /** + * Obtains a proxy that is identical to this proxy, except for connection caching. + * @param b True if the new proxy should cache connections, false otherwise. + * @return A proxy with the specified caching policy. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_connectionCached(bool b) const; + + /** + * Obtains the endpoint selection policy for this proxy (randomly or ordered). + * @return The endpoint selection policy. + */ + ::Ice::EndpointSelectionType ice_getEndpointSelection() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoint selection policy. + * @param type The new endpoint selection policy. + * @return A proxy with the specified endpoint selection policy. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_endpointSelection(::Ice::EndpointSelectionType type) const; + + /** + * Determines whether this proxy uses only secure endpoints. + * @return True if this proxy communicates only via secure endpoints, false otherwise. + */ + bool ice_isSecure() const; + + /** + * Obtains a proxy that is identical to this proxy, except for how it selects endpoints. + * @param b If true, only endpoints that use a secure transport are used by the new proxy. + * If false, the returned proxy uses both secure and insecure endpoints. + * @return A proxy with the specified security policy. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_secure(bool b) const; + + /** + * Obtains the encoding version used to marshal request parameters. + * @return The encoding version. + */ + ::Ice::EncodingVersion ice_getEncodingVersion() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the encoding used to marshal + * parameters. + * @param version The encoding version to use to marshal request parameters. + * @return A proxy with the specified encoding version. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_encodingVersion(const ::Ice::EncodingVersion& version) const; + + /** + * Determines whether this proxy prefers secure endpoints. + * @return True if the proxy always attempts to invoke via secure endpoints before it + * attempts to use insecure endpoints, false otherwise. + */ + bool ice_isPreferSecure() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its endpoint selection policy. + * @param b If true, the new proxy will use secure endpoints for invocations and only use + * insecure endpoints if an invocation cannot be made via secure endpoints. If false, the + * proxy prefers insecure endpoints to secure ones. + * @return A proxy with the specified selection policy. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_preferSecure(bool b) const; + + /** + * Obtains the router for this proxy. + * @return The router for the proxy. If no router is configured for the proxy, the return value + * is nil. + */ + ::std::shared_ptr<::Ice::RouterPrx> ice_getRouter() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the router. + * @param router The router for the new proxy. + * @return A proxy with the specified router. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_router(const ::std::shared_ptr<::Ice::RouterPrx>& router) const; + + /** + * Obtains the locator for this proxy. + * @return The locator for this proxy. If no locator is configured, the return value is nil. + */ + ::std::shared_ptr<::Ice::LocatorPrx> ice_getLocator() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator. + * @param locator The locator for the new proxy. + * @return A proxy with the specified locator. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_locator(const ::std::shared_ptr<::Ice::LocatorPrx>& locator) const; + + /** + * Determines whether this proxy uses collocation optimization. + * @return True if the proxy uses collocation optimization, false otherwise. + */ + bool ice_isCollocationOptimized() const; + + /** + * Obtains a proxy that is identical to this proxy, except for collocation optimization. + * @param b True if the new proxy enables collocation optimization, false otherwise. + * @return A proxy with the specified collocation optimization. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_collocationOptimized(bool b) const; + + /** + * Obtains the invocation timeout of this proxy. + * @return The invocation timeout value (in milliseconds). + */ + ::Ice::Int ice_getInvocationTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the invocation timeout. + * @param timeout The new invocation timeout (in milliseconds). + * @return A proxy with the new timeout. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_invocationTimeout(::Ice::Int timeout) const; + + /** + * Obtains a proxy that is identical to this proxy, but uses twoway invocations. + * @return A proxy that uses twoway invocations. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_twoway() const; + + /** + * Determines whether this proxy uses twoway invocations. + * @return True if this proxy uses twoway invocations, false otherwise. + */ + bool ice_isTwoway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses oneway invocations. + * @return A proxy that uses oneway invocations. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_oneway() const; + + /** + * Determines whether this proxy uses oneway invocations. + * @return True if this proxy uses oneway invocations, false otherwise. + */ + bool ice_isOneway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch oneway invocations. + * @return A proxy that uses batch oneway invocations. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_batchOneway() const; + + /** + * Determines whether this proxy uses batch oneway invocations. + * @return True if this proxy uses batch oneway invocations, false otherwise. + */ + bool ice_isBatchOneway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses datagram invocations. + * @return A proxy that uses datagram invocations. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_datagram() const; + + /** + * Determines whether this proxy uses datagram invocations. + * @return True if this proxy uses datagram invocations, false otherwise. + */ + bool ice_isDatagram() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch datagram invocations. + * @return A proxy that uses batch datagram invocations. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_batchDatagram() const; + + /** + * Determines whether this proxy uses batch datagram invocations. + * @return True if this proxy uses batch datagram invocations, false otherwise. + */ + bool ice_isBatchDatagram() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its compression setting which + * overrides the compression setting from the proxy endpoints. + * @param b True enables compression for the new proxy, false disables compression. + * @return A proxy with the specified compression override setting. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_compress(bool b) const; + + /** + * Obtains the compression override setting of this proxy. + * @return The compression override setting. If nullopt is returned, no override is set. Otherwise, true + * if compression is enabled, false otherwise. + */ + ::Ice::optional ice_getCompress() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection timeout setting + * which overrides the timeot setting from the proxy endpoints. + * @param timeout The connection timeout override for the proxy (in milliseconds). + * @return A proxy with the specified timeout override. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_timeout(int timeout) const; + + /** + * Obtains the timeout override of this proxy. + * @return The timeout override. If nullopt is returned, no override is set. Otherwise, returns + * the timeout override value. + */ + ::Ice::optional ice_getTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection ID. + * @param id The connection ID for the new proxy. An empty string removes the + * connection ID. + * @return A proxy with the specified connection ID. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_connectionId(const ::std::string& id) const; + + /** + * Obtains the connection ID of this proxy. + * @return The connection ID. + */ + ::std::string ice_getConnectionId() const; + + /** + * Obtains a proxy that is identical to this proxy, except it's a fixed proxy bound + * the given connection. + * @param connection The fixed proxy connection. + * @return A fixed proxy bound to the given connection. + */ + ::std::shared_ptr<::Ice::ObjectPrx> ice_fixed(const ::std::shared_ptr<::Ice::Connection>& connection) const; + + /** + * Determines whether this proxy is a fixed proxy. + * @return True if this proxy is a fixed proxy, false otherwise. + */ + bool ice_isFixed() const; + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @return The connection for this proxy. + */ + ::std::shared_ptr<::Ice::Connection> + ice_getConnection() + { + return ice_getConnectionAsync().get(); + } + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + ice_getConnectionAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr) + { + using LambdaOutgoing = ::IceInternal::ProxyGetConnectionLambda; + auto outAsync = ::std::make_shared(shared_from_this(), std::move(response), std::move(ex), std::move(sent)); + _iceI_getConnection(outAsync); + return [outAsync]() { outAsync->cancel(); }; + } + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_getConnectionAsync() -> decltype(std::declval>>().get_future()) + { + using PromiseOutgoing = ::IceInternal::ProxyGetConnectionPromise>>; + auto outAsync = ::std::make_shared(shared_from_this()); + _iceI_getConnection(outAsync); + return outAsync->getFuture(); + } + + /// \cond INTERNAL + void _iceI_getConnection(const ::std::shared_ptr<::IceInternal::ProxyGetConnection>&); + /// \endcond + + /** + * Obtains the cached Connection for this proxy. If the proxy does not yet have an established + * connection, it does not attempt to create a connection. + * @return The cached connection for this proxy, or nil if the proxy does not have + * an established connection. + */ + ::std::shared_ptr<::Ice::Connection> ice_getCachedConnection() const; + + /** + * Flushes any pending batched requests for this communicator. The call blocks until the flush is complete. + */ + void ice_flushBatchRequests() + { + return ice_flushBatchRequestsAsync().get(); + } + + /** + * Flushes asynchronously any pending batched requests for this communicator. + * @param ex The exception callback. + * @param sent The sent callback. + * @return A function that can be called to cancel the invocation locally. + */ + std::function + ice_flushBatchRequestsAsync(::std::function ex, + ::std::function sent = nullptr) + { + using LambdaOutgoing = ::IceInternal::ProxyFlushBatchLambda; + auto outAsync = ::std::make_shared(shared_from_this(), std::move(ex), std::move(sent)); + _iceI_flushBatchRequests(outAsync); + return [outAsync]() { outAsync->cancel(); }; + } + + /** + * Flushes asynchronously any pending batched requests for this communicator. + * @return The future object for the invocation. + */ + template class P = std::promise> auto + ice_flushBatchRequestsAsync() -> decltype(std::declval>().get_future()) + { + using PromiseOutgoing = ::IceInternal::ProxyFlushBatchPromise>; + auto outAsync = ::std::make_shared(shared_from_this()); + _iceI_flushBatchRequests(outAsync); + return outAsync->getFuture(); + } + + /// \cond INTERNAL + void _iceI_flushBatchRequests(const ::std::shared_ptr<::IceInternal::ProxyFlushBatchAsync>&); + + const ::IceInternal::ReferencePtr& _getReference() const { return _reference; } + + void _copyFrom(const std::shared_ptr<::Ice::ObjectPrx>&); + + int _handleException(const ::Ice::Exception&, const ::IceInternal::RequestHandlerPtr&, ::Ice::OperationMode, + bool, int&); + + void _checkTwowayOnly(const ::std::string&) const; + + ::IceInternal::RequestHandlerPtr _getRequestHandler(); + ::IceInternal::BatchRequestQueuePtr _getBatchRequestQueue(); + ::IceInternal::RequestHandlerPtr _setRequestHandler(const ::IceInternal::RequestHandlerPtr&); + void _updateRequestHandler(const ::IceInternal::RequestHandlerPtr&, const ::IceInternal::RequestHandlerPtr&); + + int _hash() const; + + void _write(OutputStream&) const; + /// \endcond + +protected: + + /// \cond INTERNAL + template class P = ::std::promise, typename Obj, typename Fn, typename... Args> + auto _makePromiseOutgoing(bool sync, Obj obj, Fn fn, Args&&... args) + -> decltype(std::declval>().get_future()) + { + auto outAsync = ::std::make_shared<::IceInternal::PromiseOutgoing, R>>(shared_from_this(), sync); + (obj->*fn)(outAsync, std::forward(args)...); + return outAsync->getFuture(); + } + + template + ::std::function _makeLamdaOutgoing(Re r, E e, S s, Obj obj, Fn fn, Args&&... args) + { + auto outAsync = ::std::make_shared<::IceInternal::LambdaOutgoing>(shared_from_this(), + std::move(r), std::move(e), std::move(s)); + (obj->*fn)(outAsync, std::forward(args)...); + return [outAsync]() { outAsync->cancel(); }; + } + + virtual ::std::shared_ptr _newInstance() const; + ObjectPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + /// \endcond + +private: + + void setup(const ::IceInternal::ReferencePtr&); + friend class ::IceInternal::ProxyFactory; + + ::IceInternal::ReferencePtr _reference; + ::IceInternal::RequestHandlerPtr _requestHandler; + ::IceInternal::BatchRequestQueuePtr _batchRequestQueue; + IceUtil::Mutex _mutex; +}; + +inline bool +operator>(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return rhs < lhs; +} + +inline bool +operator<=(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return !(lhs > rhs); +} + +inline bool +operator>=(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return !(lhs < rhs); +} + +inline bool +operator!=(const ObjectPrx& lhs, const ObjectPrx& rhs) +{ + return !(lhs == rhs); +} + +/** + * Helper template that supplies proxy factory functions. + * \headerfile Ice/Ice.h + */ +template +class Proxy : public virtual Bases... +{ +public: + + /** + * Obtains a proxy that is identical to this proxy, except for the per-proxy context. + * @param context The context for the new proxy. + * @return A proxy with the new per-proxy context. + */ + ::std::shared_ptr ice_context(const ::Ice::Context& context) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_context(context)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the adapter ID. + * @param id The adapter ID for the new proxy. + * @return A proxy with the new adapter ID. + */ + ::std::shared_ptr ice_adapterId(const ::std::string& id) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_adapterId(id)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoints. + * @param endpoints The endpoints for the new proxy. + * @return A proxy with the new endpoints. + */ + ::std::shared_ptr ice_endpoints(const ::Ice::EndpointSeq& endpoints) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_endpoints(endpoints)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the locator cache timeout. + * @param timeout The new locator cache timeout (in seconds). + * @return A proxy with the new timeout. + */ + ::std::shared_ptr ice_locatorCacheTimeout(int timeout) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_locatorCacheTimeout(timeout)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for connection caching. + * @param b True if the new proxy should cache connections, false otherwise. + * @return A proxy with the specified caching policy. + */ + ::std::shared_ptr ice_connectionCached(bool b) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_connectionCached(b)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoint selection policy. + * @param type The new endpoint selection policy. + * @return A proxy with the specified endpoint selection policy. + */ + ::std::shared_ptr ice_endpointSelection(::Ice::EndpointSelectionType type) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_endpointSelection(type)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for how it selects endpoints. + * @param b If true, only endpoints that use a secure transport are used by the new proxy. + * If false, the returned proxy uses both secure and insecure endpoints. + * @return A proxy with the specified security policy. + */ + ::std::shared_ptr ice_secure(bool b) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_secure(b)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its endpoint selection policy. + * @param b If true, the new proxy will use secure endpoints for invocations and only use + * insecure endpoints if an invocation cannot be made via secure endpoints. If false, the + * proxy prefers insecure endpoints to secure ones. + * @return A proxy with the specified selection policy. + */ + ::std::shared_ptr ice_preferSecure(bool b) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_preferSecure(b)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the router. + * @param router The router for the new proxy. + * @return A proxy with the specified router. + */ + ::std::shared_ptr ice_router(const ::std::shared_ptr<::Ice::RouterPrx>& router) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_router(router)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the locator. + * @param locator The locator for the new proxy. + * @return A proxy with the specified locator. + */ + ::std::shared_ptr ice_locator(const ::std::shared_ptr<::Ice::LocatorPrx>& locator) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_locator(locator)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for collocation optimization. + * @param b True if the new proxy enables collocation optimization, false otherwise. + * @return A proxy with the specified collocation optimization. + */ + ::std::shared_ptr ice_collocationOptimized(bool b) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_collocationOptimized(b)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the invocation timeout. + * @param timeout The new invocation timeout (in milliseconds). + * @return A proxy with the new timeout. + */ + ::std::shared_ptr ice_invocationTimeout(int timeout) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_invocationTimeout(timeout)); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses twoway invocations. + * @return A proxy that uses twoway invocations. + */ + ::std::shared_ptr ice_twoway() const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_twoway()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses oneway invocations. + * @return A proxy that uses oneway invocations. + */ + ::std::shared_ptr ice_oneway() const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_oneway()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses batch oneway invocations. + * @return A proxy that uses batch oneway invocations. + */ + ::std::shared_ptr ice_batchOneway() const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_batchOneway()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses datagram invocations. + * @return A proxy that uses datagram invocations. + */ + ::std::shared_ptr ice_datagram() const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_datagram()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses batch datagram invocations. + * @return A proxy that uses batch datagram invocations. + */ + ::std::shared_ptr ice_batchDatagram() const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_batchDatagram()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its compression setting which + * overrides the compression setting from the proxy endpoints. + * @param b True enables compression for the new proxy, false disables compression. + * @return A proxy with the specified compression override setting. + */ + ::std::shared_ptr ice_compress(bool b) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_compress(b)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its connection timeout setting + * which overrides the timeot setting from the proxy endpoints. + * @param timeout The connection timeout override for the proxy (in milliseconds). + * @return A proxy with the specified timeout override. + */ + ::std::shared_ptr ice_timeout(int timeout) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_timeout(timeout)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its connection ID. + * @param id The connection ID for the new proxy. An empty string removes the + * connection ID. + * @return A proxy with the specified connection ID. + */ + ::std::shared_ptr ice_connectionId(const ::std::string& id) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_connectionId(id)); + } + + /** + * Obtains a proxy that is identical to this proxy, except it's a fixed proxy bound + * the given connection. + * @param connection The fixed proxy connection. + * @return A fixed proxy bound to the given connection. + */ + ::std::shared_ptr ice_fixed(const ::std::shared_ptr<::Ice::Connection>& connection) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_fixed(connection)); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the encoding used to marshal + * parameters. + * @param version The encoding version to use to marshal request parameters. + * @return A proxy with the specified encoding version. + */ + ::std::shared_ptr ice_encodingVersion(const ::Ice::EncodingVersion& version) const + { + return ::std::dynamic_pointer_cast(ObjectPrx::ice_encodingVersion(version)); + } + +protected: + + /// \cond INTERNAL + virtual ::std::shared_ptr _newInstance() const = 0; + /// \endcond +}; + +ICE_API ::std::ostream& operator<<(::std::ostream&, const ::Ice::ObjectPrx&); + +/** + * Compares the object identities of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity in lhs compares less than the identity in rhs, false otherwise. + */ +ICE_API bool proxyIdentityLess(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs); + +/** + * Compares the object identities of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity in lhs compares equal to the identity in rhs, false otherwise. + */ +ICE_API bool proxyIdentityEqual(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs); + +/** + * Compares the object identities and facets of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity and facet in lhs compare less than the identity and facet + * in rhs, false otherwise. + */ +ICE_API bool proxyIdentityAndFacetLess(const ::std::shared_ptr& lhs, + const ::std::shared_ptr& rhs); + +/** + * Compares the object identities and facets of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity and facet in lhs compare equal to the identity and facet + * in rhs, false otherwise. + */ +ICE_API bool proxyIdentityAndFacetEqual(const ::std::shared_ptr& lhs, + const ::std::shared_ptr& rhs); + +/** + * A functor that compares the object identities of two proxies. Evaluates true if the identity in lhs + * compares less than the identity in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ + +struct ProxyIdentityLess +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function&, ::std::shared_ptr&> +#endif +{ + bool operator()(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs) const + { + return proxyIdentityLess(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities of two proxies. Evaluates true if the identity in lhs + * compares equal to the identity in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityEqual +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function&, ::std::shared_ptr&> +#endif +{ + bool operator()(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs) const + { + return proxyIdentityEqual(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities and facets of two proxies. Evaluates true if the identity + * and facet in lhs compare less than the identity and facet in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityAndFacetLess +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function&, ::std::shared_ptr&> +#endif +{ + bool operator()(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs) const + { + return proxyIdentityAndFacetLess(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities and facets of two proxies. Evaluates true if the identity + * and facet in lhs compare equal to the identity and facet in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityAndFacetEqual +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function&, ::std::shared_ptr&> +#endif +{ + bool operator()(const ::std::shared_ptr& lhs, const ::std::shared_ptr& rhs) const + { + return proxyIdentityAndFacetEqual(lhs, rhs); + } +}; + +/** + * Downcasts a proxy without confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @return A proxy with the requested type. + */ +template::value>::type* = nullptr, + typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> ::std::shared_ptr

+uncheckedCast(const ::std::shared_ptr& b) +{ + ::std::shared_ptr

r; + if(b) + { + r = ::std::dynamic_pointer_cast

(b); + if(!r) + { + r = IceInternal::createProxy

(); + r->_copyFrom(b); + } + } + return r; +} + +/** + * Downcasts a proxy without confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param f A facet name. + * @return A proxy with the requested type and facet. + */ +template::value>::type* = nullptr, + typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> ::std::shared_ptr

+uncheckedCast(const ::std::shared_ptr& b, const std::string& f) +{ + ::std::shared_ptr

r; + if(b) + { + r = IceInternal::createProxy

(); + r->_copyFrom(b->ice_facet(f)); + } + return r; +} + +/** + * Downcasts a proxy after confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param context The context map for the invocation. + * @return A proxy with the requested type, or nil if the target proxy is nil or the target + * object does not support the requested type. + */ +template::value>::type* = nullptr, + typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> ::std::shared_ptr

+checkedCast(const ::std::shared_ptr& b, const ::Ice::Context& context = Ice::noExplicitContext) +{ + ::std::shared_ptr

r; + if(b) + { + if(b->ice_isA(P::ice_staticId(), context)) + { + r = IceInternal::createProxy

(); + r->_copyFrom(b); + } + } + return r; +} + +/** + * Downcasts a proxy after confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param f A facet name. + * @param context The context map for the invocation. + * @return A proxy with the requested type and facet, or nil if the target proxy is nil or the target + * object does not support the requested type. + */ +template::value>::type* = nullptr, + typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> ::std::shared_ptr

+checkedCast(const ::std::shared_ptr& b, const std::string& f, const ::Ice::Context& context = Ice::noExplicitContext) +{ + ::std::shared_ptr

r; + if(b) + { + try + { + ::std::shared_ptr<::Ice::ObjectPrx> bb = b->ice_facet(f); + if(bb->ice_isA(P::ice_staticId(), context)) + { + r = IceInternal::createProxy

(); + r->_copyFrom(bb); + } + } + catch(const Ice::FacetNotExistException&) + { + } + } + return r; +} + +} + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +/// \cond INTERNAL +class Locator; +ICE_API ::IceProxy::Ice::Object* upCast(::IceProxy::Ice::Locator*); + +class Router; +ICE_API ::IceProxy::Ice::Object* upCast(::IceProxy::Ice::Router*); +/// \endcond + +} + +} + +namespace Ice +{ + +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Router> RouterPrx; +typedef RouterPrx RouterPrxPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Locator> LocatorPrx; +typedef LocatorPrx LocatorPrxPtr; + +class LocalException; +class OutputStream; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_isA. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_isA. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_isA_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_isA_Base> Callback_Object_ice_isAPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_ping. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ping. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_ping_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_ping_Base> Callback_Object_ice_pingPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_ids. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ids. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_ids_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_ids_Base> Callback_Object_ice_idsPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_id. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_id. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_id_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_id_Base> Callback_Object_ice_idPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_invoke. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_invoke. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_invoke_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_invoke_Base> Callback_Object_ice_invokePtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_flushBatchRequests_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_flushBatchRequests_Base> Callback_Object_ice_flushBatchRequestsPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Object::begin_ice_getConnection. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_getConnection. + * \headerfile Ice/Ice.h + */ +class Callback_Object_ice_getConnection_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Object_ice_getConnection_Base> Callback_Object_ice_getConnectionPtr; + +} + +namespace IceProxy { namespace Ice +{ + +/** + * Base class of all object proxies. + * \headerfile Ice/Ice.h + */ +class ICE_API Object : public ::IceUtil::Shared +{ +public: + + bool operator==(const Object&) const; + bool operator<(const Object&) const; + + /** + * Obtains the communicator that created this proxy. + * @return The communicator that created this proxy. + */ + ::Ice::CommunicatorPtr ice_getCommunicator() const; + + /** + * Obtains a stringified version of this proxy. + * @return A stringified proxy. + */ + ::std::string ice_toString() const; + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @return True if the target object has the interface + * specified by id or derives from the interface specified by id. + */ + bool ice_isA(const ::std::string& typeId, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_ice_isA(_iceI_begin_ice_isA(typeId, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_isA(const ::std::string& typeId, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_ice_isA(typeId, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_isA(const ::std::string& typeId, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_isA(typeId, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_isA(const ::std::string& typeId, + const ::Ice::Context& context, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_isA(typeId, context, cb, cookie); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_isA(const ::std::string& typeId, + const ::Ice::Callback_Object_ice_isAPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_isA(typeId, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Tests whether this object supports a specific Slice interface. + * @param typeId The type ID of the Slice interface to test against. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_isA(const ::std::string& typeId, + const ::Ice::Context& context, + const ::Ice::Callback_Object_ice_isAPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_isA(typeId, context, cb, cookie); + } + + /** + * Completes an invocation of begin_ice_isA. + * @param result The asynchronous result object for the invocation. + * @return True if the target object has the interface + * specified by id or derives from the interface specified by id. + */ + bool end_ice_isA(const ::Ice::AsyncResultPtr& result); + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + */ + void ice_ping(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_ice_ping(_iceI_begin_ice_ping(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ping(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_ice_ping(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ping(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ping(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ping(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ping(context, cb, cookie); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ping(const ::Ice::Callback_Object_ice_pingPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ping(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Tests whether the target object of this proxy can be reached. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ping(const ::Ice::Context& context, const ::Ice::Callback_Object_ice_pingPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ping(context, cb, cookie); + } + + /** + * Completes an invocation of begin_ice_ping. + * @param result The asynchronous result object for the invocation. + */ + void end_ice_ping(const ::Ice::AsyncResultPtr& result); + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The Slice type IDs of the interfaces supported by the target object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + ::std::vector< ::std::string> ice_ids(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_ice_ids(_iceI_begin_ice_ids(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ids(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_ice_ids(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ids(const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ids(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ids(const ::Ice::Context& context, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ids(context, cb, cookie); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ids(const ::Ice::Callback_Object_ice_idsPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ids(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Returns the Slice type IDs of the interfaces supported by the target object of this proxy. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_ids(const ::Ice::Context& context, + const ::Ice::Callback_Object_ice_idsPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_ids(context, cb, cookie); + } + + /** + * Completes an invocation of begin_ice_ids. + * @param result The asynchronous result object for the invocation. + * @return The Slice type IDs of the interfaces supported by the target object, in base-to-derived + * order. The first element of the returned array is always "::Ice::Object". + */ + ::std::vector< ::std::string> end_ice_ids(const ::Ice::AsyncResultPtr& result); + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + ::std::string ice_id(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_ice_id(_iceI_begin_ice_id(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_id(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_ice_id(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_id(const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_id(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_id(const ::Ice::Context& context, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_id(context, cb, cookie); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_id(const ::Ice::Callback_Object_ice_idPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_id(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Returns the Slice type ID of the most-derived interface supported by the target object of this proxy. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_id(const ::Ice::Context& context, + const ::Ice::Callback_Object_ice_idPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_id(context, cb, cookie); + } + + /** + * Completes an invocation of begin_ice_id. + * @param result The asynchronous result object for the invocation. + * @return The Slice type ID of the most-derived interface. + */ + ::std::string end_ice_id(const ::Ice::AsyncResultPtr& result); + + /** + * Returns the Slice type ID associated with this type. + * @return The Slice type ID. + */ + static const ::std::string& ice_staticId() + { + return ::Ice::Object::ice_staticId(); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param outParams An encapsulation containing the encoded results. + * @param context The context map for the invocation. + * @return True if the operation completed successfully, in which case outParams contains + * the encoded out parameters. False if the operation raised a user exception, in which + * case outParams contains the encoded user exception. If the operation raises a run-time + * exception, it throws it directly. + */ + bool ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + ::std::vector< ::Ice::Byte>& outParams, + const ::Ice::Context& context = ::Ice::noExplicitContext); + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, + ::IceInternal::dummyCallback, 0); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + const ::Ice::Context& context) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + const ::Ice::Context& context, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + const ::Ice::Callback_Object_ice_invokePtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector< ::Ice::Byte>& inParams, + const ::Ice::Context& context, + const ::Ice::Callback_Object_ice_invokePtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param outParams An encapsulation containing the encoded results. + * @param result The asynchronous result object for the invocation. + * @return True if the operation completed successfully, in which case outParams contains + * the encoded out parameters. False if the operation raised a user exception, in which + * case outParams contains the encoded user exception. If the operation raises a run-time + * exception, it throws it directly. + */ + bool end_ice_invoke(::std::vector< ::Ice::Byte>& outParams, const ::Ice::AsyncResultPtr& result); + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param outParams An encapsulation containing the encoded results. + * @param context The context map for the invocation. + * @return True if the operation completed successfully, in which case outParams contains + * the encoded out parameters. False if the operation raised a user exception, in which + * case outParams contains the encoded user exception. If the operation raises a run-time + * exception, it throws it directly. + */ + bool ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + ::std::vector< ::Ice::Byte>& outParams, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_ice_invoke(outParams, _iceI_begin_ice_invoke(operation, mode, inParams, context, + ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, + ::IceInternal::dummyCallback, 0); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::Context& context, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, ::IceInternal::dummyCallback, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::Context& context, + const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::Callback_Object_ice_invokePtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Invokes an operation dynamically. + * @param operation The name of the operation to invoke. + * @param mode The operation mode (normal or idempotent). + * @param inParams An encapsulation containing the encoded in-parameters for the operation. + * @param context The context map for the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_invoke(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair& inParams, + const ::Ice::Context& context, + const ::Ice::Callback_Object_ice_invokePtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_invoke(operation, mode, inParams, context, cb, cookie); + } + + /// \cond INTERNAL + bool _iceI_end_ice_invoke(::std::pair&, const ::Ice::AsyncResultPtr&); + /// \endcond + + /** + * Obtains the identity embedded in this proxy. + * @return The identity of the target object. + */ + ::Ice::Identity ice_getIdentity() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the identity. + * @param id The identity for the new proxy. + * @return A proxy with the new identity. + */ + ::Ice::ObjectPrx ice_identity(const ::Ice::Identity& id) const; + + /** + * Obtains the per-proxy context for this proxy. + * @return The per-proxy context. + */ + ::Ice::Context ice_getContext() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the per-proxy context. + * @param context The context for the new proxy. + * @return A proxy with the new per-proxy context. + */ + ::Ice::ObjectPrx ice_context(const ::Ice::Context& context) const; + + /** + * Obtains the facet for this proxy. + * @return The facet for this proxy. If the proxy uses the default facet, the return value is the empty string. + */ + const ::std::string& ice_getFacet() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the facet. + * @param facet The facet for the new proxy. + * @return A proxy with the new facet. + */ + ::Ice::ObjectPrx ice_facet(const ::std::string& facet) const; + + /** + * Obtains the adapter ID for this proxy. + * @return The adapter ID. If the proxy does not have an adapter ID, the return value is the empty string. + */ + ::std::string ice_getAdapterId() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the adapter ID. + * @param id The adapter ID for the new proxy. + * @return A proxy with the new adapter ID. + */ + ::Ice::ObjectPrx ice_adapterId(const ::std::string& id) const; + + /** + * Obtains the endpoints used by this proxy. + * @return The endpoints used by this proxy. + */ + ::Ice::EndpointSeq ice_getEndpoints() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoints. + * @param endpoints The endpoints for the new proxy. + * @return A proxy with the new endpoints. + */ + ::Ice::ObjectPrx ice_endpoints(const ::Ice::EndpointSeq& endpoints) const; + + /** + * Obtains the locator cache timeout of this proxy. + * @return The locator cache timeout value (in seconds). + */ + ::Ice::Int ice_getLocatorCacheTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator cache timeout. + * @param timeout The new locator cache timeout (in seconds). + * @return A proxy with the new timeout. + */ + ::Ice::ObjectPrx ice_locatorCacheTimeout(::Ice::Int timeout) const; + + /** + * Determines whether this proxy caches connections. + * @return True if this proxy caches connections, false otherwise. + */ + bool ice_isConnectionCached() const; + + /** + * Obtains a proxy that is identical to this proxy, except for connection caching. + * @param b True if the new proxy should cache connections, false otherwise. + * @return A proxy with the specified caching policy. + */ + ::Ice::ObjectPrx ice_connectionCached(bool b) const; + + /** + * Obtains the endpoint selection policy for this proxy (randomly or ordered). + * @return The endpoint selection policy. + */ + ::Ice::EndpointSelectionType ice_getEndpointSelection() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoint selection policy. + * @param type The new endpoint selection policy. + * @return A proxy with the specified endpoint selection policy. + */ + ::Ice::ObjectPrx ice_endpointSelection(::Ice::EndpointSelectionType type) const; + + /** + * Determines whether this proxy uses only secure endpoints. + * @return True if this proxy communicates only via secure endpoints, false otherwise. + */ + bool ice_isSecure() const; + + /** + * Obtains a proxy that is identical to this proxy, except for how it selects endpoints. + * @param b If true, only endpoints that use a secure transport are used by the new proxy. + * If false, the returned proxy uses both secure and insecure endpoints. + * @return A proxy with the specified security policy. + */ + ::Ice::ObjectPrx ice_secure(bool b) const; + + /** + * Obtains the encoding version used to marshal request parameters. + * @return The encoding version. + */ + ::Ice::EncodingVersion ice_getEncodingVersion() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the encoding used to marshal + * parameters. + * @param version The encoding version to use to marshal request parameters. + * @return A proxy with the specified encoding version. + */ + ::Ice::ObjectPrx ice_encodingVersion(const ::Ice::EncodingVersion& version) const; + + /** + * Determines whether this proxy prefers secure endpoints. + * @return True if the proxy always attempts to invoke via secure endpoints before it + * attempts to use insecure endpoints, false otherwise. + */ + bool ice_isPreferSecure() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its endpoint selection policy. + * @param b If true, the new proxy will use secure endpoints for invocations and only use + * insecure endpoints if an invocation cannot be made via secure endpoints. If false, the + * proxy prefers insecure endpoints to secure ones. + * @return A proxy with the specified selection policy. + */ + ::Ice::ObjectPrx ice_preferSecure(bool b) const; + + /** + * Obtains the router for this proxy. + * @return The router for the proxy. If no router is configured for the proxy, the return value + * is nil. + */ + ::Ice::RouterPrx ice_getRouter() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the router. + * @param router The router for the new proxy. + * @return A proxy with the specified router. + */ + ::Ice::ObjectPrx ice_router(const ::Ice::RouterPrx& router) const; + + /** + * Obtains the locator for this proxy. + * @return The locator for this proxy. If no locator is configured, the return value is nil. + */ + ::Ice::LocatorPrx ice_getLocator() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the locator. + * @param locator The locator for the new proxy. + * @return A proxy with the specified locator. + */ + ::Ice::ObjectPrx ice_locator(const ::Ice::LocatorPrx& locator) const; + + /** + * Determines whether this proxy uses collocation optimization. + * @return True if the proxy uses collocation optimization, false otherwise. + */ + bool ice_isCollocationOptimized() const; + + /** + * Obtains a proxy that is identical to this proxy, except for collocation optimization. + * @param b True if the new proxy enables collocation optimization, false otherwise. + * @return A proxy with the specified collocation optimization. + */ + ::Ice::ObjectPrx ice_collocationOptimized(bool b) const; + + /** + * Obtains the invocation timeout of this proxy. + * @return The invocation timeout value (in milliseconds). + */ + ::Ice::Int ice_getInvocationTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for the invocation timeout. + * @param timeout The new invocation timeout (in milliseconds). + * @return A proxy with the new timeout. + */ + ::Ice::ObjectPrx ice_invocationTimeout(::Ice::Int timeout) const; + + /** + * Obtains a proxy that is identical to this proxy, but uses twoway invocations. + * @return A proxy that uses twoway invocations. + */ + ::Ice::ObjectPrx ice_twoway() const; + + /** + * Determines whether this proxy uses twoway invocations. + * @return True if this proxy uses twoway invocations, false otherwise. + */ + bool ice_isTwoway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses oneway invocations. + * @return A proxy that uses oneway invocations. + */ + ::Ice::ObjectPrx ice_oneway() const; + + /** + * Determines whether this proxy uses oneway invocations. + * @return True if this proxy uses oneway invocations, false otherwise. + */ + bool ice_isOneway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch oneway invocations. + * @return A proxy that uses batch oneway invocations. + */ + ::Ice::ObjectPrx ice_batchOneway() const; + + /** + * Determines whether this proxy uses batch oneway invocations. + * @return True if this proxy uses batch oneway invocations, false otherwise. + */ + bool ice_isBatchOneway() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses datagram invocations. + * @return A proxy that uses datagram invocations. + */ + ::Ice::ObjectPrx ice_datagram() const; + + /** + * Determines whether this proxy uses datagram invocations. + * @return True if this proxy uses datagram invocations, false otherwise. + */ + bool ice_isDatagram() const; + + /** + * Obtains a proxy that is identical to this proxy, but uses batch datagram invocations. + * @return A proxy that uses batch datagram invocations. + */ + ::Ice::ObjectPrx ice_batchDatagram() const; + + /** + * Determines whether this proxy uses batch datagram invocations. + * @return True if this proxy uses batch datagram invocations, false otherwise. + */ + bool ice_isBatchDatagram() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its compression setting which + * overrides the compression setting from the proxy endpoints. + * @param b True enables compression for the new proxy, false disables compression. + * @return A proxy with the specified compression override setting. + */ + ::Ice::ObjectPrx ice_compress(bool b) const; + + /** + * Obtains the compression override setting of this proxy. + * @return The compression override setting. If nullopt is returned, no override is set. Otherwise, true + * if compression is enabled, false otherwise. + */ + ::IceUtil::Optional ice_getCompress() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection timeout setting + * which overrides the timeot setting from the proxy endpoints. + * @param timeout The connection timeout override for the proxy (in milliseconds). + * @return A proxy with the specified timeout override. + */ + ::Ice::ObjectPrx ice_timeout(int timeout) const; + + /** + * Obtains the timeout override of this proxy. + * @return The timeout override. If nullopt is returned, no override is set. Otherwise, returns + * the timeout override value. + */ + ::IceUtil::Optional ice_getTimeout() const; + + /** + * Obtains a proxy that is identical to this proxy, except for its connection ID. + * @param id The connection ID for the new proxy. An empty string removes the + * connection ID. + * @return A proxy with the specified connection ID. + */ + ::Ice::ObjectPrx ice_connectionId(const ::std::string& id) const; + + /** + * Obtains the connection ID of this proxy. + * @return The connection ID. + */ + ::std::string ice_getConnectionId() const; + + /** + * Obtains a proxy that is identical to this proxy, except it's a fixed proxy bound + * the given connection. + * @param connection The fixed proxy connection. + * @return A fixed proxy bound to the given connection. + */ + ::Ice::ObjectPrx ice_fixed(const ::Ice::ConnectionPtr& connection) const; + + /** + * Determines whether this proxy is a fixed proxy. + * @return True if this proxy is a fixed proxy, false otherwise. + */ + bool ice_isFixed() const; + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @return The connection for this proxy. + */ + ::Ice::ConnectionPtr ice_getConnection() + { + return end_ice_getConnection(begin_ice_getConnection()); + } + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_getConnection() + { + return _iceI_begin_ice_getConnection(::IceInternal::dummyCallback, 0); + } + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_getConnection(const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_getConnection(cb, cookie); + } + + /** + * Obtains the Connection for this proxy. If the proxy does not yet have an established connection, + * it first attempts to create a connection. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_getConnection(const ::Ice::Callback_Object_ice_getConnectionPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_getConnection(cb, cookie); + } + + /** + * Completes an invocation of begin_ice_getConnection. + * @param result The asynchronous result object for the invocation. + * @return The connection for this proxy. + */ + ::Ice::ConnectionPtr end_ice_getConnection(const ::Ice::AsyncResultPtr& result); + + /** + * Returns the cached connection for this proxy. If the proxy does not yet have an established + * connection, it does not attempt to create a connection. + * + * @return The cached connection for this proxy, or nil if the proxy does not have + * an established connection. + */ + ::Ice::ConnectionPtr ice_getCachedConnection() const; + + /** + * Flushes any pending batched requests for this proxy. The call blocks until the flush is complete. + */ + void ice_flushBatchRequests() + { + return end_ice_flushBatchRequests(begin_ice_flushBatchRequests()); + } + + /** + * Flushes asynchronously any pending batched requests for this proxy. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_flushBatchRequests() + { + return _iceI_begin_ice_flushBatchRequests(::IceInternal::dummyCallback, 0); + } + + /** + * Flushes asynchronously any pending batched requests for this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_flushBatchRequests(const ::Ice::CallbackPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_flushBatchRequests(cb, cookie); + } + + /** + * Flushes asynchronously any pending batched requests for this proxy. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_ice_flushBatchRequests(const ::Ice::Callback_Object_ice_flushBatchRequestsPtr& cb, + const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_ice_flushBatchRequests(cb, cookie); + } + + /** + * Completes an invocation of begin_ice_flushBatchRequests. + * @param result The asynchronous result object for the invocation. + */ + void end_ice_flushBatchRequests(const ::Ice::AsyncResultPtr& result); + + /// \cond INTERNAL + const ::IceInternal::ReferencePtr& _getReference() const { return _reference; } + + ::Ice::Int _hash() const; + + void _copyFrom(const ::Ice::ObjectPrx&); + + int _handleException(const ::Ice::Exception&, const ::IceInternal::RequestHandlerPtr&, ::Ice::OperationMode, + bool, int&); + + void _checkTwowayOnly(const ::std::string&, bool) const; + + void _end(const ::Ice::AsyncResultPtr&, const std::string&) const; + + ::IceInternal::RequestHandlerPtr _getRequestHandler(); + ::IceInternal::BatchRequestQueuePtr _getBatchRequestQueue(); + ::IceInternal::RequestHandlerPtr _setRequestHandler(const ::IceInternal::RequestHandlerPtr&); + void _updateRequestHandler(const ::IceInternal::RequestHandlerPtr&, const ::IceInternal::RequestHandlerPtr&); + + void _write(::Ice::OutputStream&) const; + /// \endcond + +protected: + + /// \cond INTERNAL + virtual Object* _newInstance() const; + /// \endcond + +private: + + ::Ice::AsyncResultPtr _iceI_begin_ice_isA(const ::std::string&, + const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_ping(const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_ids(const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_id(const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_invoke(const ::std::string&, + ::Ice::OperationMode, + const ::std::vector< ::Ice::Byte>&, + const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_invoke(const ::std::string&, + ::Ice::OperationMode, + const ::std::pair&, + const ::Ice::Context&, + const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&, + bool = false); + + ::Ice::AsyncResultPtr _iceI_begin_ice_getConnection(const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&); + + ::Ice::AsyncResultPtr _iceI_begin_ice_flushBatchRequests(const ::IceInternal::CallbackBasePtr&, + const ::Ice::LocalObjectPtr&); + + void setup(const ::IceInternal::ReferencePtr&); + friend class ::IceInternal::ProxyFactory; + + ::IceInternal::ReferencePtr _reference; + ::IceInternal::RequestHandlerPtr _requestHandler; + ::IceInternal::BatchRequestQueuePtr _batchRequestQueue; + IceUtil::Mutex _mutex; +}; + +} } + +ICE_API ::std::ostream& operator<<(::std::ostream&, const ::IceProxy::Ice::Object&); + +namespace Ice +{ + +/** + * Helper template that supplies proxy factory functions. + * \headerfile Ice/Ice.h + */ +template +class Proxy : public virtual Base +{ +public: + + /** + * Obtains a proxy that is identical to this proxy, except for the per-proxy context. + * @param context The context for the new proxy. + * @return A proxy with the new per-proxy context. + */ + IceInternal::ProxyHandle ice_context(const ::Ice::Context& context) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_context(context).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the adapter ID. + * @param id The adapter ID for the new proxy. + * @return A proxy with the new adapter ID. + */ + IceInternal::ProxyHandle ice_adapterId(const ::std::string& id) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_adapterId(id).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoints. + * @param endpoints The endpoints for the new proxy. + * @return A proxy with the new endpoints. + */ + IceInternal::ProxyHandle ice_endpoints(const ::Ice::EndpointSeq& endpoints) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_endpoints(endpoints).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the locator cache timeout. + * @param timeout The new locator cache timeout (in seconds). + * @return A proxy with the new timeout. + */ + IceInternal::ProxyHandle ice_locatorCacheTimeout(int timeout) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_locatorCacheTimeout(timeout).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for connection caching. + * @param b True if the new proxy should cache connections, false otherwise. + * @return A proxy with the specified caching policy. + */ + IceInternal::ProxyHandle ice_connectionCached(bool b) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_connectionCached(b).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the endpoint selection policy. + * @param type The new endpoint selection policy. + * @return A proxy with the specified endpoint selection policy. + */ + IceInternal::ProxyHandle ice_endpointSelection(::Ice::EndpointSelectionType type) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_endpointSelection(type).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for how it selects endpoints. + * @param b If true, only endpoints that use a secure transport are used by the new proxy. + * If false, the returned proxy uses both secure and insecure endpoints. + * @return A proxy with the specified security policy. + */ + IceInternal::ProxyHandle ice_secure(bool b) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_secure(b).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its endpoint selection policy. + * @param b If true, the new proxy will use secure endpoints for invocations and only use + * insecure endpoints if an invocation cannot be made via secure endpoints. If false, the + * proxy prefers insecure endpoints to secure ones. + * @return A proxy with the specified selection policy. + */ + IceInternal::ProxyHandle ice_preferSecure(bool b) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_preferSecure(b).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the router. + * @param router The router for the new proxy. + * @return A proxy with the specified router. + */ + IceInternal::ProxyHandle ice_router(const ::Ice::RouterPrx& router) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_router(router).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the locator. + * @param locator The locator for the new proxy. + * @return A proxy with the specified locator. + */ + IceInternal::ProxyHandle ice_locator(const ::Ice::LocatorPrx& locator) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_locator(locator).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for collocation optimization. + * @param b True if the new proxy enables collocation optimization, false otherwise. + * @return A proxy with the specified collocation optimization. + */ + IceInternal::ProxyHandle ice_collocationOptimized(bool b) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_collocationOptimized(b).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the invocation timeout. + * @param timeout The new invocation timeout (in milliseconds). + * @return A proxy with the new timeout. + */ + IceInternal::ProxyHandle ice_invocationTimeout(int timeout) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_invocationTimeout(timeout).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses twoway invocations. + * @return A proxy that uses twoway invocations. + */ + IceInternal::ProxyHandle ice_twoway() const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_twoway().get()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses oneway invocations. + * @return A proxy that uses oneway invocations. + */ + IceInternal::ProxyHandle ice_oneway() const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_oneway().get()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses batch oneway invocations. + * @return A proxy that uses batch oneway invocations. + */ + IceInternal::ProxyHandle ice_batchOneway() const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_batchOneway().get()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses datagram invocations. + * @return A proxy that uses datagram invocations. + */ + IceInternal::ProxyHandle ice_datagram() const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_datagram().get()); + } + + /** + * Obtains a proxy that is identical to this proxy, but uses batch datagram invocations. + * @return A proxy that uses batch datagram invocations. + */ + IceInternal::ProxyHandle ice_batchDatagram() const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_batchDatagram().get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its compression setting which + * overrides the compression setting from the proxy endpoints. + * @param b True enables compression for the new proxy, false disables compression. + * @return A proxy with the specified compression override setting. + */ + IceInternal::ProxyHandle ice_compress(bool b) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_compress(b).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its connection timeout setting + * which overrides the timeot setting from the proxy endpoints. + * @param timeout The connection timeout override for the proxy (in milliseconds). + * @return A proxy with the specified timeout override. + */ + IceInternal::ProxyHandle ice_timeout(int timeout) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_timeout(timeout).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for its connection ID. + * @param id The connection ID for the new proxy. An empty string removes the + * connection ID. + * @return A proxy with the specified connection ID. + */ + IceInternal::ProxyHandle ice_connectionId(const ::std::string& id) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_connectionId(id).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except it's a fixed proxy bound + * the given connection. + * @param connection The fixed proxy connection. + * @return A fixed proxy bound to the given connection. + */ + IceInternal::ProxyHandle ice_fixed(const ::Ice::ConnectionPtr& connection) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_fixed(connection).get()); + } + + /** + * Obtains a proxy that is identical to this proxy, except for the encoding used to marshal + * parameters. + * @param version The encoding version to use to marshal request parameters. + * @return A proxy with the specified encoding version. + */ + IceInternal::ProxyHandle ice_encodingVersion(const ::Ice::EncodingVersion& version) const + { + return dynamic_cast(::IceProxy::Ice::Object::ice_encodingVersion(version).get()); + } + +protected: + + /// \cond INTERNAL + virtual ::IceProxy::Ice::Object* _newInstance() const = 0; + /// \endcond +}; + +/** + * Compares the object identities of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity in lhs compares less than the identity in rhs, false otherwise. + */ +ICE_API bool proxyIdentityLess(const ObjectPrx& lhs, const ObjectPrx& rhs); + +/** + * Compares the object identities of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity in lhs compares equal to the identity in rhs, false otherwise. + */ +ICE_API bool proxyIdentityEqual(const ObjectPrx& lhs, const ObjectPrx& rhs); + +/** + * Compares the object identities and facets of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity and facet in lhs compare less than the identity and facet + * in rhs, false otherwise. + */ +ICE_API bool proxyIdentityAndFacetLess(const ObjectPrx& lhs, const ObjectPrx& rhs); + +/** + * Compares the object identities and facets of two proxies. + * @param lhs A proxy. + * @param rhs A proxy. + * @return True if the identity and facet in lhs compare equal to the identity and facet + * in rhs, false otherwise. + */ +ICE_API bool proxyIdentityAndFacetEqual(const ObjectPrx& lhs, const ObjectPrx& rhs); + +/** + * A functor that compares the object identities of two proxies. Evaluates true if the identity in lhs + * compares less than the identity in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityLess +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function +#endif +{ + bool operator()(const ObjectPrx& lhs, const ObjectPrx& rhs) const + { + return proxyIdentityLess(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities of two proxies. Evaluates true if the identity in lhs + * compares equal to the identity in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityEqual +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function +#endif +{ + bool operator()(const ObjectPrx& lhs, const ObjectPrx& rhs) const + { + return proxyIdentityEqual(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities and facets of two proxies. Evaluates true if the identity + * and facet in lhs compare less than the identity and facet in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityAndFacetLess +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function +#endif +{ + bool operator()(const ObjectPrx& lhs, const ObjectPrx& rhs) const + { + return proxyIdentityAndFacetLess(lhs, rhs); + } +}; + +/** + * A functor that compares the object identities and facets of two proxies. Evaluates true if the identity + * and facet in lhs compare equal to the identity and facet in rhs, false otherwise. + * \headerfile Ice/Ice.h + */ +struct ProxyIdentityAndFacetEqual +#if (ICE_CPLUSPLUS < 201703L) + : std::binary_function +#endif +{ + bool operator()(const ObjectPrx& lhs, const ObjectPrx& rhs) const + { + return proxyIdentityAndFacetEqual(lhs, rhs); + } +}; + +} + +namespace IceInternal +{ + +// +// Inline comparison functions for proxies +// +template +inline bool operator==(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + ::IceProxy::Ice::Object* l = lhs._upCast(); + ::IceProxy::Ice::Object* r = rhs._upCast(); + if(l && r) + { + return *l == *r; + } + else + { + return !l && !r; + } +} + +template +inline bool operator!=(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + return !operator==(lhs, rhs); +} + +template +inline bool operator<(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + ::IceProxy::Ice::Object* l = lhs._upCast(); + ::IceProxy::Ice::Object* r = rhs._upCast(); + if(l && r) + { + return *l < *r; + } + else + { + return !l && r; + } +} + +template +inline bool operator<=(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + return lhs < rhs || lhs == rhs; +} + +template +inline bool operator>(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + return !(lhs < rhs || lhs == rhs); +} + +template +inline bool operator>=(const ProxyHandle& lhs, const ProxyHandle& rhs) +{ + return !(lhs < rhs); +} + +// +// checkedCast and uncheckedCast functions without facet: +// +template P +checkedCastImpl(const ::Ice::ObjectPrx& b, const ::Ice::Context& context) +{ + P d = 0; + if(b.get()) + { + typedef typename P::element_type T; + + if(b->ice_isA(T::ice_staticId(), context)) + { + d = new T; + d->_copyFrom(b); + } + } + return d; +} + +template P +uncheckedCastImpl(const ::Ice::ObjectPrx& b) +{ + P d = 0; + if(b) + { + typedef typename P::element_type T; + + d = dynamic_cast(b.get()); + if(!d) + { + d = new T; + d->_copyFrom(b); + } + } + return d; +} + +// +// checkedCast and uncheckedCast with facet: +// + +// +// Helper with type ID. +// +ICE_API ::Ice::ObjectPrx checkedCastImpl(const ::Ice::ObjectPrx&, const std::string&, const std::string&, + const ::Ice::Context&); + +// +// Specializations for P = ::Ice::ObjectPrx +// We have to use inline functions for broken compilers such as VC7. +// + +template<> inline ::Ice::ObjectPrx +checkedCastImpl< ::Ice::ObjectPrx>(const ::Ice::ObjectPrx& b, const std::string& f, const ::Ice::Context& context) +{ + return checkedCastImpl(b, f, "::Ice::Object", context); +} + +template<> inline ::Ice::ObjectPrx +uncheckedCastImpl< ::Ice::ObjectPrx>(const ::Ice::ObjectPrx& b, const std::string& f) +{ + ::Ice::ObjectPrx d = 0; + if(b) + { + d = b->ice_facet(f); + } + return d; +} + +template P +checkedCastImpl(const ::Ice::ObjectPrx& b, const std::string& f, const ::Ice::Context& context) +{ + P d = 0; + + typedef typename P::element_type T; + ::Ice::ObjectPrx bb = checkedCastImpl(b, f, T::ice_staticId(), context); + + if(bb) + { + d = new T; + d->_copyFrom(bb); + } + return d; +} + +template P +uncheckedCastImpl(const ::Ice::ObjectPrx& b, const std::string& f) +{ + P d = 0; + if(b) + { + typedef typename P::element_type T; + + ::Ice::ObjectPrx bb = b->ice_facet(f); + d = new T; + d->_copyFrom(bb); + } + return d; +} +} + +// +// checkedCast and uncheckedCast functions provided in the Ice namespace +// +namespace Ice +{ + +/** + * Downcasts a proxy after confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param context The context map for the invocation. + * @return A proxy with the requested type, or nil if the target proxy is nil or the target + * object does not support the requested type. + */ +template inline P +checkedCast(const ::IceInternal::ProxyHandle& b, const ::Ice::Context& context = ::Ice::noExplicitContext) +{ + Y* tag = 0; + return ::IceInternal::checkedCastHelper(b, tag, context); +} + +/** + * Downcasts a proxy without confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @return A proxy with the requested type. + */ +template inline P +uncheckedCast(const ::IceInternal::ProxyHandle& b) +{ + Y* tag = 0; + return ::IceInternal::uncheckedCastHelper(b, tag); +} + +/** + * Downcasts a proxy after confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param f A facet name. + * @param context The context map for the invocation. + * @return A proxy with the requested type and facet, or nil if the target proxy is nil or the target + * object does not support the requested type. + */ +template inline P +checkedCast(const ::Ice::ObjectPrx& b, const std::string& f, const ::Ice::Context& context = ::Ice::noExplicitContext) +{ + return ::IceInternal::checkedCastImpl

(b, f, context); +} + +/** + * Downcasts a proxy without confirming the target object's type via a remote invocation. + * @param b The target proxy. + * @param f A facet name. + * @return A proxy with the requested type and facet. + */ +template inline P +uncheckedCast(const ::Ice::ObjectPrx& b, const std::string& f) +{ + return ::IceInternal::uncheckedCastImpl

(b, f); +} + +} + +namespace IceInternal +{ + +// +// Base template for operation callbacks. +// +template +class CallbackNC : public virtual CallbackBase +{ +public: + + typedef T callback_type; + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC(const TPtr& instance, Exception excb, Sent sentcb) : _callback(instance), _exception(excb), _sent(sentcb) + { + } + + virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr& cookie) + { + if(cookie != 0) // Makes sure begin_ was called without a cookie + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "cookie specified for callback without cookie"); + } + return this; + } + + virtual void sent(const ::Ice::AsyncResultPtr& result) const + { + if(_sent) + { + (_callback.get()->*_sent)(result->sentSynchronously()); + } + } + + virtual bool hasSentCallback() const + { + return _sent != 0; + } + +protected: + + void exception(const ::Ice::AsyncResultPtr&, const ::Ice::Exception& ex) const + { + if(_exception) + { + (_callback.get()->*_exception)(ex); + } + } + + TPtr _callback; + +private: + + Exception _exception; + Sent _sent; +}; + +template +class Callback : public virtual CallbackBase +{ +public: + + typedef T callback_type; + typedef CT cookie_type; + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + + Callback(const TPtr& instance, Exception excb, Sent sentcb) : _callback(instance), _exception(excb), _sent(sentcb) + { + } + + virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr& cookie) + { + if(cookie && !CT::dynamicCast(cookie)) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "unexpected cookie type"); + } + return this; + } + + virtual void sent(const ::Ice::AsyncResultPtr& result) const + { + if(_sent) + { + (_callback.get()->*_sent)(result->sentSynchronously(), CT::dynamicCast(result->getCookie())); + } + } + + virtual bool hasSentCallback() const + { + return _sent != 0; + } + +protected: + + void exception(const ::Ice::AsyncResultPtr& result, const ::Ice::Exception& ex) const + { + if(_exception) + { + (_callback.get()->*_exception)(ex, CT::dynamicCast(result->getCookie())); + } + } + + TPtr _callback; + +private: + + Exception _exception; + Sent _sent; +}; + +// +// Base class for twoway operation callbacks. +// +template +class TwowayCallbackNC : public CallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + TwowayCallbackNC(const TPtr& instance, bool cb, Exception excb, Sent sentcb) : CallbackNC(instance, excb, sentcb) + { + CallbackBase::checkCallback(instance, cb || excb != 0); + } +}; + +template +class TwowayCallback : public Callback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + + TwowayCallback(const TPtr& instance, bool cb, Exception excb, Sent sentcb) : Callback(instance, excb, sentcb) + { + CallbackBase::checkCallback(instance, cb || excb != 0); + } +}; + +// +// Base template class for oneway operations callbacks. +// +template +class OnewayCallbackNC : public CallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + OnewayCallbackNC(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + CallbackNC(instance, excb, sentcb), _response(cb) + { + CallbackBase::checkCallback(instance, cb != 0 || excb != 0); + } + + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + try + { + result->getProxy()->_end(result, result->getOperation()); + } + catch(const ::Ice::Exception& ex) + { + CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (CallbackNC::_callback.get()->*_response)(); + } + } + +private: + + Response _response; +}; + +template +class OnewayCallback : public Callback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(const CT&); + + OnewayCallback(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + Callback(instance, excb, sentcb), _response(cb) + { + CallbackBase::checkCallback(instance, cb != 0 || excb != 0); + } + + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + try + { + result->getProxy()->_end(result, result->getOperation()); + } + catch(const ::Ice::Exception& ex) + { + Callback::exception(result, ex); + return; + } + if(_response) + { + (Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + +private: + + Response _response; +}; + +} + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_isA. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_isA. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_isA : public Callback_Object_ice_isA_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(bool); + + CallbackNC_Object_ice_isA(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallbackNC(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + bool ret; + try + { + ret = result->getProxy()->end_ice_isA(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_isA. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_isA. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_isA : public Callback_Object_ice_isA_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(bool, const CT&); + + Callback_Object_ice_isA(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallback(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + bool ret; + try + { + ret = result->getProxy()->end_ice_isA(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, + CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_ping. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ping. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_ping : public Callback_Object_ice_ping_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Object_ice_ping(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::OnewayCallbackNC(instance, cb, excb, sentcb) + { + } +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_ping. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ping. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_ping : public Callback_Object_ice_ping_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Object_ice_ping(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::OnewayCallback(instance, cb, excb, sentcb) + { + } +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_ids. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ids. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_ids : public Callback_Object_ice_ids_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ::std::vector< ::std::string>&); + + CallbackNC_Object_ice_ids(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallbackNC(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::std::vector< ::std::string> ret; + try + { + ret = result->getProxy()->end_ice_ids(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_ids. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_ids. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_ids : public Callback_Object_ice_ids_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(const ::std::vector< ::std::string>&, const CT&); + + Callback_Object_ice_ids(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallback(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::std::vector< ::std::string> ret; + try + { + ret = result->getProxy()->end_ice_ids(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, + CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_id. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_id. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_id : public Callback_Object_ice_id_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ::std::string&); + + CallbackNC_Object_ice_id(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallbackNC(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::std::string ret; + try + { + ret = result->getProxy()->end_ice_id(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_id. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_id. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_id : public Callback_Object_ice_id_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(const ::std::string&, const CT&); + + Callback_Object_ice_id(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallback(instance, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::std::string ret; + try + { + ret = result->getProxy()->end_ice_id(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, + CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_invoke. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_invoke. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_invoke : public Callback_Object_ice_invoke_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(bool, const std::vector< ::Ice::Byte>&); + typedef void (T::*ResponseArray)(bool, const std::pair&); + + CallbackNC_Object_ice_invoke(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallbackNC(instance, cb != 0, excb, sentcb), _response(cb), _responseArray(0) + { + } + + CallbackNC_Object_ice_invoke(const TPtr& instance, ResponseArray cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallbackNC(instance, cb != 0, excb, sentcb), _response(0), _responseArray(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + if(_response) + { + bool ok; + std::vector< ::Ice::Byte> outParams; + try + { + ok = result->getProxy()->end_ice_invoke(outParams, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + (::IceInternal::CallbackNC::_callback.get()->*_response)(ok, outParams); + } + else + { + bool ok; + std::pair outParams; + try + { + ok = result->getProxy()->_iceI_end_ice_invoke(outParams, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_responseArray) + { + (::IceInternal::CallbackNC::_callback.get()->*_responseArray)(ok, outParams); + } + } + } + /// \endcond + +private: + + Response _response; + ResponseArray _responseArray; +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_invoke. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_invoke. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_invoke : public Callback_Object_ice_invoke_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + typedef void (T::*Response)(bool, const std::vector< ::Ice::Byte>&, const CT&); + typedef void (T::*ResponseArray)(bool, const std::pair&, const CT&); + + Callback_Object_ice_invoke(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallback(instance, cb != 0, excb, sentcb), _response(cb), _responseArray(0) + { + } + + Callback_Object_ice_invoke(const TPtr& instance, ResponseArray cb, Exception excb, Sent sentcb) : + ::IceInternal::TwowayCallback(instance, cb != 0, excb, sentcb), _response(0), _responseArray(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + if(_response) + { + bool ok; + std::vector< ::Ice::Byte> outParams; + try + { + ok = result->getProxy()->end_ice_invoke(outParams, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + (::IceInternal::Callback::_callback.get()->*_response)(ok, + outParams, + CT::dynamicCast(result->getCookie())); + } + else + { + bool ok; + std::pair outParams; + try + { + ok = result->getProxy()->_iceI_end_ice_invoke(outParams, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_responseArray) + { + (::IceInternal::Callback::_callback.get()->*_responseArray)(ok, + outParams, + CT::dynamicCast( + result->getCookie())); + } + } + } + /// \endcond + +private: + + Response _response; + ResponseArray _responseArray; +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_getConnection. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_getConnection. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_getConnection : public Callback_Object_ice_getConnection_Base, + public ::IceInternal::CallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Response)(const ::Ice::ConnectionPtr&); + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC_Object_ice_getConnection(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::CallbackNC(instance, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::ConnectionPtr ret; + try + { + ret = result->getProxy()->end_ice_getConnection(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_getConnection. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_getConnection. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_getConnection : public Callback_Object_ice_getConnection_Base, + public ::IceInternal::Callback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Response)(const ::Ice::ConnectionPtr&, const CT&); + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + + Callback_Object_ice_getConnection(const TPtr& instance, Response cb, Exception excb, Sent sentcb) : + ::IceInternal::Callback(instance, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + ::Ice::ConnectionPtr ret; + try + { + ret = result->getProxy()->end_ice_getConnection(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, + CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class CallbackNC_Object_ice_flushBatchRequests : public Callback_Object_ice_flushBatchRequests_Base, + public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + + CallbackNC_Object_ice_flushBatchRequests(const TPtr& instance, Exception excb, Sent sentcb) : + ::IceInternal::OnewayCallbackNC(instance, 0, excb, sentcb) + { + } +}; + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + * Create a wrapper instance by calling ::Ice::newCallback_Object_ice_flushBatchRequests. + * \headerfile Ice/Ice.h + */ +template +class Callback_Object_ice_flushBatchRequests : public Callback_Object_ice_flushBatchRequests_Base, + public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&, const CT&); + typedef void (T::*Sent)(bool, const CT&); + + Callback_Object_ice_flushBatchRequests(const TPtr& instance, Exception excb, Sent sentcb) : + ::IceInternal::OnewayCallback(instance, 0, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(const IceUtil::Handle& instance, + void (T::*cb)(bool), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_isA(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(const IceUtil::Handle& instance, + void (T::*cb)(bool, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_isA(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_isA(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_isA(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(T* instance, + void (T::*cb)(bool), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_isA(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(T* instance, + void (T::*cb)(bool, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_isA(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_isA(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_isA. + */ +template Callback_Object_ice_isAPtr +newCallback_Object_ice_isA(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_isA(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(const IceUtil::Handle& instance, + void (T::*cb)(), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ping(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(const IceUtil::Handle& instance, + void (T::*cb)(const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ping(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ping(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ping(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(T* instance, + void (T::*cb)(), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ping(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(T* instance, + void (T::*cb)(const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ping(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ping(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ping. + */ +template Callback_Object_ice_pingPtr +newCallback_Object_ice_ping(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ping(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(const IceUtil::Handle& instance, + void (T::*cb)(const ::std::vector< ::std::string>&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ids(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(const IceUtil::Handle& instance, + void (T::*cb)(const ::std::vector< ::std::string>&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ids(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ids(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ids(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(T* instance, + void (T::*cb)(const ::std::vector< ::std::string>&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ids(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(T* instance, + void (T::*cb)(const ::std::vector< ::std::string>&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ids(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_ids(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_ids. + */ +template Callback_Object_ice_idsPtr +newCallback_Object_ice_ids(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_ids(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(const IceUtil::Handle& instance, + void (T::*cb)(const ::std::string&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_id(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(const IceUtil::Handle& instance, + void (T::*cb)(const ::std::string&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_id(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_id(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_id(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(T* instance, + void (T::*cb)(const ::std::string&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_id(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(T* instance, + void (T::*cb)(const ::std::string&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_id(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_id(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_id. + */ +template Callback_Object_ice_idPtr +newCallback_Object_ice_id(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_id(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*cb)(bool, const std::vector&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*cb)(bool, const std::pair&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*cb)(bool, const std::vector&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*cb)(bool, const std::pair&, + const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*cb)(bool, const std::vector&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*cb)(bool, const std::pair&), + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*cb)(bool, const std::vector&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*cb)(bool, const std::pair&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_invoke( + instance, static_cast&)>(0), excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_invoke. + */ +template Callback_Object_ice_invokePtr +newCallback_Object_ice_invoke(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_invoke( + instance, static_cast&, const CT&)>(0), excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_getConnection. + */ +template Callback_Object_ice_getConnectionPtr +newCallback_Object_ice_getConnection(const IceUtil::Handle& instance, + void (T::*cb)(const ::Ice::ConnectionPtr&), + void (T::*excb)(const ::Ice::Exception&)) +{ + return new CallbackNC_Object_ice_getConnection(instance, cb, excb, 0); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_getConnection. + */ +template Callback_Object_ice_getConnectionPtr +newCallback_Object_ice_getConnection(const IceUtil::Handle& instance, + void (T::*cb)(const ::Ice::ConnectionPtr&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&)) +{ + return new Callback_Object_ice_getConnection(instance, cb, excb, 0); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_getConnection. + */ +template Callback_Object_ice_getConnectionPtr +newCallback_Object_ice_getConnection(T* instance, + void (T::*cb)(const ::Ice::ConnectionPtr&), + void (T::*excb)(const ::Ice::Exception&)) +{ + return new CallbackNC_Object_ice_getConnection(instance, cb, excb, 0); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Object::begin_ice_getConnection. + */ +template Callback_Object_ice_getConnectionPtr +newCallback_Object_ice_getConnection(T* instance, + void (T::*cb)(const ::Ice::ConnectionPtr&, const CT&), + void (T::*excb)(const ::Ice::Exception&, const CT&)) +{ + return new Callback_Object_ice_getConnection(instance, cb, excb, 0); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + */ +template Callback_Object_ice_flushBatchRequestsPtr +newCallback_Object_ice_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + */ +template Callback_Object_ice_flushBatchRequestsPtr +newCallback_Object_ice_flushBatchRequests(const IceUtil::Handle& instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + */ +template Callback_Object_ice_flushBatchRequestsPtr +newCallback_Object_ice_flushBatchRequests(T* instance, + void (T::*excb)(const ::Ice::Exception&), + void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Object_ice_flushBatchRequests(instance, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of + * IceProxy::Ice::Object::begin_ice_flushBatchRequests. + */ +template Callback_Object_ice_flushBatchRequestsPtr +newCallback_Object_ice_flushBatchRequests(T* instance, + void (T::*excb)(const ::Ice::Exception&, const CT&), + void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Object_ice_flushBatchRequests(instance, excb, sentcb); +} + +} +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/ProxyF.h b/Sources/IceCpp/include/Ice/ProxyF.h new file mode 100644 index 0000000..63bcebb --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProxyF.h @@ -0,0 +1,53 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROXY_F_H +#define ICE_PROXY_F_H + +#include +#include + +#ifdef ICE_CPP11_MAPPING +namespace Ice +{ + +class ObjectPrx; +/// \cond INTERNAL +using ObjectPrxPtr = ::std::shared_ptr; +/// \endcond + +} + +namespace IceInternal +{ + +template +::std::shared_ptr

createProxy(); + +} + +#else // C++98 mapping +namespace IceProxy +{ + +namespace Ice +{ + +class Object; +inline Object* upCast(Object* o) { return o; } + +} + +} + +namespace Ice +{ + +typedef IceInternal::ProxyHandle< ::IceProxy::Ice::Object> ObjectPrx; +typedef ObjectPrx ObjectPrxPtr; + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/ProxyFactory.h b/Sources/IceCpp/include/Ice/ProxyFactory.h new file mode 100644 index 0000000..96b0c30 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProxyFactory.h @@ -0,0 +1,57 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROXY_FACTORY_H +#define ICE_PROXY_FACTORY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +} + +namespace IceInternal +{ + +class ProxyFactory : public IceUtil::Shared +{ +public: + + Ice::ObjectPrxPtr stringToProxy(const std::string&) const; + std::string proxyToString(const Ice::ObjectPrxPtr&) const; + + Ice::ObjectPrxPtr propertyToProxy(const std::string&) const; + Ice::PropertyDict proxyToProperty(const Ice::ObjectPrxPtr&, const std::string&) const; + + Ice::ObjectPrxPtr streamToProxy(Ice::InputStream*) const; + + Ice::ObjectPrxPtr referenceToProxy(const ReferencePtr&) const; + + int checkRetryAfterException(const Ice::LocalException&, const ReferencePtr&, int&) const; + +private: + + ProxyFactory(const InstancePtr&); + virtual ~ProxyFactory(); + friend class Instance; + + InstancePtr _instance; + std::vector _retryIntervals; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProxyFactoryF.h b/Sources/IceCpp/include/Ice/ProxyFactoryF.h new file mode 100644 index 0000000..7e62e6b --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProxyFactoryF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROXY_FACTORY_F_H +#define ICE_PROXY_FACTORY_F_H + +#include + +#include + +namespace IceInternal +{ + +class ProxyFactory; +IceUtil::Shared* upCast(ProxyFactory*); +typedef IceInternal::Handle ProxyFactoryPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ProxyHandle.h b/Sources/IceCpp/include/Ice/ProxyHandle.h new file mode 100644 index 0000000..21eb55e --- /dev/null +++ b/Sources/IceCpp/include/Ice/ProxyHandle.h @@ -0,0 +1,318 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_PROXY_HANDLE_H +#define ICE_PROXY_HANDLE_H + +#ifndef ICE_CPP11_MAPPING // C++98 mapping + +#include +#include + +#include + +namespace IceInternal +{ + +template class ProxyHandle; +template class Handle; + +} + +namespace IceProxy +{ +namespace Ice +{ + +class Object; + +} +} + +namespace Ice +{ + +/** Smart pointer for an object proxy. */ +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Object> ObjectPrx; + +class ObjectAdapter; +typedef ::IceInternal::Handle< ::Ice::ObjectAdapter> ObjectAdapterPtr; + +/** + * A request context. Context is used to transmit metadata about a + * request from the server to the client, such as Quality-of-Service + * (QoS) parameters. Each remote operation on a proxy optionally + * accepts a Context parameter. + **/ +typedef ::std::map< ::std::string, ::std::string> Context; + +/** Sentinel value indicating that no explicit context argument was passed to a remote invocation. */ +ICE_API extern const Context noExplicitContext; + +} + +namespace IceInternal +{ + +template P +checkedCastImpl(const ::Ice::ObjectPrx&, const ::Ice::Context&); + +template P +checkedCastImpl(const ::Ice::ObjectPrx&, const std::string&, const ::Ice::Context&); + +template P +uncheckedCastImpl(const ::Ice::ObjectPrx&); + +template P +uncheckedCastImpl(const ::Ice::ObjectPrx&, const std::string&); + +// +// Upcast +// +template inline ProxyHandle +checkedCastHelper(const ::IceInternal::ProxyHandle& b, T*, const ::Ice::Context&) +{ + return b; +} + +template inline ProxyHandle +uncheckedCastHelper(const ::IceInternal::ProxyHandle& b, T*) +{ + return b; +} + +// +// Downcast +// +template inline ProxyHandle +checkedCastHelper(const ::IceInternal::ProxyHandle& b, void*, const ::Ice::Context& ctx) +{ +#ifdef __SUNPRO_CC + // + // Sun CC bug introduced in version 5.10 + // + const ::Ice::ObjectPrx& o = b; + return checkedCastImpl >(o, ctx); +#else + return checkedCastImpl >(b, ctx); +#endif +} + +template inline ProxyHandle +uncheckedCastHelper(const ::IceInternal::ProxyHandle& b, void*) +{ +#ifdef __SUNPRO_CC + // + // Sun CC bug introduced in version 5.10 + // + const ::Ice::ObjectPrx& o = b; + return uncheckedCastImpl >(o); +#else + return uncheckedCastImpl >(b); +#endif +} + +// +// Like IceInternal::Handle, but specifically for proxies, with +// support for checkedCast() and uncheckedCast() instead of +// dynamicCast(). +// +template +class ProxyHandle : public ::IceUtil::HandleBase +{ +public: + + ProxyHandle(T* p = 0) + { + this->_ptr = p; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + template + ProxyHandle(const ProxyHandle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + template + ProxyHandle(const ::IceUtil::Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + ProxyHandle(const ProxyHandle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + upCast(this->_ptr)->__incRef(); + } + } + + ~ProxyHandle() + { + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + } + + ProxyHandle& operator=(T* p) + { + if(this->_ptr != p) + { + if(p) + { + upCast(p)->__incRef(); + } + + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + + this->_ptr = p; + } + return *this; + } + + template + ProxyHandle& operator=(const ProxyHandle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + + this->_ptr = r._ptr; + } + return *this; + } + + template + ProxyHandle& operator=(const ::IceUtil::Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + + this->_ptr = r._ptr; + } + return *this; + } + + ProxyHandle& operator=(const ProxyHandle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + upCast(r._ptr)->__incRef(); + } + + if(this->_ptr) + { + upCast(this->_ptr)->__decRef(); + } + + this->_ptr = r._ptr; + } + return *this; + } + + ::IceProxy::Ice::Object* _upCast() const + { + return upCast(this->_ptr); + } + + template + static ProxyHandle checkedCast(const ProxyHandle& r, const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + Y* tag = 0; + return ::IceInternal::checkedCastHelper(r, tag, ctx); + } + + template + static ProxyHandle checkedCast(const ProxyHandle& r, const std::string& f, + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { +#ifdef __SUNPRO_CC + // + // Sun CC bug introduced in version 5.10 + // + const ::Ice::ObjectPrx& o = r; + return ::IceInternal::checkedCastImpl(o, f, ctx); +#else + return ::IceInternal::checkedCastImpl(r, f, ctx); +#endif + } + + template + static ProxyHandle uncheckedCast(const ProxyHandle& r) + { + Y* tag = 0; + return::IceInternal::uncheckedCastHelper(r, tag); + } + + template + static ProxyHandle uncheckedCast(const ProxyHandle& r, const std::string& f) + { +#ifdef __SUNPRO_CC + // + // Sun CC bug introduced in version 5.10 + // + const ::Ice::ObjectPrx& o = r; + return ::IceInternal::uncheckedCastImpl >(o, f); +#else + return ::IceInternal::uncheckedCastImpl(r, f); +#endif + } + + static const std::string& ice_staticId() + { + return T::ice_staticId(); + } +}; + +template +std::ostream& operator<<(std::ostream& os, ::IceInternal::ProxyHandle p) +{ + return os << (p ? p->ice_toString() : std::string("")); +} + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/Reference.h b/Sources/IceCpp/include/Ice/Reference.h new file mode 100644 index 0000000..adaf4bf --- /dev/null +++ b/Sources/IceCpp/include/Ice/Reference.h @@ -0,0 +1,323 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REFERENCE_H +#define ICE_REFERENCE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; + +} + +namespace IceInternal +{ + +class Reference : public IceUtil::Shared +{ +public: + + class GetConnectionCallback +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif + { + public: + + virtual void setConnection(const Ice::ConnectionIPtr&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + ICE_DEFINE_PTR(GetConnectionCallbackPtr, GetConnectionCallback); + + enum Mode + { + ModeTwoway, + ModeOneway, + ModeBatchOneway, + ModeDatagram, + ModeBatchDatagram, + ModeLast = ModeBatchDatagram + }; + + Mode getMode() const { return _mode; } + bool getSecure() const { return _secure; } + const Ice::ProtocolVersion& getProtocol() const { return _protocol; } + const Ice::EncodingVersion& getEncoding() const { return _encoding; } + const Ice::Identity& getIdentity() const { return _identity; } + const std::string& getFacet() const { return _facet; } + const InstancePtr& getInstance() const { return _instance; } + const SharedContextPtr& getContext() const { return _context; } + int getInvocationTimeout() const { return _invocationTimeout; } + IceUtil::Optional getCompress() const + { + return _overrideCompress ? IceUtil::Optional(_compress) : IceUtil::None; + } + + Ice::CommunicatorPtr getCommunicator() const; + + virtual std::vector getEndpoints() const = 0; + virtual std::string getAdapterId() const = 0; + virtual LocatorInfoPtr getLocatorInfo() const { return 0; } + virtual RouterInfoPtr getRouterInfo() const { return 0; } + virtual bool getCollocationOptimized() const = 0; + virtual bool getCacheConnection() const = 0; + virtual bool getPreferSecure() const = 0; + virtual Ice::EndpointSelectionType getEndpointSelection() const = 0; + virtual int getLocatorCacheTimeout() const = 0; + virtual std::string getConnectionId() const = 0; + virtual IceUtil::Optional getTimeout() const = 0; + + // + // The change* methods (here and in derived classes) create + // a new reference based on the existing one, with the + // corresponding value changed. + // + ReferencePtr changeContext(const Ice::Context&) const; + ReferencePtr changeMode(Mode) const; + ReferencePtr changeSecure(bool) const; + ReferencePtr changeIdentity(const Ice::Identity&) const; + ReferencePtr changeFacet(const std::string&) const; + ReferencePtr changeInvocationTimeout(int) const; + virtual ReferencePtr changeEncoding(const Ice::EncodingVersion&) const; + virtual ReferencePtr changeCompress(bool) const; + + virtual ReferencePtr changeEndpoints(const std::vector&) const = 0; + virtual ReferencePtr changeAdapterId(const std::string&) const = 0; + virtual ReferencePtr changeLocator(const Ice::LocatorPrxPtr&) const = 0; + virtual ReferencePtr changeRouter(const Ice::RouterPrxPtr&) const = 0; + virtual ReferencePtr changeCollocationOptimized(bool) const = 0; + virtual ReferencePtr changeLocatorCacheTimeout(int) const = 0; + virtual ReferencePtr changeCacheConnection(bool) const = 0; + virtual ReferencePtr changePreferSecure(bool) const = 0; + virtual ReferencePtr changeEndpointSelection(Ice::EndpointSelectionType) const = 0; + + virtual ReferencePtr changeTimeout(int) const = 0; + virtual ReferencePtr changeConnectionId(const std::string&) const = 0; + virtual ReferencePtr changeConnection(const Ice::ConnectionIPtr&) const = 0; + + int hash() const; // Conceptually const. + + bool getCompressOverride(bool&) const; + + // + // Utility methods. + // + virtual bool isIndirect() const = 0; + virtual bool isWellKnown() const = 0; + + // + // Marshal the reference. + // + virtual void streamWrite(Ice::OutputStream*) const; + + // + // Convert the reference to its string form. + // + virtual std::string toString() const; + + // + // Convert the refernce to its property form. + // + virtual Ice::PropertyDict toProperty(const std::string&) const = 0; + + // + // Get a suitable connection for this reference. + // + virtual RequestHandlerPtr getRequestHandler(const Ice::ObjectPrxPtr&) const = 0; + virtual BatchRequestQueuePtr getBatchRequestQueue() const = 0; + + virtual bool operator==(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const = 0; + +protected: + + Reference(const InstancePtr&, const Ice::CommunicatorPtr&, const Ice::Identity&, const std::string&, Mode, bool, + const Ice::ProtocolVersion&, const Ice::EncodingVersion&, int, const Ice::Context& ctx); + Reference(const Reference&); + + virtual Ice::Int hashInit() const; + + mutable Ice::Int _hashValue; + mutable bool _hashInitialized; + +private: + + const InstancePtr _instance; + const Ice::CommunicatorPtr _communicator; + + Mode _mode; + bool _secure; + Ice::Identity _identity; + SharedContextPtr _context; + std::string _facet; + Ice::ProtocolVersion _protocol; + Ice::EncodingVersion _encoding; + int _invocationTimeout; + +protected: + + bool _overrideCompress; + bool _compress; // Only used if _overrideCompress == true +}; + +class FixedReference : public Reference +{ +public: + + FixedReference(const InstancePtr&, const Ice::CommunicatorPtr&, const Ice::Identity&, const std::string&, Mode, + bool, const Ice::ProtocolVersion&, const Ice::EncodingVersion&, const Ice::ConnectionIPtr&, + int, const Ice::Context&, const IceUtil::Optional&); + + virtual std::vector getEndpoints() const; + virtual std::string getAdapterId() const; + virtual bool getCollocationOptimized() const; + virtual bool getCacheConnection() const; + virtual bool getPreferSecure() const; + virtual Ice::EndpointSelectionType getEndpointSelection() const; + virtual int getLocatorCacheTimeout() const; + virtual std::string getConnectionId() const; + virtual IceUtil::Optional getTimeout() const; + + virtual ReferencePtr changeEndpoints(const std::vector&) const; + virtual ReferencePtr changeAdapterId(const std::string&) const; + virtual ReferencePtr changeLocator(const Ice::LocatorPrxPtr&) const; + virtual ReferencePtr changeRouter(const Ice::RouterPrxPtr&) const; + virtual ReferencePtr changeCollocationOptimized(bool) const; + virtual ReferencePtr changeCacheConnection(bool) const; + virtual ReferencePtr changePreferSecure(bool) const; + virtual ReferencePtr changeEndpointSelection(Ice::EndpointSelectionType) const; + virtual ReferencePtr changeLocatorCacheTimeout(int) const; + + virtual ReferencePtr changeTimeout(int) const; + virtual ReferencePtr changeConnectionId(const std::string&) const; + virtual ReferencePtr changeConnection(const Ice::ConnectionIPtr&) const; + + virtual bool isIndirect() const; + virtual bool isWellKnown() const; + + virtual void streamWrite(Ice::OutputStream*) const; + virtual Ice::PropertyDict toProperty(const std::string&) const; + + virtual RequestHandlerPtr getRequestHandler(const Ice::ObjectPrxPtr&) const; + virtual BatchRequestQueuePtr getBatchRequestQueue() const; + + virtual bool operator==(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const; + +private: + + FixedReference(const FixedReference&); + + Ice::ConnectionIPtr _fixedConnection; +}; + +class RoutableReference : public Reference +{ +public: + + RoutableReference(const InstancePtr&, const Ice::CommunicatorPtr&, const Ice::Identity&, const std::string&, Mode, + bool, const Ice::ProtocolVersion&, const Ice::EncodingVersion&, const std::vector&, + const std::string&, const LocatorInfoPtr&, const RouterInfoPtr&, bool, bool, bool, + Ice::EndpointSelectionType, int, int, const Ice::Context&); + + virtual std::vector getEndpoints() const; + virtual std::string getAdapterId() const; + virtual LocatorInfoPtr getLocatorInfo() const; + virtual RouterInfoPtr getRouterInfo() const; + virtual bool getCollocationOptimized() const; + virtual bool getCacheConnection() const; + virtual bool getPreferSecure() const; + virtual Ice::EndpointSelectionType getEndpointSelection() const; + virtual int getLocatorCacheTimeout() const; + virtual std::string getConnectionId() const; + virtual IceUtil::Optional getTimeout() const; + + virtual ReferencePtr changeEncoding(const Ice::EncodingVersion&) const; + virtual ReferencePtr changeCompress(bool) const; + virtual ReferencePtr changeEndpoints(const std::vector&) const; + virtual ReferencePtr changeAdapterId(const std::string&) const; + virtual ReferencePtr changeLocator(const Ice::LocatorPrxPtr&) const; + virtual ReferencePtr changeRouter(const Ice::RouterPrxPtr&) const; + virtual ReferencePtr changeCollocationOptimized(bool) const; + virtual ReferencePtr changeCacheConnection(bool) const; + virtual ReferencePtr changePreferSecure(bool) const; + virtual ReferencePtr changeEndpointSelection(Ice::EndpointSelectionType) const; + virtual ReferencePtr changeLocatorCacheTimeout(int) const; + + virtual ReferencePtr changeTimeout(int) const; + virtual ReferencePtr changeConnectionId(const std::string&) const; + virtual ReferencePtr changeConnection(const Ice::ConnectionIPtr&) const; + + virtual bool isIndirect() const; + virtual bool isWellKnown() const; + + virtual void streamWrite(Ice::OutputStream*) const; + virtual std::string toString() const; + virtual Ice::PropertyDict toProperty(const std::string&) const; + + virtual bool operator==(const Reference&) const; + virtual bool operator<(const Reference&) const; + + virtual ReferencePtr clone() const; + + virtual RequestHandlerPtr getRequestHandler(const Ice::ObjectPrxPtr&) const; + virtual BatchRequestQueuePtr getBatchRequestQueue() const; + + void getConnection(const GetConnectionCallbackPtr&) const; + void getConnectionNoRouterInfo(const GetConnectionCallbackPtr&) const; + + void createConnection(const std::vector&, const GetConnectionCallbackPtr&) const; + void applyOverrides(std::vector&) const; + +protected: + + RoutableReference(const RoutableReference&); + + std::vector filterEndpoints(const std::vector&) const; + + virtual int hashInit() const; + +private: + + std::vector _endpoints; // Empty if indirect proxy. + std::string _adapterId; // Empty if direct proxy. + + LocatorInfoPtr _locatorInfo; // Null if no locator is used. + RouterInfoPtr _routerInfo; // Null if no router is used. + bool _collocationOptimized; + bool _cacheConnection; + bool _preferSecure; + Ice::EndpointSelectionType _endpointSelection; + int _locatorCacheTimeout; + + bool _overrideTimeout; + int _timeout; // Only used if _overrideTimeout == true + std::string _connectionId; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ReferenceF.h b/Sources/IceCpp/include/Ice/ReferenceF.h new file mode 100644 index 0000000..97d5cc4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ReferenceF.h @@ -0,0 +1,29 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REFERENCE_F_H +#define ICE_REFERENCE_F_H + +#include + +#include + +namespace IceInternal +{ + +class Reference; +ICE_API IceUtil::Shared* upCast(Reference*); +typedef IceInternal::Handle ReferencePtr; + +class FixedReference; +ICE_API IceUtil::Shared* upCast(FixedReference*); +typedef IceInternal::Handle FixedReferencePtr; + +class RoutableReference; +ICE_API IceUtil::Shared* upCast(RoutableReference*); +typedef IceInternal::Handle RoutableReferencePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ReferenceFactory.h b/Sources/IceCpp/include/Ice/ReferenceFactory.h new file mode 100644 index 0000000..b32874e --- /dev/null +++ b/Sources/IceCpp/include/Ice/ReferenceFactory.h @@ -0,0 +1,76 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REFERENCE_FACTORY_H +#define ICE_REFERENCE_FACTORY_H + +#include +#include +#include // For Reference::Mode +#include +#include + +namespace IceInternal +{ + +class ReferenceFactory : public ::IceUtil::Shared +{ +public: + + // + // Make a polymorphic copy of a reference. + // + ReferencePtr copy(const Reference* r) const; + + // + // Create a direct reference. + // + ReferencePtr create(const ::Ice::Identity&, const ::std::string&, const ReferencePtr&, + const ::std::vector&); + + // + // Create an indirect reference. + // + ReferencePtr create(const ::Ice::Identity&, const ::std::string&, const ReferencePtr&, const std::string&); + + // + // Create a fixed reference. + // + ReferencePtr create(const ::Ice::Identity&, const Ice::ConnectionIPtr&); + + // + // Create a reference from a string. + // + ReferencePtr create(const ::std::string&, const std::string&); + + // + // Create a reference by unmarshaling it from a stream. + // + ReferencePtr create(const ::Ice::Identity&, Ice::InputStream*); + + ReferenceFactoryPtr setDefaultRouter(const ::Ice::RouterPrxPtr&); + ::Ice::RouterPrxPtr getDefaultRouter() const; + + ReferenceFactoryPtr setDefaultLocator(const ::Ice::LocatorPrxPtr&); + ::Ice::LocatorPrxPtr getDefaultLocator() const; + +private: + + ReferenceFactory(const InstancePtr&, const ::Ice::CommunicatorPtr&); + friend class Instance; + + void checkForUnknownProperties(const std::string&); + RoutableReferencePtr create(const ::Ice::Identity&, const ::std::string&, Reference::Mode, bool, + const Ice::ProtocolVersion&, const Ice::EncodingVersion&, + const std::vector&, const std::string&, const std::string&); + + const InstancePtr _instance; + const ::Ice::CommunicatorPtr _communicator; + ::Ice::RouterPrxPtr _defaultRouter; + ::Ice::LocatorPrxPtr _defaultLocator; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ReferenceFactoryF.h b/Sources/IceCpp/include/Ice/ReferenceFactoryF.h new file mode 100644 index 0000000..1fe7623 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ReferenceFactoryF.h @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REFERENCE_FACTORY_F_H +#define ICE_REFERENCE_FACTORY_F_H + +#include + +namespace IceInternal +{ + +class ReferenceFactory; +IceUtil::Shared* upCast(ReferenceFactory*); +typedef Handle ReferenceFactoryPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RegisterPlugins.h b/Sources/IceCpp/include/Ice/RegisterPlugins.h new file mode 100644 index 0000000..ee2545e --- /dev/null +++ b/Sources/IceCpp/include/Ice/RegisterPlugins.h @@ -0,0 +1,127 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REGISTER_PLUGINS_H +#define ICE_REGISTER_PLUGINS_H + +#include + +// +// Register functions for Ice plugins are declared here. +// +// These functions can be used to explicitly link with a plugin rather +// than relying on the loading of the plugin at runtime. The application +// must call the register function before initializing the communicator. +// + +namespace Ice +{ + +#if defined(ICE_STATIC_LIBS) +# define ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT /**/ +#else +# define ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT ICE_DECLSPEC_IMPORT +#endif + +// +// Checking for the API_EXPORTS macro is necessary to prevent +// inconsistent DLL linkage errors on Windows. +// + +#ifndef ICE_API_EXPORTS +/** + * When using static libraries, calling this function ensures the string converter plug-in is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceStringConverter(bool loadOnInitialize = true); + +/** + * When using static libraries, calling this function ensures the UDP transport is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceUDP(bool loadOnInitialize = true); + +/** + * When using static libraries, calling this function ensures the WebSocket transport is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceWS(bool loadOnInitialize = true); +#endif + +#ifndef ICESSL_API_EXPORTS +/** + * When using static libraries, calling this function ensures the SSL transport is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceSSL(bool loadOnInitialize = true); +#endif + +#ifndef ICE_DISCOVERY_API_EXPORTS +/** + * When using static libraries, calling this function ensures the IceDiscovery plug-in is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceDiscovery(bool loadOnInitialize = true); +#endif + +#ifndef ICE_LOCATOR_DISCOVERY_API_EXPORTS +/** + * When using static libraries, calling this function ensures the IceLocatorDiscovery plug-in is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceLocatorDiscovery(bool loadOnInitialize = true); +#endif + +#if !defined(_WIN32) && !defined(__APPLE__) +# ifndef ICEBT_API_EXPORTS +/** + * When using static libraries, calling this function ensures the IceBT plug-in is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceBT(bool loadOnInitialize = true); +# endif +#endif + +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 +# ifndef ICEIAP_API_EXPORTS +/** + * When using static libraries, calling this function ensures the iAP plug-in is + * linked with the application. + * @param loadOnInitialize If true, the plug-in is loaded (created) during communicator initialization. + * If false, the plug-in is only loaded during communicator initialization if its corresponding + * plug-in property is set to 1. + */ +ICE_PLUGIN_REGISTER_DECLSPEC_IMPORT void registerIceIAP(bool loadOnInitialize = true); +# endif +#endif + +#if defined(_MSC_VER) && !defined(ICE_BUILDING_SRC) +# pragma comment(lib, ICE_LIBNAME("IceDiscovery")) +# pragma comment(lib, ICE_LIBNAME("IceLocatorDiscovery")) +# pragma comment(lib, ICE_LIBNAME("IceSSL")) +#endif +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RegisterPluginsInit.h b/Sources/IceCpp/include/Ice/RegisterPluginsInit.h new file mode 100644 index 0000000..c78edeb --- /dev/null +++ b/Sources/IceCpp/include/Ice/RegisterPluginsInit.h @@ -0,0 +1,20 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REGISTER_PLUGINS_INIT_H +#define ICE_REGISTER_PLUGINS_INIT_H + +namespace IceInternal +{ + +class RegisterPluginsInit +{ +public: + + RegisterPluginsInit(); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RemoteLogger.h b/Sources/IceCpp/include/Ice/RemoteLogger.h new file mode 100644 index 0000000..d386ebb --- /dev/null +++ b/Sources/IceCpp/include/Ice/RemoteLogger.h @@ -0,0 +1,2707 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RemoteLogger.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_RemoteLogger_h__ +#define __Ice_RemoteLogger_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class RemoteLogger; +class RemoteLoggerPrx; +class LoggerAdmin; +class LoggerAdminPrx; + +} + +namespace Ice +{ + +/** + * An enumeration representing the different types of log messages. + */ +enum class LogMessageType : unsigned char +{ + /** + * The {@link Logger} received a print message. + */ + PrintMessage, + /** + * The {@link Logger} received a trace message. + */ + TraceMessage, + /** + * The {@link Logger} received a warning message. + */ + WarningMessage, + /** + * The {@link Logger} received an error message. + */ + ErrorMessage +}; + +/** + * A sequence of {@link LogMessageType} + */ +using LogMessageTypeSeq = ::std::vector; + +/** + * A complete log message. + * \headerfile Ice/Ice.h + */ +struct LogMessage +{ + /** + * The type of message sent to the {@link Logger}. + */ + ::Ice::LogMessageType type; + /** + * The date and time when the {@link Logger} received this message, expressed + * as the number of microseconds since the Unix Epoch (00:00:00 UTC on 1 January 1970) + */ + long long int timestamp; + /** + * For a message of type trace, the trace category of this log message; + * otherwise, the empty string. + */ + ::std::string traceCategory; + /** + * The log message itself. + */ + ::std::string message; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(type, timestamp, traceCategory, message); + } +}; + +/** + * A sequence of {@link LogMessage}. + */ +using LogMessageSeq = std::list; + +/** + * Thrown when the provided RemoteLogger was previously attached to a LoggerAdmin. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RemoteLoggerAlreadyAttachedException : public UserExceptionHelper +{ +public: + + ICE_MEMBER(ICE_API) virtual ~RemoteLoggerAlreadyAttachedException(); + + RemoteLoggerAlreadyAttachedException(const RemoteLoggerAlreadyAttachedException&) = default; + + RemoteLoggerAlreadyAttachedException() = default; + + /** + * Obtains a tuple containing all of the exception's data members. + * @return The data members in a tuple. + */ + std::tuple<> ice_tuple() const + { + return std::tie(); + } + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); +}; + +/// \cond INTERNAL +static RemoteLoggerAlreadyAttachedException _iceS_RemoteLoggerAlreadyAttachedException_init; +/// \endcond + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +namespace Ice +{ + +/** + * The Ice remote logger interface. An application can implement a + * RemoteLogger to receive the log messages sent to the local {@link Logger} + * of another Ice application. + * \headerfile Ice/Ice.h + */ +class ICE_API RemoteLogger : public virtual Object +{ +public: + + using ProxyType = RemoteLoggerPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param current The Current object for the invocation. + */ + virtual void init(::std::string prefix, LogMessageSeq logMessages, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_init(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param current The Current object for the invocation. + */ + virtual void log(LogMessage message, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_log(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +/** + * The interface of the admin object that allows an Ice application the attach its + * {@link RemoteLogger} to the {@link Logger} of this admin object's Ice communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API LoggerAdmin : public virtual Object +{ +public: + + using ProxyType = LoggerAdminPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param current The Current object for the invocation. + * @throws Ice::RemoteLoggerAlreadyAttachedException Raised if this remote logger is already + * attached to this admin object. + */ + virtual void attachRemoteLogger(::std::shared_ptr prx, LogMessageTypeSeq messageTypes, StringSeq traceCategories, int messageMax, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_attachRemoteLogger(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param current The Current object for the invocation. + * @return True if the provided remote logger proxy was detached, and false otherwise. + */ + virtual bool detachRemoteLogger(::std::shared_ptr prx, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_detachRemoteLogger(::IceInternal::Incoming&, const Current&); + /// \endcond + + /** + * Encapsulates the results of a call to getLog. + */ + struct GetLogResult + { + /** The Log messages. */ + LogMessageSeq returnValue; + /** The prefix of the associated local logger. */ + ::std::string prefix; + }; + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param prefix The prefix of the associated local logger. + * @param current The Current object for the invocation. + * @return The Log messages. + */ + virtual LogMessageSeq getLog(LogMessageTypeSeq messageTypes, StringSeq traceCategories, int messageMax, ::std::string& prefix, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getLog(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * The Ice remote logger interface. An application can implement a + * RemoteLogger to receive the log messages sent to the local {@link Logger} + * of another Ice application. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RemoteLoggerPrx : public virtual Proxy +{ +public: + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + */ + void init(const ::std::string& prefix, const LogMessageSeq& logMessages, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &RemoteLoggerPrx::_iceI_init, prefix, logMessages, context).get(); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto initAsync(const ::std::string& prefix, const LogMessageSeq& logMessages, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &RemoteLoggerPrx::_iceI_init, prefix, logMessages, context); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + initAsync(const ::std::string& prefix, const LogMessageSeq& logMessages, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::RemoteLoggerPrx::_iceI_init, prefix, logMessages, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_init(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const LogMessageSeq&, const Context&); + /// \endcond + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + */ + void log(const LogMessage& message, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &RemoteLoggerPrx::_iceI_log, message, context).get(); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto logAsync(const LogMessage& message, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &RemoteLoggerPrx::_iceI_log, message, context); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + logAsync(const LogMessage& message, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::RemoteLoggerPrx::_iceI_log, message, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_log(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const LogMessage&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + RemoteLoggerPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +/** + * The interface of the admin object that allows an Ice application the attach its + * {@link RemoteLogger} to the {@link Logger} of this admin object's Ice communicator. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) LoggerAdminPrx : public virtual Proxy +{ +public: + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @throws Ice::RemoteLoggerAlreadyAttachedException Raised if this remote logger is already + * attached to this admin object. + */ + void attachRemoteLogger(const ::std::shared_ptr& prx, const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, const Context& context = noExplicitContext) + { + _makePromiseOutgoing(true, this, &LoggerAdminPrx::_iceI_attachRemoteLogger, prx, messageTypes, traceCategories, messageMax, context).get(); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto attachRemoteLoggerAsync(const ::std::shared_ptr& prx, const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LoggerAdminPrx::_iceI_attachRemoteLogger, prx, messageTypes, traceCategories, messageMax, context); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + attachRemoteLoggerAsync(const ::std::shared_ptr& prx, const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::LoggerAdminPrx::_iceI_attachRemoteLogger, prx, messageTypes, traceCategories, messageMax, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_attachRemoteLogger(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::shared_ptr&, const LogMessageTypeSeq&, const StringSeq&, int, const Context&); + /// \endcond + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @return True if the provided remote logger proxy was detached, and false otherwise. + */ + bool detachRemoteLogger(const ::std::shared_ptr& prx, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing(true, this, &LoggerAdminPrx::_iceI_detachRemoteLogger, prx, context).get(); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto detachRemoteLoggerAsync(const ::std::shared_ptr& prx, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LoggerAdminPrx::_iceI_detachRemoteLogger, prx, context); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + detachRemoteLoggerAsync(const ::std::shared_ptr& prx, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &Ice::LoggerAdminPrx::_iceI_detachRemoteLogger, prx, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_detachRemoteLogger(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::shared_ptr&, const Context&); + /// \endcond + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param prefix The prefix of the associated local logger. + * @param context The Context map to send with the invocation. + * @return The Log messages. + */ + LogMessageSeq getLog(const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, ::std::string& prefix, const Context& context = noExplicitContext) + { + auto _result = _makePromiseOutgoing(true, this, &LoggerAdminPrx::_iceI_getLog, messageTypes, traceCategories, messageMax, context).get(); + prefix = ::std::move(_result.prefix); + return ::std::move(_result.returnValue); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getLogAsync(const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LoggerAdminPrx::_iceI_getLog, messageTypes, traceCategories, messageMax, context); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getLogAsync(const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, int messageMax, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + auto _responseCb = [response](LoggerAdmin::GetLogResult&& _result) + { + response(::std::move(_result.returnValue), ::std::move(_result.prefix)); + }; + return _makeLamdaOutgoing(std::move(_responseCb), std::move(ex), std::move(sent), this, &Ice::LoggerAdminPrx::_iceI_getLog, messageTypes, traceCategories, messageMax, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getLog(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const LogMessageTypeSeq&, const StringSeq&, int, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LoggerAdminPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::LogMessageType> +{ + static const StreamHelperCategory helper = StreamHelperCategoryEnum; + static const int minValue = 0; + static const int maxValue = 3; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +template<> +struct StreamableTraits<::Ice::LogMessage> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 11; + static const bool fixedLength = false; +}; + +template +struct StreamReader<::Ice::LogMessage, S> +{ + static void read(S* istr, ::Ice::LogMessage& v) + { + istr->readAll(v.type, v.timestamp, v.traceCategory, v.message); + } +}; + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using RemoteLoggerPtr = ::std::shared_ptr; +using RemoteLoggerPrxPtr = ::std::shared_ptr; + +using LoggerAdminPtr = ::std::shared_ptr; +using LoggerAdminPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class RemoteLogger; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< RemoteLogger>&); +ICE_API ::IceProxy::Ice::Object* upCast(RemoteLogger*); +/// \endcond + +class LoggerAdmin; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LoggerAdmin>&); +ICE_API ::IceProxy::Ice::Object* upCast(LoggerAdmin*); +/// \endcond + +} + +} + +namespace Ice +{ + +class RemoteLogger; +/// \cond INTERNAL +ICE_API Object* upCast(RemoteLogger*); +/// \endcond +typedef ::IceInternal::Handle< RemoteLogger> RemoteLoggerPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::RemoteLogger> RemoteLoggerPrx; +typedef RemoteLoggerPrx RemoteLoggerPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(RemoteLoggerPtr&, const ObjectPtr&); +/// \endcond + +class LoggerAdmin; +/// \cond INTERNAL +ICE_API Object* upCast(LoggerAdmin*); +/// \endcond +typedef ::IceInternal::Handle< LoggerAdmin> LoggerAdminPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::LoggerAdmin> LoggerAdminPrx; +typedef LoggerAdminPrx LoggerAdminPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(LoggerAdminPtr&, const ObjectPtr&); +/// \endcond + +} + +namespace Ice +{ + +/** + * An enumeration representing the different types of log messages. + */ +enum LogMessageType +{ + /** + * The {@link Logger} received a print message. + */ + PrintMessage, + /** + * The {@link Logger} received a trace message. + */ + TraceMessage, + /** + * The {@link Logger} received a warning message. + */ + WarningMessage, + /** + * The {@link Logger} received an error message. + */ + ErrorMessage +}; + +/** + * A sequence of {@link LogMessageType} + */ +typedef ::std::vector LogMessageTypeSeq; + +/** + * A complete log message. + * \headerfile Ice/Ice.h + */ +struct LogMessage +{ + /** + * The type of message sent to the {@link Logger}. + */ + ::Ice::LogMessageType type; + /** + * The date and time when the {@link Logger} received this message, expressed + * as the number of microseconds since the Unix Epoch (00:00:00 UTC on 1 January 1970) + */ + ::Ice::Long timestamp; + /** + * For a message of type trace, the trace category of this log message; + * otherwise, the empty string. + */ + ::std::string traceCategory; + /** + * The log message itself. + */ + ::std::string message; + + bool operator==(const LogMessage& rhs_) const + { + if(this == &rhs_) + { + return true; + } + if(type != rhs_.type) + { + return false; + } + if(timestamp != rhs_.timestamp) + { + return false; + } + if(traceCategory != rhs_.traceCategory) + { + return false; + } + if(message != rhs_.message) + { + return false; + } + return true; + } + + bool operator<(const LogMessage& rhs_) const + { + if(this == &rhs_) + { + return false; + } + if(type < rhs_.type) + { + return true; + } + else if(rhs_.type < type) + { + return false; + } + if(timestamp < rhs_.timestamp) + { + return true; + } + else if(rhs_.timestamp < timestamp) + { + return false; + } + if(traceCategory < rhs_.traceCategory) + { + return true; + } + else if(rhs_.traceCategory < traceCategory) + { + return false; + } + if(message < rhs_.message) + { + return true; + } + else if(rhs_.message < message) + { + return false; + } + return false; + } + + bool operator!=(const LogMessage& rhs_) const + { + return !operator==(rhs_); + } + bool operator<=(const LogMessage& rhs_) const + { + return operator<(rhs_) || operator==(rhs_); + } + bool operator>(const LogMessage& rhs_) const + { + return !operator<(rhs_) && !operator==(rhs_); + } + bool operator>=(const LogMessage& rhs_) const + { + return !operator<(rhs_); + } +}; + +/** + * A sequence of {@link LogMessage}. + */ +typedef std::list LogMessageSeq; + +/** + * Thrown when the provided RemoteLogger was previously attached to a LoggerAdmin. + * \headerfile Ice/Ice.h + */ +class ICE_API RemoteLoggerAlreadyAttachedException : public UserException +{ +public: + + RemoteLoggerAlreadyAttachedException() {} + +#ifdef ICE_CPP11_COMPILER + RemoteLoggerAlreadyAttachedException(const RemoteLoggerAlreadyAttachedException&) = default; + virtual ~RemoteLoggerAlreadyAttachedException(); +#else + virtual ~RemoteLoggerAlreadyAttachedException() throw(); +#endif + + /** + * Obtains the Slice type ID of this exception. + * @return The fully-scoped type ID. + */ + virtual ::std::string ice_id() const; + /** + * Polymorphically clones this exception. + * @return A shallow copy of this exception. + */ + virtual RemoteLoggerAlreadyAttachedException* ice_clone() const; + /** + * Throws this exception. + */ + virtual void ice_throw() const; + +protected: + + /// \cond STREAM + virtual void _writeImpl(OutputStream*) const; + virtual void _readImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +static RemoteLoggerAlreadyAttachedException _iceS_RemoteLoggerAlreadyAttachedException_init; +/// \endcond + +} + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::RemoteLogger::begin_init. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_init. + */ +class Callback_RemoteLogger_init_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_RemoteLogger_init_Base> Callback_RemoteLogger_initPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::RemoteLogger::begin_log. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_log. + */ +class Callback_RemoteLogger_log_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_RemoteLogger_log_Base> Callback_RemoteLogger_logPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_attachRemoteLogger. + */ +class Callback_LoggerAdmin_attachRemoteLogger_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LoggerAdmin_attachRemoteLogger_Base> Callback_LoggerAdmin_attachRemoteLoggerPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_detachRemoteLogger. + */ +class Callback_LoggerAdmin_detachRemoteLogger_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LoggerAdmin_detachRemoteLogger_Base> Callback_LoggerAdmin_detachRemoteLoggerPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::LoggerAdmin::begin_getLog. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_getLog. + */ +class Callback_LoggerAdmin_getLog_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LoggerAdmin_getLog_Base> Callback_LoggerAdmin_getLogPtr; + +} + +namespace IceProxy +{ + +namespace Ice +{ + +class ICE_CLASS(ICE_API) RemoteLogger : public virtual ::Ice::Proxy +{ +public: + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + */ + ICE_MEMBER(ICE_API) void init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_init(_iceI_begin_init(prefix, logMessages, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_init(prefix, logMessages, context, ::IceInternal::dummyCallback, 0); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_init(prefix, logMessages, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_init(prefix, logMessages, context, cb, cookie); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::Callback_RemoteLogger_initPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_init(prefix, logMessages, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_init(const ::std::string& prefix, const ::Ice::LogMessageSeq& logMessages, const ::Ice::Context& context, const ::Ice::Callback_RemoteLogger_initPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_init(prefix, logMessages, context, cb, cookie); + } + + /** + * Completes an invocation of begin_init. + * @param result The asynchronous result object for the invocation. + */ + ICE_MEMBER(ICE_API) void end_init(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_init(const ::std::string&, const ::Ice::LogMessageSeq&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + */ + ICE_MEMBER(ICE_API) void log(const ::Ice::LogMessage& message, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_log(_iceI_begin_log(message, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_log(const ::Ice::LogMessage& message, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_log(message, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_log(const ::Ice::LogMessage& message, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_log(message, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_log(const ::Ice::LogMessage& message, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_log(message, context, cb, cookie); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_log(const ::Ice::LogMessage& message, const ::Ice::Callback_RemoteLogger_logPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_log(message, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_log(const ::Ice::LogMessage& message, const ::Ice::Context& context, const ::Ice::Callback_RemoteLogger_logPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_log(message, context, cb, cookie); + } + + /** + * Completes an invocation of begin_log. + * @param result The asynchronous result object for the invocation. + */ + ICE_MEMBER(ICE_API) void end_log(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_log(const ::Ice::LogMessage&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) LoggerAdmin : public virtual ::Ice::Proxy +{ +public: + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @throws Ice::RemoteLoggerAlreadyAttachedException Raised if this remote logger is already + * attached to this admin object. + */ + ICE_MEMBER(ICE_API) void attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_attachRemoteLogger(_iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, context, cb, cookie); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Callback_LoggerAdmin_attachRemoteLoggerPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context, const ::Ice::Callback_LoggerAdmin_attachRemoteLoggerPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_attachRemoteLogger(prx, messageTypes, traceCategories, messageMax, context, cb, cookie); + } + + /** + * Completes an invocation of begin_attachRemoteLogger. + * @param result The asynchronous result object for the invocation. + * @throws Ice::RemoteLoggerAlreadyAttachedException Raised if this remote logger is already + * attached to this admin object. + */ + ICE_MEMBER(ICE_API) void end_attachRemoteLogger(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_attachRemoteLogger(const ::Ice::RemoteLoggerPrx&, const ::Ice::LogMessageTypeSeq&, const ::Ice::StringSeq&, ::Ice::Int, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @return True if the provided remote logger proxy was detached, and false otherwise. + */ + ICE_MEMBER(ICE_API) bool detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_detachRemoteLogger(_iceI_begin_detachRemoteLogger(prx, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_detachRemoteLogger(prx, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_detachRemoteLogger(prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_detachRemoteLogger(prx, context, cb, cookie); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::Callback_LoggerAdmin_detachRemoteLoggerPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_detachRemoteLogger(prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx& prx, const ::Ice::Context& context, const ::Ice::Callback_LoggerAdmin_detachRemoteLoggerPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_detachRemoteLogger(prx, context, cb, cookie); + } + + /** + * Completes an invocation of begin_detachRemoteLogger. + * @param result The asynchronous result object for the invocation. + * @return True if the provided remote logger proxy was detached, and false otherwise. + */ + ICE_MEMBER(ICE_API) bool end_detachRemoteLogger(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_detachRemoteLogger(const ::Ice::RemoteLoggerPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param prefix The prefix of the associated local logger. + * @param context The Context map to send with the invocation. + * @return The Log messages. + */ + ICE_MEMBER(ICE_API) ::Ice::LogMessageSeq getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, ::std::string& prefix, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getLog(prefix, _iceI_begin_getLog(messageTypes, traceCategories, messageMax, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getLog(messageTypes, traceCategories, messageMax, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLog(messageTypes, traceCategories, messageMax, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLog(messageTypes, traceCategories, messageMax, context, cb, cookie); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Callback_LoggerAdmin_getLogPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLog(messageTypes, traceCategories, messageMax, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getLog(const ::Ice::LogMessageTypeSeq& messageTypes, const ::Ice::StringSeq& traceCategories, ::Ice::Int messageMax, const ::Ice::Context& context, const ::Ice::Callback_LoggerAdmin_getLogPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getLog(messageTypes, traceCategories, messageMax, context, cb, cookie); + } + + /** + * Completes an invocation of begin_getLog. + * @param prefix The prefix of the associated local logger. + * @param result The asynchronous result object for the invocation. + * @return The Log messages. + */ + ICE_MEMBER(ICE_API) ::Ice::LogMessageSeq end_getLog(::std::string& prefix, const ::Ice::AsyncResultPtr& result); + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) void _iceI_end_getLog(::std::string& iceP_prefix, ::Ice::LogMessageSeq& ret, const ::Ice::AsyncResultPtr&); + /// \endcond + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getLog(const ::Ice::LogMessageTypeSeq&, const ::Ice::StringSeq&, ::Ice::Int, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace Ice +{ + +/** + * The Ice remote logger interface. An application can implement a + * RemoteLogger to receive the log messages sent to the local {@link Logger} + * of another Ice application. + * \headerfile Ice/Ice.h + */ +class ICE_API RemoteLogger : public virtual Object +{ +public: + + typedef RemoteLoggerPrx ProxyType; + typedef RemoteLoggerPtr PointerType; + + virtual ~RemoteLogger(); + +#ifdef ICE_CPP11_COMPILER + RemoteLogger() = default; + RemoteLogger(const RemoteLogger&) = default; + RemoteLogger& operator=(const RemoteLogger&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * init is called by attachRemoteLogger when a RemoteLogger proxy is attached. + * @param prefix The prefix of the associated local Logger. + * @param logMessages Old log messages generated before "now". + * @param current The Current object for the invocation. + */ + virtual void init(const ::std::string& prefix, const LogMessageSeq& logMessages, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_init(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Log a LogMessage. Note that log may be called by LoggerAdmin before init. + * @param message The message to log. + * @param current The Current object for the invocation. + */ + virtual void log(const LogMessage& message, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_log(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const RemoteLogger& lhs, const RemoteLogger& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const RemoteLogger& lhs, const RemoteLogger& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The interface of the admin object that allows an Ice application the attach its + * {@link RemoteLogger} to the {@link Logger} of this admin object's Ice communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API LoggerAdmin : public virtual Object +{ +public: + + typedef LoggerAdminPrx ProxyType; + typedef LoggerAdminPtr PointerType; + + virtual ~LoggerAdmin(); + +#ifdef ICE_CPP11_COMPILER + LoggerAdmin() = default; + LoggerAdmin(const LoggerAdmin&) = default; + LoggerAdmin& operator=(const LoggerAdmin&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Attaches a RemoteLogger object to the local logger. + * attachRemoteLogger calls init on the provided RemoteLogger proxy. + * @param prx A proxy to the remote logger. + * @param messageTypes The list of message types that the remote logger wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that the remote logger wishes to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be provided + * to init. A negative value requests all messages available. + * @param current The Current object for the invocation. + * @throws Ice::RemoteLoggerAlreadyAttachedException Raised if this remote logger is already + * attached to this admin object. + */ + virtual void attachRemoteLogger(const RemoteLoggerPrx& prx, const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, Int messageMax, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_attachRemoteLogger(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Detaches a RemoteLogger object from the local logger. + * @param prx A proxy to the remote logger. + * @param current The Current object for the invocation. + * @return True if the provided remote logger proxy was detached, and false otherwise. + */ + virtual bool detachRemoteLogger(const RemoteLoggerPrx& prx, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_detachRemoteLogger(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Retrieves log messages recently logged. + * @param messageTypes The list of message types that the caller wishes to receive. + * An empty list means no filtering (send all message types). + * @param traceCategories The categories of traces that caller wish to receive. + * This parameter is ignored if messageTypes is not empty and does not include trace. + * An empty list means no filtering (send all trace categories). + * @param messageMax The maximum number of log messages (of all types) to be returned. + * A negative value requests all messages available. + * @param prefix The prefix of the associated local logger. + * @param current The Current object for the invocation. + * @return The Log messages. + */ + virtual LogMessageSeq getLog(const LogMessageTypeSeq& messageTypes, const StringSeq& traceCategories, Int messageMax, ::std::string& prefix, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getLog(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const LoggerAdmin& lhs, const LoggerAdmin& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const LoggerAdmin& lhs, const LoggerAdmin& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::LogMessageType> +{ + static const StreamHelperCategory helper = StreamHelperCategoryEnum; + static const int minValue = 0; + static const int maxValue = 3; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +template<> +struct StreamableTraits< ::Ice::LogMessage> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 11; + static const bool fixedLength = false; +}; + +template +struct StreamWriter< ::Ice::LogMessage, S> +{ + static void write(S* ostr, const ::Ice::LogMessage& v) + { + ostr->write(v.type); + ostr->write(v.timestamp); + ostr->write(v.traceCategory); + ostr->write(v.message); + } +}; + +template +struct StreamReader< ::Ice::LogMessage, S> +{ + static void read(S* istr, ::Ice::LogMessage& v) + { + istr->read(v.type); + istr->read(v.timestamp); + istr->read(v.traceCategory); + istr->read(v.message); + } +}; + +template<> +struct StreamableTraits< ::Ice::RemoteLoggerAlreadyAttachedException> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; +}; + +} +/// \endcond + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::RemoteLogger::begin_init. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_init. + */ +template +class CallbackNC_RemoteLogger_init : public Callback_RemoteLogger_init_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_RemoteLogger_init(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_init(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_init(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_init(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_init(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::RemoteLogger::begin_init. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_init. + */ +template +class Callback_RemoteLogger_init : public Callback_RemoteLogger_init_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_RemoteLogger_init(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_init(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_init(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_init(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_init. + */ +template Callback_RemoteLogger_initPtr +newCallback_RemoteLogger_init(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_init(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::RemoteLogger::begin_log. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_log. + */ +template +class CallbackNC_RemoteLogger_log : public Callback_RemoteLogger_log_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_RemoteLogger_log(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_log(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_log(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_log(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RemoteLogger_log(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::RemoteLogger::begin_log. + * Create a wrapper instance by calling ::Ice::newCallback_RemoteLogger_log. + */ +template +class Callback_RemoteLogger_log : public Callback_RemoteLogger_log_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_RemoteLogger_log(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_log(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_log(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_log(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RemoteLogger::begin_log. + */ +template Callback_RemoteLogger_logPtr +newCallback_RemoteLogger_log(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RemoteLogger_log(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_attachRemoteLogger. + */ +template +class CallbackNC_LoggerAdmin_attachRemoteLogger : public Callback_LoggerAdmin_attachRemoteLogger_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LoggerAdmin_attachRemoteLogger(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_attachRemoteLogger(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_attachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_attachRemoteLogger(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_attachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_attachRemoteLogger(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_attachRemoteLogger. + */ +template +class Callback_LoggerAdmin_attachRemoteLogger : public Callback_LoggerAdmin_attachRemoteLogger_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LoggerAdmin_attachRemoteLogger(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + try + { + proxy->end_attachRemoteLogger(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_attachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_attachRemoteLogger(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_attachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_attachRemoteLogger. + */ +template Callback_LoggerAdmin_attachRemoteLoggerPtr +newCallback_LoggerAdmin_attachRemoteLogger(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_attachRemoteLogger(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_detachRemoteLogger. + */ +template +class CallbackNC_LoggerAdmin_detachRemoteLogger : public Callback_LoggerAdmin_detachRemoteLogger_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(bool); + + CallbackNC_LoggerAdmin_detachRemoteLogger(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + bool ret; + try + { + ret = proxy->end_detachRemoteLogger(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + */ +template Callback_LoggerAdmin_detachRemoteLoggerPtr +newCallback_LoggerAdmin_detachRemoteLogger(const IceUtil::Handle& instance, void (T::*cb)(bool), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_detachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + */ +template Callback_LoggerAdmin_detachRemoteLoggerPtr +newCallback_LoggerAdmin_detachRemoteLogger(T* instance, void (T::*cb)(bool), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_detachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_detachRemoteLogger. + */ +template +class Callback_LoggerAdmin_detachRemoteLogger : public Callback_LoggerAdmin_detachRemoteLogger_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(bool, const CT&); + + Callback_LoggerAdmin_detachRemoteLogger(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + bool ret; + try + { + ret = proxy->end_detachRemoteLogger(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + */ +template Callback_LoggerAdmin_detachRemoteLoggerPtr +newCallback_LoggerAdmin_detachRemoteLogger(const IceUtil::Handle& instance, void (T::*cb)(bool, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_detachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_detachRemoteLogger. + */ +template Callback_LoggerAdmin_detachRemoteLoggerPtr +newCallback_LoggerAdmin_detachRemoteLogger(T* instance, void (T::*cb)(bool, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_detachRemoteLogger(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::LoggerAdmin::begin_getLog. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_getLog. + */ +template +class CallbackNC_LoggerAdmin_getLog : public Callback_LoggerAdmin_getLog_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const LogMessageSeq&, const ::std::string&); + + CallbackNC_LoggerAdmin_getLog(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + ::std::string iceP_prefix; + LogMessageSeq ret; + try + { + ret = proxy->end_getLog(iceP_prefix, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret, iceP_prefix); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_getLog. + */ +template Callback_LoggerAdmin_getLogPtr +newCallback_LoggerAdmin_getLog(const IceUtil::Handle& instance, void (T::*cb)(const LogMessageSeq&, const ::std::string&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_getLog(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_getLog. + */ +template Callback_LoggerAdmin_getLogPtr +newCallback_LoggerAdmin_getLog(T* instance, void (T::*cb)(const LogMessageSeq&, const ::std::string&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LoggerAdmin_getLog(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::LoggerAdmin::begin_getLog. + * Create a wrapper instance by calling ::Ice::newCallback_LoggerAdmin_getLog. + */ +template +class Callback_LoggerAdmin_getLog : public Callback_LoggerAdmin_getLog_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const LogMessageSeq&, const ::std::string&, const CT&); + + Callback_LoggerAdmin_getLog(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + LoggerAdminPrx proxy = LoggerAdminPrx::uncheckedCast(result->getProxy()); + ::std::string iceP_prefix; + LogMessageSeq ret; + try + { + ret = proxy->end_getLog(iceP_prefix, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, iceP_prefix, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_getLog. + */ +template Callback_LoggerAdmin_getLogPtr +newCallback_LoggerAdmin_getLog(const IceUtil::Handle& instance, void (T::*cb)(const LogMessageSeq&, const ::std::string&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_getLog(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::LoggerAdmin::begin_getLog. + */ +template Callback_LoggerAdmin_getLogPtr +newCallback_LoggerAdmin_getLog(T* instance, void (T::*cb)(const LogMessageSeq&, const ::std::string&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LoggerAdmin_getLog(instance, cb, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ReplyStatus.h b/Sources/IceCpp/include/Ice/ReplyStatus.h new file mode 100644 index 0000000..8eeac4c --- /dev/null +++ b/Sources/IceCpp/include/Ice/ReplyStatus.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REPLY_STATUS_H +#define ICE_REPLY_STATUS_H + +#include + +namespace IceInternal +{ + +static const Ice::Byte replyOK = 0; +static const Ice::Byte replyUserException = 1; +static const Ice::Byte replyObjectNotExist = 2; +static const Ice::Byte replyFacetNotExist = 3; +static const Ice::Byte replyOperationNotExist = 4; +static const Ice::Byte replyUnknownLocalException = 5; +static const Ice::Byte replyUnknownUserException = 6; +static const Ice::Byte replyUnknownException = 7; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RequestHandler.h b/Sources/IceCpp/include/Ice/RequestHandler.h new file mode 100644 index 0000000..d446f0c --- /dev/null +++ b/Sources/IceCpp/include/Ice/RequestHandler.h @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REQUEST_HANDLER_H +#define ICE_REQUEST_HANDLER_H + +#include +#include + +#include +#include +#include +#include +#include + +namespace Ice +{ + +class LocalException; + +} + +namespace IceInternal +{ + +// +// An exception wrapper, which is used to notify that the request +// handler should be cleared and the invocation retried. +// +class RetryException +{ +public: + + RetryException(const Ice::LocalException&); + RetryException(const RetryException&); + + const Ice::LocalException* get() const; + +private: + + IceInternal::UniquePtr _ex; +}; + +class CancellationHandler +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + virtual void asyncRequestCanceled(const OutgoingAsyncBasePtr&, const Ice::LocalException&) = 0; +}; + +class RequestHandler : public CancellationHandler +{ +public: + + RequestHandler(const ReferencePtr&); + + virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&) = 0; + + virtual AsyncStatus sendAsyncRequest(const ProxyOutgoingAsyncBasePtr&) = 0; + + const ReferencePtr& getReference() const { return _reference; } // Inlined for performances. + + virtual Ice::ConnectionIPtr getConnection() = 0; + virtual Ice::ConnectionIPtr waitForConnection() = 0; + +protected: + + const ReferencePtr _reference; + const bool _response; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RequestHandlerF.h b/Sources/IceCpp/include/Ice/RequestHandlerF.h new file mode 100644 index 0000000..325f304 --- /dev/null +++ b/Sources/IceCpp/include/Ice/RequestHandlerF.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REQUEST_HANDLER_F_H +#define ICE_REQUEST_HANDLER_F_H + +#include +#include + +namespace IceInternal +{ + +class CancellationHandler; +class RequestHandler; + +#ifdef ICE_CPP11_MAPPING +using CancellationHandlerPtr = ::std::shared_ptr; +using RequestHandlerPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(CancellationHandler*); +typedef IceInternal::Handle CancellationHandlerPtr; + +ICE_API IceUtil::Shared* upCast(RequestHandler*); +typedef IceInternal::Handle RequestHandlerPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RequestHandlerFactory.h b/Sources/IceCpp/include/Ice/RequestHandlerFactory.h new file mode 100644 index 0000000..501666e --- /dev/null +++ b/Sources/IceCpp/include/Ice/RequestHandlerFactory.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_REQUEST_HANDLER_FACTORY_H +#define ICE_REQUEST_HANDLER_FACTORY_H + +#include +#include + +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class RequestHandlerFactory : public IceUtil::Shared, private IceUtil::Mutex +{ +public: + + RequestHandlerFactory(const InstancePtr&); + + RequestHandlerPtr getRequestHandler(const RoutableReferencePtr&, const Ice::ObjectPrxPtr&); + void removeRequestHandler(const ReferencePtr&, const RequestHandlerPtr&); + +private: + + const InstancePtr _instance; + std::map _handlers; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ResponseHandler.h b/Sources/IceCpp/include/Ice/ResponseHandler.h new file mode 100644 index 0000000..548cc72 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ResponseHandler.h @@ -0,0 +1,43 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_RESPONSE_HANDLER_H +#define ICE_RESPONSE_HANDLER_H + +#include +#include + +#include +#include +#include +#include + +namespace Ice +{ + +class OutputStream; + +} + +namespace IceInternal +{ + +class ResponseHandler : +#ifdef ICE_CPP11_MAPPING + public EnableSharedFromThis +#else + public virtual IceUtil::Shared +#endif +{ +public: + + virtual void sendResponse(Ice::Int, Ice::OutputStream*, Ice::Byte, bool) = 0; + virtual void sendNoResponse() = 0; + virtual bool systemException(Ice::Int, const Ice::SystemException&, bool) = 0; + virtual void invokeException(Ice::Int, const Ice::LocalException&, int, bool) = 0; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ResponseHandlerF.h b/Sources/IceCpp/include/Ice/ResponseHandlerF.h new file mode 100644 index 0000000..53e8650 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ResponseHandlerF.h @@ -0,0 +1,25 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_RESPONSE_HANDLER_F_H +#define ICE_RESPONSE_HANDLER_F_H + +#include +#include + +namespace IceInternal +{ + +class ResponseHandler; + +#ifdef ICE_CPP11_MAPPING +using ResponseHandlerPtr = ::std::shared_ptr; +#else +ICE_API IceUtil::Shared* upCast(ResponseHandler*); +typedef IceInternal::Handle ResponseHandlerPtr; +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RetryQueue.h b/Sources/IceCpp/include/Ice/RetryQueue.h new file mode 100644 index 0000000..5583f72 --- /dev/null +++ b/Sources/IceCpp/include/Ice/RetryQueue.h @@ -0,0 +1,66 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_RETRY_QUEUE_H +#define ICE_RETRY_QUEUE_H + +#include +#include +#include +#include +#include +#include +#include // For CancellationHandler + +namespace IceInternal +{ + +class RetryTask : public IceUtil::TimerTask, + public CancellationHandler +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + RetryTask(const InstancePtr&, const RetryQueuePtr&, const ProxyOutgoingAsyncBasePtr&); + + virtual void runTimerTask(); + + virtual void asyncRequestCanceled(const OutgoingAsyncBasePtr&, const Ice::LocalException&); + + void destroy(); + + bool operator<(const RetryTask&) const; + +private: + + const InstancePtr _instance; + const RetryQueuePtr _queue; + const ProxyOutgoingAsyncBasePtr _outAsync; +}; +ICE_DEFINE_PTR(RetryTaskPtr, RetryTask); + +class RetryQueue : public IceUtil::Shared, public IceUtil::Monitor +{ +public: + + RetryQueue(const InstancePtr&); + + void add(const ProxyOutgoingAsyncBasePtr&, int); + void destroy(); + +private: + + void remove(const RetryTaskPtr&); + bool cancel(const RetryTaskPtr&); + friend class RetryTask; + + InstancePtr _instance; + std::set _requests; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RetryQueueF.h b/Sources/IceCpp/include/Ice/RetryQueueF.h new file mode 100644 index 0000000..6639f13 --- /dev/null +++ b/Sources/IceCpp/include/Ice/RetryQueueF.h @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_RETRY_QUEUE_F_H +#define ICE_RETRY_QUEUE_F_H + +#include + +namespace IceInternal +{ + +class RetryQueue; +IceUtil::Shared* upCast(RetryQueue*); +typedef Handle RetryQueuePtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Router.h b/Sources/IceCpp/include/Ice/Router.h new file mode 100644 index 0000000..06212ed --- /dev/null +++ b/Sources/IceCpp/include/Ice/Router.h @@ -0,0 +1,1850 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Router.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Router_h__ +#define __Ice_Router_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Router; +class RouterPrx; +class RouterFinder; +class RouterFinderPrx; + +} + +namespace Ice +{ + +/** + * The Ice router interface. Routers can be set either globally with + * {@link Communicator#setDefaultRouter}, or with ice_router on specific + * proxies. + * \headerfile Ice/Ice.h + */ +class ICE_API Router : public virtual Object +{ +public: + + using ProxyType = RouterPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Encapsulates the results of a call to getClientProxy. + */ + struct GetClientProxyResult + { + /** The router's client proxy. */ + ::std::shared_ptr returnValue; + /** Indicates whether or not the router supports a routing table. */ + Ice::optional hasRoutingTable; + }; + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param hasRoutingTable Indicates whether or not the router supports a routing + * table. If it is supported, the Ice runtime will call addProxies to populate the + * routing table. This out parameter is only supported starting with Ice 3.7. + * The Ice runtime assumes the router has a routing table if the optional is not + * set. + * @param current The Current object for the invocation. + * @return The router's client proxy. + */ + virtual ::std::shared_ptr getClientProxy(Ice::optional& hasRoutingTable, const Current& current) const = 0; + /// \cond INTERNAL + bool _iceD_getClientProxy(::IceInternal::Incoming&, const Current&) const; + /// \endcond + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param current The Current object for the invocation. + * @return The router's server proxy. + */ + virtual ::std::shared_ptr getServerProxy(const Current& current) const = 0; + /// \cond INTERNAL + bool _iceD_getServerProxy(::IceInternal::Incoming&, const Current&) const; + /// \endcond + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param current The Current object for the invocation. + * @return Proxies discarded by the router. + */ + virtual ObjectProxySeq addProxies(ObjectProxySeq proxies, const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_addProxies(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +/** + * This inferface should be implemented by services implementing the + * Ice::Router interface. It should be advertised through an Ice + * object with the identity `Ice/RouterFinder'. This allows clients to + * retrieve the router proxy with just the endpoint information of the + * service. + * \headerfile Ice/Ice.h + */ +class ICE_API RouterFinder : public virtual Object +{ +public: + + using ProxyType = RouterFinderPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param current The Current object for the invocation. + * @return The router proxy. + */ + virtual ::std::shared_ptr getRouter(const Current& current) = 0; + /// \cond INTERNAL + bool _iceD_getRouter(::IceInternal::Incoming&, const Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&) override; + /// \endcond +}; + +} + +namespace Ice +{ + +/** + * The Ice router interface. Routers can be set either globally with + * {@link Communicator#setDefaultRouter}, or with ice_router on specific + * proxies. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RouterPrx : public virtual Proxy +{ +public: + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param hasRoutingTable Indicates whether or not the router supports a routing + * table. If it is supported, the Ice runtime will call addProxies to populate the + * routing table. This out parameter is only supported starting with Ice 3.7. + * The Ice runtime assumes the router has a routing table if the optional is not + * set. + * @param context The Context map to send with the invocation. + * @return The router's client proxy. + */ + ::std::shared_ptr getClientProxy(Ice::optional& hasRoutingTable, const Context& context = noExplicitContext) + { + auto _result = _makePromiseOutgoing(true, this, &RouterPrx::_iceI_getClientProxy, context).get(); + hasRoutingTable = _result.hasRoutingTable; + return ::std::move(_result.returnValue); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getClientProxyAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &RouterPrx::_iceI_getClientProxy, context); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getClientProxyAsync(::std::function, Ice::optional)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + auto _responseCb = [response](Router::GetClientProxyResult&& _result) + { + response(::std::move(_result.returnValue), _result.hasRoutingTable); + }; + return _makeLamdaOutgoing(std::move(_responseCb), std::move(ex), std::move(sent), this, &Ice::RouterPrx::_iceI_getClientProxy, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getClientProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const Context&); + /// \endcond + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @return The router's server proxy. + */ + ::std::shared_ptr getServerProxy(const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(true, this, &RouterPrx::_iceI_getServerProxy, context).get(); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getServerProxyAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::ObjectPrx>, P>(false, this, &RouterPrx::_iceI_getServerProxy, context); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getServerProxyAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::ObjectPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::RouterPrx::_iceI_getServerProxy, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getServerProxy(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::ObjectPrx>>>&, const Context&); + /// \endcond + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @return Proxies discarded by the router. + */ + ObjectProxySeq addProxies(const ObjectProxySeq& proxies, const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::Ice::ObjectProxySeq>(true, this, &RouterPrx::_iceI_addProxies, proxies, context).get(); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto addProxiesAsync(const ObjectProxySeq& proxies, const Context& context = noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing<::Ice::ObjectProxySeq, P>(false, this, &RouterPrx::_iceI_addProxies, proxies, context); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + addProxiesAsync(const ObjectProxySeq& proxies, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::Ice::ObjectProxySeq>(std::move(response), std::move(ex), std::move(sent), this, &Ice::RouterPrx::_iceI_addProxies, proxies, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_addProxies(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::Ice::ObjectProxySeq>>&, const ObjectProxySeq&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + RouterPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +/** + * This inferface should be implemented by services implementing the + * Ice::Router interface. It should be advertised through an Ice + * object with the identity `Ice/RouterFinder'. This allows clients to + * retrieve the router proxy with just the endpoint information of the + * service. + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) RouterFinderPrx : public virtual Proxy +{ +public: + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The router proxy. + */ + ::std::shared_ptr getRouter(const Context& context = noExplicitContext) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::RouterPrx>>(true, this, &RouterFinderPrx::_iceI_getRouter, context).get(); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto getRouterAsync(const Context& context = noExplicitContext) + -> decltype(::std::declval>>().get_future()) + { + return _makePromiseOutgoing<::std::shared_ptr<::Ice::RouterPrx>, P>(false, this, &RouterFinderPrx::_iceI_getRouter, context); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + getRouterAsync(::std::function)> response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const Context& context = noExplicitContext) + { + return _makeLamdaOutgoing<::std::shared_ptr<::Ice::RouterPrx>>(std::move(response), std::move(ex), std::move(sent), this, &Ice::RouterFinderPrx::_iceI_getRouter, context); + } + + /// \cond INTERNAL + ICE_MEMBER(ICE_API) void _iceI_getRouter(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::shared_ptr<::Ice::RouterPrx>>>&, const Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + RouterFinderPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + ICE_MEMBER(ICE_API) virtual ::std::shared_ptr _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using RouterPtr = ::std::shared_ptr; +using RouterPrxPtr = ::std::shared_ptr; + +using RouterFinderPtr = ::std::shared_ptr; +using RouterFinderPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class Router; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Router>&); +ICE_API ::IceProxy::Ice::Object* upCast(Router*); +/// \endcond + +class RouterFinder; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< RouterFinder>&); +ICE_API ::IceProxy::Ice::Object* upCast(RouterFinder*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Router; +/// \cond INTERNAL +ICE_API Object* upCast(Router*); +/// \endcond +typedef ::IceInternal::Handle< Router> RouterPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Router> RouterPrx; +typedef RouterPrx RouterPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(RouterPtr&, const ObjectPtr&); +/// \endcond + +class RouterFinder; +/// \cond INTERNAL +ICE_API Object* upCast(RouterFinder*); +/// \endcond +typedef ::IceInternal::Handle< RouterFinder> RouterFinderPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::RouterFinder> RouterFinderPrx; +typedef RouterFinderPrx RouterFinderPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(RouterFinderPtr&, const ObjectPtr&); +/// \endcond + +} + +namespace Ice +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Router::begin_getClientProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getClientProxy. + */ +class Callback_Router_getClientProxy_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Router_getClientProxy_Base> Callback_Router_getClientProxyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Router::begin_getServerProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getServerProxy. + */ +class Callback_Router_getServerProxy_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Router_getServerProxy_Base> Callback_Router_getServerProxyPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::Router::begin_addProxies. + * Create a wrapper instance by calling ::Ice::newCallback_Router_addProxies. + */ +class Callback_Router_addProxies_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Router_addProxies_Base> Callback_Router_addProxiesPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::Ice::RouterFinder::begin_getRouter. + * Create a wrapper instance by calling ::Ice::newCallback_RouterFinder_getRouter. + */ +class Callback_RouterFinder_getRouter_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_RouterFinder_getRouter_Base> Callback_RouterFinder_getRouterPtr; + +} + +namespace IceProxy +{ + +namespace Ice +{ + +class ICE_CLASS(ICE_API) Router : public virtual ::Ice::Proxy +{ +public: + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param hasRoutingTable Indicates whether or not the router supports a routing + * table. If it is supported, the Ice runtime will call addProxies to populate the + * routing table. This out parameter is only supported starting with Ice 3.7. + * The Ice runtime assumes the router has a routing table if the optional is not + * set. + * @param context The Context map to send with the invocation. + * @return The router's client proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx getClientProxy(IceUtil::Optional& hasRoutingTable, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getClientProxy(hasRoutingTable, _iceI_begin_getClientProxy(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getClientProxy(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getClientProxy(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getClientProxy(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getClientProxy(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getClientProxy(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getClientProxy(context, cb, cookie); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getClientProxy(const ::Ice::Callback_Router_getClientProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getClientProxy(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getClientProxy(const ::Ice::Context& context, const ::Ice::Callback_Router_getClientProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getClientProxy(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getClientProxy. + * @param hasRoutingTable Indicates whether or not the router supports a routing + * table. If it is supported, the Ice runtime will call addProxies to populate the + * routing table. This out parameter is only supported starting with Ice 3.7. + * The Ice runtime assumes the router has a routing table if the optional is not + * set. + * @param result The asynchronous result object for the invocation. + * @return The router's client proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx end_getClientProxy(IceUtil::Optional& hasRoutingTable, const ::Ice::AsyncResultPtr& result); + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) void _iceI_end_getClientProxy(IceUtil::Optional& iceP_hasRoutingTable, ::Ice::ObjectPrxPtr& ret, const ::Ice::AsyncResultPtr&); + /// \endcond + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getClientProxy(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @return The router's server proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx getServerProxy(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getServerProxy(_iceI_begin_getServerProxy(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getServerProxy(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getServerProxy(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getServerProxy(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getServerProxy(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getServerProxy(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getServerProxy(context, cb, cookie); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getServerProxy(const ::Ice::Callback_Router_getServerProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getServerProxy(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getServerProxy(const ::Ice::Context& context, const ::Ice::Callback_Router_getServerProxyPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getServerProxy(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getServerProxy. + * @param result The asynchronous result object for the invocation. + * @return The router's server proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectPrx end_getServerProxy(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getServerProxy(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @return Proxies discarded by the router. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectProxySeq addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_addProxies(_iceI_begin_addProxies(proxies, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_addProxies(proxies, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_addProxies(proxies, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_addProxies(proxies, context, cb, cookie); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::Callback_Router_addProxiesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_addProxies(proxies, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_addProxies(const ::Ice::ObjectProxySeq& proxies, const ::Ice::Context& context, const ::Ice::Callback_Router_addProxiesPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_addProxies(proxies, context, cb, cookie); + } + + /** + * Completes an invocation of begin_addProxies. + * @param result The asynchronous result object for the invocation. + * @return Proxies discarded by the router. + */ + ICE_MEMBER(ICE_API) ::Ice::ObjectProxySeq end_addProxies(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_addProxies(const ::Ice::ObjectProxySeq&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class ICE_CLASS(ICE_API) RouterFinder : public virtual ::Ice::Proxy +{ +public: + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The router proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::RouterPrx getRouter(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return end_getRouter(_iceI_begin_getRouter(context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRouter(const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_getRouter(context, ::IceInternal::dummyCallback, 0); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRouter(const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRouter(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRouter(const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRouter(context, cb, cookie); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRouter(const ::Ice::Callback_RouterFinder_getRouterPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRouter(::Ice::noExplicitContext, cb, cookie); + } + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_getRouter(const ::Ice::Context& context, const ::Ice::Callback_RouterFinder_getRouterPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_getRouter(context, cb, cookie); + } + + /** + * Completes an invocation of begin_getRouter. + * @param result The asynchronous result object for the invocation. + * @return The router proxy. + */ + ICE_MEMBER(ICE_API) ::Ice::RouterPrx end_getRouter(const ::Ice::AsyncResultPtr& result); + +private: + + ICE_MEMBER(ICE_API) ::Ice::AsyncResultPtr _iceI_begin_getRouter(const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + ICE_MEMBER(ICE_API) static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + ICE_MEMBER(ICE_API) virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace Ice +{ + +/** + * The Ice router interface. Routers can be set either globally with + * {@link Communicator#setDefaultRouter}, or with ice_router on specific + * proxies. + * \headerfile Ice/Ice.h + */ +class ICE_API Router : public virtual Object +{ +public: + + typedef RouterPrx ProxyType; + typedef RouterPtr PointerType; + + virtual ~Router(); + +#ifdef ICE_CPP11_COMPILER + Router() = default; + Router(const Router&) = default; + Router& operator=(const Router&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the router's client proxy, i.e., the proxy to use for + * forwarding requests from the client to the router. + * + * If a null proxy is returned, the client will forward requests + * to the router's endpoints. + * @param hasRoutingTable Indicates whether or not the router supports a routing + * table. If it is supported, the Ice runtime will call addProxies to populate the + * routing table. This out parameter is only supported starting with Ice 3.7. + * The Ice runtime assumes the router has a routing table if the optional is not + * set. + * @param current The Current object for the invocation. + * @return The router's client proxy. + */ + virtual ObjectPrx getClientProxy(IceUtil::Optional& hasRoutingTable, const Current& current = emptyCurrent) const = 0; + /// \cond INTERNAL + bool _iceD_getClientProxy(::IceInternal::Incoming&, const ::Ice::Current&) const; + /// \endcond + + /** + * Get the router's server proxy, i.e., the proxy to use for + * forwarding requests from the server to the router. + * @param current The Current object for the invocation. + * @return The router's server proxy. + */ + virtual ObjectPrx getServerProxy(const Current& current = emptyCurrent) const = 0; + /// \cond INTERNAL + bool _iceD_getServerProxy(::IceInternal::Incoming&, const ::Ice::Current&) const; + /// \endcond + + /** + * Add new proxy information to the router's routing table. + * @param proxies The proxies to add. + * @param current The Current object for the invocation. + * @return Proxies discarded by the router. + */ + virtual ObjectProxySeq addProxies(const ObjectProxySeq& proxies, const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_addProxies(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const Router& lhs, const Router& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Router& lhs, const Router& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * This inferface should be implemented by services implementing the + * Ice::Router interface. It should be advertised through an Ice + * object with the identity `Ice/RouterFinder'. This allows clients to + * retrieve the router proxy with just the endpoint information of the + * service. + * \headerfile Ice/Ice.h + */ +class ICE_API RouterFinder : public virtual Object +{ +public: + + typedef RouterFinderPrx ProxyType; + typedef RouterFinderPtr PointerType; + + virtual ~RouterFinder(); + +#ifdef ICE_CPP11_COMPILER + RouterFinder() = default; + RouterFinder(const RouterFinder&) = default; + RouterFinder& operator=(const RouterFinder&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const Current& current = emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const Current& current = emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const Current& current = emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Get the router proxy implemented by the process hosting this + * finder object. The proxy might point to several replicas. + * @param current The Current object for the invocation. + * @return The router proxy. + */ + virtual RouterPrx getRouter(const Current& current = emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_getRouter(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(OutputStream*) const; + virtual void _iceReadImpl(InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const RouterFinder& lhs, const RouterFinder& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const RouterFinder& lhs, const RouterFinder& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +namespace Ice +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Router::begin_getClientProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getClientProxy. + */ +template +class CallbackNC_Router_getClientProxy : public Callback_Router_getClientProxy_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ObjectPrx&, const IceUtil::Optional&); + + CallbackNC_Router_getClientProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + IceUtil::Optional iceP_hasRoutingTable; + ObjectPrx ret; + try + { + ret = proxy->end_getClientProxy(iceP_hasRoutingTable, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret, iceP_hasRoutingTable); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getClientProxy. + */ +template Callback_Router_getClientProxyPtr +newCallback_Router_getClientProxy(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&, const IceUtil::Optional&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_getClientProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getClientProxy. + */ +template Callback_Router_getClientProxyPtr +newCallback_Router_getClientProxy(T* instance, void (T::*cb)(const ObjectPrx&, const IceUtil::Optional&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_getClientProxy(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Router::begin_getClientProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getClientProxy. + */ +template +class Callback_Router_getClientProxy : public Callback_Router_getClientProxy_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ObjectPrx&, const IceUtil::Optional&, const CT&); + + Callback_Router_getClientProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + IceUtil::Optional iceP_hasRoutingTable; + ObjectPrx ret; + try + { + ret = proxy->end_getClientProxy(iceP_hasRoutingTable, result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, iceP_hasRoutingTable, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getClientProxy. + */ +template Callback_Router_getClientProxyPtr +newCallback_Router_getClientProxy(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&, const IceUtil::Optional&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_getClientProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getClientProxy. + */ +template Callback_Router_getClientProxyPtr +newCallback_Router_getClientProxy(T* instance, void (T::*cb)(const ObjectPrx&, const IceUtil::Optional&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_getClientProxy(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Router::begin_getServerProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getServerProxy. + */ +template +class CallbackNC_Router_getServerProxy : public Callback_Router_getServerProxy_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ObjectPrx&); + + CallbackNC_Router_getServerProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_getServerProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getServerProxy. + */ +template Callback_Router_getServerProxyPtr +newCallback_Router_getServerProxy(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_getServerProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getServerProxy. + */ +template Callback_Router_getServerProxyPtr +newCallback_Router_getServerProxy(T* instance, void (T::*cb)(const ObjectPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_getServerProxy(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Router::begin_getServerProxy. + * Create a wrapper instance by calling ::Ice::newCallback_Router_getServerProxy. + */ +template +class Callback_Router_getServerProxy : public Callback_Router_getServerProxy_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ObjectPrx&, const CT&); + + Callback_Router_getServerProxy(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + ObjectPrx ret; + try + { + ret = proxy->end_getServerProxy(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getServerProxy. + */ +template Callback_Router_getServerProxyPtr +newCallback_Router_getServerProxy(const IceUtil::Handle& instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_getServerProxy(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_getServerProxy. + */ +template Callback_Router_getServerProxyPtr +newCallback_Router_getServerProxy(T* instance, void (T::*cb)(const ObjectPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_getServerProxy(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::Router::begin_addProxies. + * Create a wrapper instance by calling ::Ice::newCallback_Router_addProxies. + */ +template +class CallbackNC_Router_addProxies : public Callback_Router_addProxies_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const ObjectProxySeq&); + + CallbackNC_Router_addProxies(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + ObjectProxySeq ret; + try + { + ret = proxy->end_addProxies(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_addProxies. + */ +template Callback_Router_addProxiesPtr +newCallback_Router_addProxies(const IceUtil::Handle& instance, void (T::*cb)(const ObjectProxySeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_addProxies(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_addProxies. + */ +template Callback_Router_addProxiesPtr +newCallback_Router_addProxies(T* instance, void (T::*cb)(const ObjectProxySeq&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Router_addProxies(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::Router::begin_addProxies. + * Create a wrapper instance by calling ::Ice::newCallback_Router_addProxies. + */ +template +class Callback_Router_addProxies : public Callback_Router_addProxies_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const ObjectProxySeq&, const CT&); + + Callback_Router_addProxies(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterPrx proxy = RouterPrx::uncheckedCast(result->getProxy()); + ObjectProxySeq ret; + try + { + ret = proxy->end_addProxies(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_addProxies. + */ +template Callback_Router_addProxiesPtr +newCallback_Router_addProxies(const IceUtil::Handle& instance, void (T::*cb)(const ObjectProxySeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_addProxies(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::Router::begin_addProxies. + */ +template Callback_Router_addProxiesPtr +newCallback_Router_addProxies(T* instance, void (T::*cb)(const ObjectProxySeq&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Router_addProxies(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::Ice::RouterFinder::begin_getRouter. + * Create a wrapper instance by calling ::Ice::newCallback_RouterFinder_getRouter. + */ +template +class CallbackNC_RouterFinder_getRouter : public Callback_RouterFinder_getRouter_Base, public ::IceInternal::TwowayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(const RouterPrx&); + + CallbackNC_RouterFinder_getRouter(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallbackNC(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterFinderPrx proxy = RouterFinderPrx::uncheckedCast(result->getProxy()); + RouterPrx ret; + try + { + ret = proxy->end_getRouter(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::CallbackNC::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::CallbackNC::_callback.get()->*_response)(ret); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RouterFinder::begin_getRouter. + */ +template Callback_RouterFinder_getRouterPtr +newCallback_RouterFinder_getRouter(const IceUtil::Handle& instance, void (T::*cb)(const RouterPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RouterFinder_getRouter(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RouterFinder::begin_getRouter. + */ +template Callback_RouterFinder_getRouterPtr +newCallback_RouterFinder_getRouter(T* instance, void (T::*cb)(const RouterPrx&), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_RouterFinder_getRouter(instance, cb, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::Ice::RouterFinder::begin_getRouter. + * Create a wrapper instance by calling ::Ice::newCallback_RouterFinder_getRouter. + */ +template +class Callback_RouterFinder_getRouter : public Callback_RouterFinder_getRouter_Base, public ::IceInternal::TwowayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const RouterPrx&, const CT&); + + Callback_RouterFinder_getRouter(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::TwowayCallback(obj, cb != 0, excb, sentcb), _response(cb) + { + } + + /// \cond INTERNAL + virtual void completed(const AsyncResultPtr& result) const + { + RouterFinderPrx proxy = RouterFinderPrx::uncheckedCast(result->getProxy()); + RouterPrx ret; + try + { + ret = proxy->end_getRouter(result); + } + catch(const ::Ice::Exception& ex) + { + ::IceInternal::Callback::exception(result, ex); + return; + } + if(_response) + { + (::IceInternal::Callback::_callback.get()->*_response)(ret, CT::dynamicCast(result->getCookie())); + } + } + /// \endcond + +private: + + Response _response; +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RouterFinder::begin_getRouter. + */ +template Callback_RouterFinder_getRouterPtr +newCallback_RouterFinder_getRouter(const IceUtil::Handle& instance, void (T::*cb)(const RouterPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RouterFinder_getRouter(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::Ice::RouterFinder::begin_getRouter. + */ +template Callback_RouterFinder_getRouterPtr +newCallback_RouterFinder_getRouter(T* instance, void (T::*cb)(const RouterPrx&, const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_RouterFinder_getRouter(instance, cb, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/RouterF.h b/Sources/IceCpp/include/Ice/RouterF.h new file mode 100644 index 0000000..e5c5709 --- /dev/null +++ b/Sources/IceCpp/include/Ice/RouterF.h @@ -0,0 +1,125 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `RouterF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_RouterF_h__ +#define __Ice_RouterF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class Router; +class RouterPrx; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using RouterPtr = ::std::shared_ptr; +using RouterPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace Ice +{ + +class Router; +/// \cond INTERNAL +ICE_API void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Router>&); +ICE_API ::IceProxy::Ice::Object* upCast(Router*); +/// \endcond + +} + +} + +namespace Ice +{ + +class Router; +/// \cond INTERNAL +ICE_API Object* upCast(Router*); +/// \endcond +typedef ::IceInternal::Handle< Router> RouterPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Router> RouterPrx; +typedef RouterPrx RouterPrxPtr; +/// \cond INTERNAL +ICE_API void _icePatchObjectPtr(RouterPtr&, const ObjectPtr&); +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/RouterInfo.h b/Sources/IceCpp/include/Ice/RouterInfo.h new file mode 100644 index 0000000..d4d41d7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/RouterInfo.h @@ -0,0 +1,152 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ROUTER_INFO_H +#define ICE_ROUTER_INFO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace IceInternal +{ + +class RouterManager : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + RouterManager(); + + void destroy(); + + // + // Returns router info for a given router. Automatically creates + // the router info if it doesn't exist yet. + // + RouterInfoPtr get(const Ice::RouterPrxPtr&); + RouterInfoPtr erase(const Ice::RouterPrxPtr&); + +private: + +#ifdef ICE_CPP11_MAPPING + using RouterInfoTable = std::map, + RouterInfoPtr, + Ice::TargetCompare, std::less>>; +#else + typedef std::map RouterInfoTable; +#endif + + RouterInfoTable _table; + RouterInfoTable::iterator _tableHint; +}; + +class RouterInfo : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + class GetClientEndpointsCallback : public virtual Ice::LocalObject + { + public: + + virtual void setEndpoints(const std::vector&) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle GetClientEndpointsCallbackPtr; + + class AddProxyCallback +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif + { + public: + + virtual void addedProxy() = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + ICE_DEFINE_PTR(AddProxyCallbackPtr, AddProxyCallback); + + RouterInfo(const Ice::RouterPrxPtr&); + + void destroy(); + + bool operator==(const RouterInfo&) const; + bool operator<(const RouterInfo&) const; + + const Ice::RouterPrxPtr& getRouter() const + { + // + // No mutex lock necessary, _router is immutable. + // + return _router; + } + void getClientProxyResponse(const Ice::ObjectPrxPtr&, const IceUtil::Optional&, + const GetClientEndpointsCallbackPtr&); + void getClientProxyException(const Ice::Exception&, const GetClientEndpointsCallbackPtr&); + std::vector getClientEndpoints(); + void getClientEndpoints(const GetClientEndpointsCallbackPtr&); + std::vector getServerEndpoints(); + + class AddProxyCookie : public Ice::LocalObject + { + public: + + AddProxyCookie(const AddProxyCallbackPtr cb, const Ice::ObjectPrxPtr& proxy) : + _cb(cb), + _proxy(proxy) + { + } + + AddProxyCallbackPtr cb() const + { + return _cb; + } + + Ice::ObjectPrxPtr proxy() const + { + return _proxy; + } + + private: + + const AddProxyCallbackPtr _cb; + const Ice::ObjectPrxPtr _proxy; + }; + typedef IceUtil::Handle AddProxyCookiePtr; + + void addProxyResponse(const Ice::ObjectProxySeq&, const AddProxyCookiePtr&); + void addProxyException(const Ice::Exception&, const AddProxyCookiePtr&); + bool addProxy(const Ice::ObjectPrxPtr&, const AddProxyCallbackPtr&); + + void setAdapter(const Ice::ObjectAdapterPtr&); + Ice::ObjectAdapterPtr getAdapter() const; + + void clearCache(const ReferencePtr&); + + // + // The following methods need to be public for access by AMI callbacks. + // + std::vector setClientEndpoints(const Ice::ObjectPrxPtr&, bool); + void addAndEvictProxies(const Ice::ObjectPrxPtr&, const Ice::ObjectProxySeq&); + +private: + + const Ice::RouterPrxPtr _router; + std::vector _clientEndpoints; + bool _hasRoutingTable; + Ice::ObjectAdapterPtr _adapter; + std::set _identities; + std::multiset _evictedIdentities; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/RouterInfoF.h b/Sources/IceCpp/include/Ice/RouterInfoF.h new file mode 100644 index 0000000..971a0fa --- /dev/null +++ b/Sources/IceCpp/include/Ice/RouterInfoF.h @@ -0,0 +1,25 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_ROUTER_INFO_F_H +#define ICE_ROUTER_INFO_F_H + +#include + +#include + +namespace IceInternal +{ + +class RouterManager; +IceUtil::Shared* upCast(RouterManager*); +typedef Handle RouterManagerPtr; + +class RouterInfo; +IceUtil::Shared* upCast(RouterInfo*); +typedef Handle RouterInfoPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SHA1.h b/Sources/IceCpp/include/Ice/SHA1.h new file mode 100644 index 0000000..9b4fe53 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SHA1.h @@ -0,0 +1,40 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SHA1_H +#define ICE_SHA1_H + +#include +#include + +#include + +namespace IceInternal +{ + +ICE_API void +sha1(const unsigned char*, std::size_t, std::vector&); + +class ICE_API SHA1 +{ +public: + + SHA1(); + ~SHA1(); + + void update(const unsigned char*, std::size_t); + void finalize(std::vector&); + +private: + + // noncopyable + SHA1(const SHA1&); + SHA1 operator=(const SHA1&); + + class Hasher; + UniquePtr _hasher; +}; + +} +#endif diff --git a/Sources/IceCpp/include/Ice/Selector.h b/Sources/IceCpp/include/Ice/Selector.h new file mode 100644 index 0000000..704fdfb --- /dev/null +++ b/Sources/IceCpp/include/Ice/Selector.h @@ -0,0 +1,292 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SELECTOR_H +#define ICE_SELECTOR_H + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(ICE_USE_EPOLL) +# include +#elif defined(ICE_USE_KQUEUE) +# include +#elif defined(ICE_USE_IOCP) +// Nothing to include +#elif defined(ICE_USE_POLL) +# include +#endif + +#if defined(ICE_USE_CFSTREAM) +# include +# include +# include + +struct __CFRunLoop; +typedef struct __CFRunLoop * CFRunLoopRef; + +struct __CFRunLoopSource; +typedef struct __CFRunLoopSource * CFRunLoopSourceRef; + +struct __CFSocket; +typedef struct __CFSocket * CFSocketRef; +#endif + +namespace IceInternal +{ + +// +// Exception raised if select times out. +// +class SelectorTimeoutException +{ +}; + +#if defined(ICE_USE_IOCP) + +class Selector +{ +public: + + Selector(const InstancePtr&); + ~Selector(); + +#ifdef ICE_USE_IOCP + void setup(int); +#endif + void destroy(); + + void initialize(EventHandler*); + void update(EventHandler*, SocketOperation, SocketOperation); + void finish(EventHandler*); + + void ready(EventHandler*, SocketOperation, bool); + +#ifdef ICE_USE_IOCP + EventHandler* getNextHandler(SocketOperation&, DWORD&, int&, int); +#else + EventHandler* getNextHandler(SocketOperation&, int); +#endif + + void completed(EventHandler*, SocketOperation); + +private: + + const InstancePtr _instance; +#ifdef ICE_USE_IOCP + HANDLE _handle; +#else + IceUtil::Monitor _monitor; + std::deque _events; +#endif +}; + +#elif defined(ICE_USE_KQUEUE) || defined(ICE_USE_EPOLL) || defined(ICE_USE_SELECT) || defined(ICE_USE_POLL) + +class Selector +{ +public: + + Selector(const InstancePtr&); + ~Selector(); + + void destroy(); + + void initialize(EventHandler*) + { + // Nothing to do + } + void update(EventHandler*, SocketOperation, SocketOperation); + void enable(EventHandler*, SocketOperation); + void disable(EventHandler*, SocketOperation); + bool finish(EventHandler*, bool); + + void ready(EventHandler*, SocketOperation, bool); + + void startSelect(); + void finishSelect(std::vector >&); + void select(int); + +private: + + void wakeup(); + void checkReady(EventHandler*); + void updateSelector(); + void updateSelectorForEventHandler(EventHandler*, SocketOperation, SocketOperation); + + const InstancePtr _instance; + + SOCKET _fdIntrRead; + SOCKET _fdIntrWrite; + bool _interrupted; + bool _selectNow; + int _count; + bool _selecting; + std::map _readyHandlers; + +#if defined(ICE_USE_EPOLL) + std::vector _events; + int _queueFd; +#elif defined(ICE_USE_KQUEUE) + std::vector _events; + std::vector _changes; + int _queueFd; +#elif defined(ICE_USE_SELECT) + std::vector > _changes; + std::map _handlers; + + fd_set _readFdSet; + fd_set _writeFdSet; + fd_set _errorFdSet; + fd_set _selectedReadFdSet; + fd_set _selectedWriteFdSet; + fd_set _selectedErrorFdSet; + + fd_set* + fdSetCopy(fd_set& dest, fd_set& src) + { + if(src.fd_count > 0) + { + dest.fd_count = src.fd_count; + memcpy(dest.fd_array, src.fd_array, sizeof(SOCKET) * src.fd_count); + return &dest; + } + return 0; + } +#elif defined(ICE_USE_POLL) + std::vector > _changes; + std::map _handlers; + std::vector _pollFdSet; +#endif +}; + +#elif defined(ICE_USE_CFSTREAM) + +class Selector; + +class SelectorReadyCallback : public IceUtil::Shared +{ +public: + + virtual ~SelectorReadyCallback() { } + virtual void readyCallback(SocketOperation, int = 0) = 0; +}; + +class StreamNativeInfo : public NativeInfo +{ +public: + + StreamNativeInfo(SOCKET fd) : NativeInfo(fd), _connectError(0) + { + } + + virtual void initStreams(SelectorReadyCallback*) = 0; + virtual SocketOperation registerWithRunLoop(SocketOperation) = 0; + virtual SocketOperation unregisterFromRunLoop(SocketOperation, bool) = 0; + virtual void closeStreams() = 0; + + void setConnectError(int error) + { + _connectError = error; + } + +private: + + int _connectError; +}; +typedef IceUtil::Handle StreamNativeInfoPtr; + +class EventHandlerWrapper : public SelectorReadyCallback +{ +public: + + EventHandlerWrapper(EventHandler*, Selector&); + ~EventHandlerWrapper(); + + void updateRunLoop(); + + virtual void readyCallback(SocketOperation, int = 0); + void ready(SocketOperation, int); + + SocketOperation readyOp(); + bool checkReady(); + + bool update(SocketOperation, SocketOperation); + bool finish(); + + bool operator<(const EventHandlerWrapper& o) + { + return this < &o; + } + +private: + + friend class Selector; + + EventHandlerPtr _handler; + StreamNativeInfoPtr _streamNativeInfo; + Selector& _selector; + SocketOperation _ready; + bool _finish; + IceInternal::UniqueRef _socket; + IceInternal::UniqueRef _source; +}; +typedef IceUtil::Handle EventHandlerWrapperPtr; + +class Selector : IceUtil::Monitor +{ + +public: + + Selector(const InstancePtr&); + virtual ~Selector(); + + void destroy(); + + void initialize(EventHandler*); + void update(EventHandler*, SocketOperation, SocketOperation); + void enable(EventHandler*, SocketOperation); + void disable(EventHandler*, SocketOperation); + bool finish(EventHandler*, bool); + + void ready(EventHandler*, SocketOperation, bool); + + void startSelect(); + void finishSelect(std::vector >&); + void select(int); + + void processInterrupt(); + void run(); + +private: + + void ready(EventHandlerWrapper*, SocketOperation, int = 0); + void addReadyHandler(EventHandlerWrapper*); + + friend class EventHandlerWrapper; + + InstancePtr _instance; + IceUtil::ThreadPtr _thread; + CFRunLoopRef _runLoop; + IceInternal::UniqueRef _source; + bool _destroyed; + + std::set _changes; + + std::set _readyHandlers; + std::vector > _selectedHandlers; + std::map _wrappers; +}; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ServantLocator.h b/Sources/IceCpp/include/Ice/ServantLocator.h new file mode 100644 index 0000000..3679b1a --- /dev/null +++ b/Sources/IceCpp/include/Ice/ServantLocator.h @@ -0,0 +1,305 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocator.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ServantLocator_h__ +#define __Ice_ServantLocator_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ServantLocator; + +} + +namespace Ice +{ + +/** + * A servant locator is called by an object adapter to + * locate a servant that is not found in its active servant map. + * @see ObjectAdapter + * @see ObjectAdapter#addServantLocator + * @see ObjectAdapter#findServantLocator + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ServantLocator +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ServantLocator(); + + /** + * Called before a request is dispatched if a + * servant cannot be found in the object adapter's active servant + * map. Note that the object adapter does not automatically insert + * the returned servant into its active servant map. This must be + * done by the servant locator implementation, if this is desired. + * + * locate can throw any user exception. If it does, that exception + * is marshaled back to the client. If the Slice definition for the + * corresponding operation includes that user exception, the client + * receives that user exception; otherwise, the client receives + * {@link UnknownUserException}. + * + * If locate throws any exception, the Ice run time does not + * call finished. + * + *

If you call locate from your own code, you + * must also call finished when you have finished using the + * servant, provided that locate returned a non-null servant; + * otherwise, you will get undefined behavior if you use + * servant locators such as the Freeze Evictor. + * @param curr Information about the current operation for which + * a servant is required. + * @param cookie A "cookie" that will be passed to finished. + * @return The located servant, or null if no suitable servant has + * been found. + * @throws UserException The implementation can raise a UserException + * and the run time will marshal it as the result of the invocation. + * @see ObjectAdapter + * @see Current + * @see #finished + */ + virtual ::std::shared_ptr<::Ice::Object> locate(const Current& curr, ::std::shared_ptr& cookie) = 0; + + /** + * Called by the object adapter after a request has been + * made. This operation is only called if locate was called + * prior to the request and returned a non-null servant. This + * operation can be used for cleanup purposes after a request. + * + * finished can throw any user exception. If it does, that exception + * is marshaled back to the client. If the Slice definition for the + * corresponding operation includes that user exception, the client + * receives that user exception; otherwise, the client receives + * {@link UnknownUserException}. + * + * If both the operation and finished throw an exception, the + * exception thrown by finished is marshaled back to the client. + * @param curr Information about the current operation call for + * which a servant was located by locate. + * @param servant The servant that was returned by locate. + * @param cookie The cookie that was returned by locate. + * @throws UserException The implementation can raise a UserException + * and the run time will marshal it as the result of the invocation. + * @see ObjectAdapter + * @see Current + * @see #locate + */ + virtual void finished(const Current& curr, const ::std::shared_ptr& servant, const ::std::shared_ptr& cookie) = 0; + + /** + * Called when the object adapter in which this servant locator is + * installed is destroyed. + * @param category Indicates for which category the servant locator + * is being deactivated. + * @see ObjectAdapter#destroy + * @see Communicator#shutdown + * @see Communicator#destroy + */ + virtual void deactivate(const ::std::string& category) = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ServantLocatorPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ServantLocator; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ServantLocator*); +/// \endcond +typedef ::IceInternal::Handle< ServantLocator> ServantLocatorPtr; + +} + +namespace Ice +{ + +/** + * A servant locator is called by an object adapter to + * locate a servant that is not found in its active servant map. + * @see ObjectAdapter + * @see ObjectAdapter#addServantLocator + * @see ObjectAdapter#findServantLocator + * \headerfile Ice/Ice.h + */ +class ICE_API ServantLocator : public virtual LocalObject +{ +public: + + typedef ServantLocatorPtr PointerType; + + virtual ~ServantLocator(); + +#ifdef ICE_CPP11_COMPILER + ServantLocator() = default; + ServantLocator(const ServantLocator&) = default; + ServantLocator& operator=(const ServantLocator&) = default; +#endif + + /** + * Called before a request is dispatched if a + * servant cannot be found in the object adapter's active servant + * map. Note that the object adapter does not automatically insert + * the returned servant into its active servant map. This must be + * done by the servant locator implementation, if this is desired. + * + * locate can throw any user exception. If it does, that exception + * is marshaled back to the client. If the Slice definition for the + * corresponding operation includes that user exception, the client + * receives that user exception; otherwise, the client receives + * {@link UnknownUserException}. + * + * If locate throws any exception, the Ice run time does not + * call finished. + * + *

If you call locate from your own code, you + * must also call finished when you have finished using the + * servant, provided that locate returned a non-null servant; + * otherwise, you will get undefined behavior if you use + * servant locators such as the Freeze Evictor. + * @param curr Information about the current operation for which + * a servant is required. + * @param cookie A "cookie" that will be passed to finished. + * @return The located servant, or null if no suitable servant has + * been found. + * @throws UserException The implementation can raise a UserException + * and the run time will marshal it as the result of the invocation. + * @see ObjectAdapter + * @see Current + * @see #finished + */ + virtual ObjectPtr locate(const Current& curr, LocalObjectPtr& cookie) = 0; + + /** + * Called by the object adapter after a request has been + * made. This operation is only called if locate was called + * prior to the request and returned a non-null servant. This + * operation can be used for cleanup purposes after a request. + * + * finished can throw any user exception. If it does, that exception + * is marshaled back to the client. If the Slice definition for the + * corresponding operation includes that user exception, the client + * receives that user exception; otherwise, the client receives + * {@link UnknownUserException}. + * + * If both the operation and finished throw an exception, the + * exception thrown by finished is marshaled back to the client. + * @param curr Information about the current operation call for + * which a servant was located by locate. + * @param servant The servant that was returned by locate. + * @param cookie The cookie that was returned by locate. + * @throws UserException The implementation can raise a UserException + * and the run time will marshal it as the result of the invocation. + * @see ObjectAdapter + * @see Current + * @see #locate + */ + virtual void finished(const Current& curr, const ObjectPtr& servant, const LocalObjectPtr& cookie) = 0; + + /** + * Called when the object adapter in which this servant locator is + * installed is destroyed. + * @param category Indicates for which category the servant locator + * is being deactivated. + * @see ObjectAdapter#destroy + * @see Communicator#shutdown + * @see Communicator#destroy + */ + virtual void deactivate(const ::std::string& category) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ServantLocator& lhs, const ServantLocator& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ServantLocator& lhs, const ServantLocator& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ServantLocatorF.h b/Sources/IceCpp/include/Ice/ServantLocatorF.h new file mode 100644 index 0000000..96c13b0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ServantLocatorF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ServantLocatorF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ServantLocatorF_h__ +#define __Ice_ServantLocatorF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ServantLocator; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ServantLocatorPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ServantLocator; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ServantLocator*); +/// \endcond +typedef ::IceInternal::Handle< ServantLocator> ServantLocatorPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ServantManager.h b/Sources/IceCpp/include/Ice/ServantManager.h new file mode 100644 index 0000000..e19d334 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ServantManager.h @@ -0,0 +1,69 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SERVANT_MANAGER_H +#define ICE_SERVANT_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include + +namespace Ice +{ + +class ObjectAdapterI; + +} + +namespace IceInternal +{ + +class ServantManager : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + void addServant(const Ice::ObjectPtr&, const Ice::Identity&, const std::string&); + void addDefaultServant(const Ice::ObjectPtr&, const std::string&); + Ice::ObjectPtr removeServant(const Ice::Identity&, const std::string&); + Ice::ObjectPtr removeDefaultServant(const std::string&); + Ice::FacetMap removeAllFacets(const Ice::Identity&); + Ice::ObjectPtr findServant(const Ice::Identity&, const std::string&) const; + Ice::ObjectPtr findDefaultServant(const std::string&) const; + Ice::FacetMap findAllFacets(const Ice::Identity&) const; + bool hasServant(const Ice::Identity&) const; + + void addServantLocator(const Ice::ServantLocatorPtr& locator, const std::string&); + Ice::ServantLocatorPtr removeServantLocator(const std::string&); + Ice::ServantLocatorPtr findServantLocator(const std::string&) const; + +private: + + ServantManager(const InstancePtr&, const std::string&); + ~ServantManager(); + void destroy(); + friend class Ice::ObjectAdapterI; + + InstancePtr _instance; + + const std::string _adapterName; + + typedef std::map ServantMapMap; + typedef std::map DefaultServantMap; + + ServantMapMap _servantMapMap; + mutable ServantMapMap::iterator _servantMapMapHint; + + DefaultServantMap _defaultServantMap; + + std::map _locatorMap; + mutable std::map::iterator _locatorMapHint; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ServantManagerF.h b/Sources/IceCpp/include/Ice/ServantManagerF.h new file mode 100644 index 0000000..0892c00 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ServantManagerF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SERVANT_MANAGER_F_H +#define ICE_SERVANT_MANAGER_F_H + +#include + +#include + +namespace IceInternal +{ + +class ServantManager; +ICE_API IceUtil::Shared* upCast(ServantManager*); +typedef Handle ServantManagerPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Service.h b/Sources/IceCpp/include/Ice/Service.h new file mode 100644 index 0000000..8196d29 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Service.h @@ -0,0 +1,379 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SERVICE_H +#define ICE_SERVICE_H + +#include +#include + +#ifdef _WIN32 +# include +#endif + +namespace Ice +{ + +/** + * A singleton class comparable to Ice::Application but also provides the low-level, platform-specific + * initialization and shutdown procedures common to system services. + * \headerfile Ice/Ice.h + */ +class ICE_API Service +{ +public: + + Service(); + virtual ~Service(); + + /** + * Shutdown the service. The default implementation invokes shutdown() + * on the communicator. + */ + virtual bool shutdown(); + + /** + * Notify the service about a signal interrupt. The default + * implementation invokes shutdown(). + */ + virtual void interrupt(); + + /** + * The primary entry point for services. This function examines + * the given argument vector for reserved options and takes the + * appropriate action. The reserved options are shown below. + * + * Win32: + * + * --service NAME + * + * Unix: + * + * --daemon [--nochdir] [--noclose] + * + * If --service or --daemon are specified, the program runs as + * a service, otherwise the program runs as a regular foreground + * process. Any service-specific (and Ice-specific) options + * are stripped from argv (just as for Ice::initialize()). + * + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status: EXIT_FAILURE or EXIT_SUCCESS. + */ + int main(int argc, const char* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +#ifdef _WIN32 + /** + * The primary entry point for services. This function examines + * the given argument vector for reserved options and takes the + * appropriate action. The reserved options are shown below. + * + * Win32: + * + * --service NAME + * + * Unix: + * + * --daemon [--nochdir] [--noclose] + * + * If --service or --daemon are specified, the program runs as + * a service, otherwise the program runs as a regular foreground + * process. Any service-specific (and Ice-specific) options + * are stripped from argv (just as for Ice::initialize()). + * + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status: EXIT_FAILURE or EXIT_SUCCESS. + */ + int main(int argc, const wchar_t* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); +#endif + + /** + * The primary entry point for services. This function examines + * the given argument vector for reserved options and takes the + * appropriate action. The reserved options are shown below. + * + * Win32: + * + * --service NAME + * + * Unix: + * + * --daemon [--nochdir] [--noclose] + * + * If --service or --daemon are specified, the program runs as + * a service, otherwise the program runs as a regular foreground + * process. Any service-specific (and Ice-specific) options + * are stripped from argv (just as for Ice::initialize()). + * + * @param args The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status: EXIT_FAILURE or EXIT_SUCCESS. + */ + int main(const StringSeq& args, const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + + /** + * Obtains the communicator created by the service. + * @return The service's communicator. + */ + Ice::CommunicatorPtr communicator() const; + + /** + * Obtains the Service singleton. + * @return A pointer to this service. + */ + static Service* instance(); + + /** + * Indicates whether the program is running as a Win32 service or Unix daemon. + * @return True if the program is running as a service, false otherwise. + */ + bool service() const; + + /** + * Obtains the program name. If the program is running as a Win32 + * service, the return value is the service name. Otherwise the + * return value is the executable name (i.e., argv[0]). + * @return The service name. + */ + std::string name() const; + + /** + * Determines whether the operating system supports running the + * program as a Win32 service or Unix daemon. + * @return True if the system supports services, false otherwise. + */ + bool checkSystem() const; + +#ifdef _WIN32 + /** + * Alternative entry point for services that use their own + * command-line options. Instead of invoking main(), the + * program processes its command-line options and invokes + * run(). To run as a Win32 service or Unix daemon, the + * program must first invoke configureService() or + * configureDaemon(), respectively. + * + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status: EXIT_FAILURE or EXIT_SUCCESS. + */ + int run(int argc, const wchar_t* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); +#endif + + /** + * Alternative entry point for services that use their own + * command-line options. Instead of invoking main(), the + * program processes its command-line options and invokes + * run(). To run as a Win32 service or Unix daemon, the + * program must first invoke configureService() or + * configureDaemon(), respectively. + * + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The application's exit status: EXIT_FAILURE or EXIT_SUCCESS. + */ + int run(int argc, const char* const argv[], const InitializationData& initData = InitializationData(), + int version = ICE_INT_VERSION); + +#ifdef _WIN32 + + /** + * Configures the program to run as a Win32 service with the given name. + * @param name The service name. + */ + void configureService(const std::string& name); + + /// \cond INTERNAL + static void setModuleHandle(HMODULE); + /// \endcond + +#else + + /** + * Configures the program to run as a Unix daemon. The first + * argument indicates whether the daemon should change its + * working directory to the root directory. The second + * argument indicates whether extraneous file descriptors are + * closed. If the value of the last argument is not an empty + * string, the daemon writes its process ID to the given + * filename. + * + * @param changeDirectory True if the daemon should change its working directory to the root directory, + * false otherwise. + * @param closeFiles True if the daemon should close unnecessary file descriptors (i.e., stdin, stdout, etc.), + * false otherwise. + * @param pidFile If a non-empty string is provided, the daemon writes its process ID to the given file. + */ + void configureDaemon(bool changeDirectory, bool closeFiles, const std::string& pidFile); + +#endif + + /** + * Invoked by the signal handler when it catches a signal. + * @param sig The signal that was caught. + */ + virtual void handleInterrupt(int sig); + +protected: + + /** + * Prepares a service for execution, including the creation and + * activation of object adapters and servants. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param status The exit status, which is returned by main + * @return True if startup was successful, false otherwise. + */ + virtual bool start(int argc, char* argv[], int& status) = 0; + + /** + * Blocks until the service shuts down. The default implementation + * invokes waitForShutdown() on the communicator. + */ + virtual void waitForShutdown(); + + /** + * Cleans up resources after shutting down. + */ + virtual bool stop(); + + /** + * Initializes a communicator. + * @param argc Specifies the number of arguments in argv. + * @param argv The command-line arguments. + * @param initData Configuration data for the new Communicator. + * @param version Indicates the Ice version with which the application is compatible. If not + * specified, the version of the Ice installation is used. + * @return The new communicator instance. + */ + virtual Ice::CommunicatorPtr initializeCommunicator(int& argc, char* argv[], const InitializationData& initData, + int version); + + /** + * Logs a system error, which includes a description of the + * current system error code. + * @param msg The log message. + */ + virtual void syserror(const std::string& msg); + + /** + * Logs an error. + * @param msg The log message. + */ + virtual void error(const std::string& msg); + + /** + * Logs a warning. + * @param msg The log message. + */ + virtual void warning(const std::string& msg); + + /** + * Logs trace information. + * @param msg The log message. + */ + virtual void trace(const std::string& msg); + + /** + * Logs a literal message. + * @param msg The log message. + */ + virtual void print(const std::string& msg); + + /** + * Enables the signal handler to invoke interrupt() when a signal occurs. + */ + void enableInterrupt(); + + /** + * Ignore signals. + */ + void disableInterrupt(); + + /** + * Logger utility class for a system error. + */ + typedef LoggerOutput ServiceSysError; + + /** + * Logger utility class for an error. + */ + typedef LoggerOutput ServiceError; + + /** + * Logger utility class for a warning. + */ + typedef LoggerOutput ServiceWarning; + + /** + * Logger utility class for a trace message. + */ + typedef LoggerOutput ServiceTrace; + + /** + * Logger utility class for a literal message. + */ + typedef LoggerOutput ServicePrint; + +private: + + Ice::LoggerPtr _logger; + Ice::CommunicatorPtr _communicator; + bool _nohup; + bool _service; + std::string _name; + + static Service* _instance; + +#ifdef _WIN32 + + int runService(int, const char* const[], const InitializationData&); + void terminateService(DWORD); + bool waitForServiceState(SC_HANDLE, DWORD, SERVICE_STATUS&); + void showServiceStatus(const std::string&, SERVICE_STATUS&); + + SERVICE_STATUS_HANDLE _statusHandle; + std::vector _serviceArgs; + InitializationData _initData; + +public: + + /// \cond INTERNAL + void serviceMain(int, const wchar_t* const[]); + void control(int); + /// \endcond + +#else + + int runDaemon(int, char*[], const InitializationData&, int); + + bool _changeDirectory; + bool _closeFiles; + std::string _pidFile; + +#endif +}; + +} // End of namespace Ice + +#endif diff --git a/Sources/IceCpp/include/Ice/SharedContext.h b/Sources/IceCpp/include/Ice/SharedContext.h new file mode 100644 index 0000000..caa9f20 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SharedContext.h @@ -0,0 +1,46 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SHARED_CONTEXT_H +#define ICE_SHARED_CONTEXT_H + +#include +#include +#include +#include + +namespace Ice +{ +typedef ::std::map< ::std::string, ::std::string> Context; +} + +namespace IceInternal +{ + +class SharedContext : public IceUtil::Shared +{ +public: + + SharedContext() + { + } + + SharedContext(const Ice::Context& val) : + _val(val) + { + } + + inline const Ice::Context& getValue() + { + return _val; + } + +private: + + Ice::Context _val; +}; +typedef IceUtil::Handle SharedContextPtr; +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SliceChecksumDict.h b/Sources/IceCpp/include/Ice/SliceChecksumDict.h new file mode 100644 index 0000000..6f36209 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SliceChecksumDict.h @@ -0,0 +1,84 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `SliceChecksumDict.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_SliceChecksumDict_h__ +#define __Ice_SliceChecksumDict_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * A mapping from type IDs to Slice checksums. The dictionary + * allows verification at run time that client and server + * use matching Slice definitions. + */ +using SliceChecksumDict = ::std::map<::std::string, ::std::string>; + +} + +#else // C++98 mapping + +namespace Ice +{ + +/** + * A mapping from type IDs to Slice checksums. The dictionary + * allows verification at run time that client and server + * use matching Slice definitions. + */ +typedef ::std::map< ::std::string, ::std::string> SliceChecksumDict; + +} + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/SliceChecksums.h b/Sources/IceCpp/include/Ice/SliceChecksums.h new file mode 100644 index 0000000..1f6a433 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SliceChecksums.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SLICE_CHECKSUM_H +#define ICE_SLICE_CHECKSUM_H + +#include + +namespace Ice +{ + +/** + * Obtains the map containing the checksums for Slice definitions. + * @return The checksum map. + */ +ICE_API SliceChecksumDict sliceChecksums(); + +} + +namespace IceInternal +{ + +class ICE_API SliceChecksumInit : private IceUtil::noncopyable +{ +public: + + SliceChecksumInit(const char*[]); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SlicedData.h b/Sources/IceCpp/include/Ice/SlicedData.h new file mode 100644 index 0000000..ee57acb --- /dev/null +++ b/Sources/IceCpp/include/Ice/SlicedData.h @@ -0,0 +1,172 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SLICED_DATA_H +#define ICE_SLICED_DATA_H + +#include +#include +#include + +namespace Ice +{ + +/** + * Encapsulates the details of a slice for an unknown class or exception type. + * \headerfile Ice/Ice.h + */ +struct ICE_API SliceInfo +#ifndef ICE_CPP11_MAPPING + : public ::IceUtil::Shared +#endif +{ + /** + * The Slice type ID for this slice. + */ + ::std::string typeId; + + /** + * The Slice compact type ID for this slice. + */ + int compactId; + + /** + * The encoded bytes for this slice, including the leading size integer. + */ + ::std::vector bytes; + + /** + * The class instances referenced by this slice. + */ + ::std::vector instances; + + /** + * Whether or not the slice contains optional members. + */ + bool hasOptionalMembers; + + /** + * Whether or not this is the last slice. + */ + bool isLastSlice; +}; + +/** + * Holds the slices of unknown types. + * \headerfile Ice/Ice.h + */ +class ICE_API SlicedData +#ifndef ICE_CPP11_MAPPING + : public ::IceUtil::Shared +#endif +{ +public: + +#ifndef ICE_CPP11_MAPPING + virtual ~SlicedData(); +#endif + + SlicedData(const SliceInfoSeq&); + + /** The slices of unknown types. */ + const SliceInfoSeq slices; + + /** + * Clears the slices to break potential cyclic references. + */ + void clear(); + +#ifndef ICE_CPP11_MAPPING + /// \cond INTERNAL + void _iceGcVisitMembers(IceInternal::GCVisitor&); + /// \endcond +#endif + +}; + +/** + * Represents an instance of an unknown type. + * \headerfile Ice/Ice.h + */ +class ICE_API UnknownSlicedValue : +#ifdef ICE_CPP11_MAPPING + public Value +#else + public IceInternal::GCObject +#endif +{ +public: + + /** + * Constructs the placeholder instance. + * @param unknownTypeId The Slice type ID of the unknown value. + */ + UnknownSlicedValue(const std::string& unknownTypeId); + +#ifdef ICE_CPP11_MAPPING + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the value has a preserved-slice base class and has been sliced during + * unmarshaling of the value, or nil otherwise. + */ + virtual SlicedDataPtr ice_getSlicedData() const override; + + /** + * Determine the Slice type ID associated with this instance. + * @return The type ID supplied to the constructor. + */ + virtual std::string ice_id() const override; + + /** + * Clones this object. + * @return A new instance. + */ + std::shared_ptr ice_clone() const; + + /// \cond STREAM + virtual void _iceWrite(::Ice::OutputStream*) const override; + virtual void _iceRead(::Ice::InputStream*) override; + /// \endcond + +protected: + + /// \cond INTERNAL + virtual std::shared_ptr _iceCloneImpl() const override; + /// \endcond + +#else + + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the value has a preserved-slice base class and has been sliced during + * unmarshaling of the value, or nil otherwise. + */ + virtual SlicedDataPtr ice_getSlicedData() const; + + /** + * Determine the Slice type ID associated with this instance. + * @param current The current object for this invocation. + * @return The type ID supplied to the constructor. + */ + virtual const std::string& ice_id(const Current& current = Ice::emptyCurrent) const; + + /// \cond INTERNAL + virtual void _iceGcVisitMembers(IceInternal::GCVisitor&); + /// \endcond + + /// \cond STREAM + virtual void _iceWrite(::Ice::OutputStream*) const; + virtual void _iceRead(::Ice::InputStream*); + /// \endcond +#endif + +private: + + const std::string _unknownTypeId; + SlicedDataPtr _slicedData; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SlicedDataF.h b/Sources/IceCpp/include/Ice/SlicedDataF.h new file mode 100644 index 0000000..83842a0 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SlicedDataF.h @@ -0,0 +1,40 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SLICED_DATA_F_H +#define ICE_SLICED_DATA_F_H + +#include +#include + +namespace Ice +{ + +struct SliceInfo; +class SlicedData; +class UnknownSlicedValue; + +#ifdef ICE_CPP11_MAPPING +/// \cond INTERNAL +using SliceInfoPtr = ::std::shared_ptr; +using SlicedDataPtr = ::std::shared_ptr; +using UnknownSlicedValuePtr = ::std::shared_ptr; +/// \endcond +#else +ICE_API IceUtil::Shared* upCast(SliceInfo*); +typedef IceInternal::Handle SliceInfoPtr; + +ICE_API IceUtil::Shared* upCast(SlicedData*); +typedef IceInternal::Handle SlicedDataPtr; + +ICE_API IceUtil::Shared* upCast(UnknownSlicedValue*); +typedef IceInternal::Handle UnknownSlicedValuePtr; +#endif + +/** The slices of unknown types. */ +typedef ::std::vector SliceInfoSeq; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/StreamHelpers.h b/Sources/IceCpp/include/Ice/StreamHelpers.h new file mode 100644 index 0000000..16292f9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/StreamHelpers.h @@ -0,0 +1,1190 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_HELPERS_H +#define ICE_STREAM_HELPERS_H + +#include + +#ifndef ICE_CPP11_MAPPING +# include +# include +#endif + +namespace Ice +{ + +/// \cond STREAM + +/** + * The stream helper category allows streams to select the desired StreamHelper for a given streamable object. + */ +typedef int StreamHelperCategory; + +/** For types with no specialized trait. */ +const StreamHelperCategory StreamHelperCategoryUnknown = 0; +/** For built-in types. */ +const StreamHelperCategory StreamHelperCategoryBuiltin = 1; +/** For struct types. */ +const StreamHelperCategory StreamHelperCategoryStruct = 2; +/** For struct types with cpp:class metadata. */ +const StreamHelperCategory StreamHelperCategoryStructClass = 3; +/** For enum types. */ +const StreamHelperCategory StreamHelperCategoryEnum = 4; +/** For sequence types. */ +const StreamHelperCategory StreamHelperCategorySequence = 5; +/** For dictionary types. */ +const StreamHelperCategory StreamHelperCategoryDictionary = 6; +/** For proxy types. */ +const StreamHelperCategory StreamHelperCategoryProxy = 7; +/** For class types. */ +const StreamHelperCategory StreamHelperCategoryClass = 8; +/** For exception types. */ +const StreamHelperCategory StreamHelperCategoryUserException = 9; + +/** + * The optional format. + * + * Optional data members and parameters are encoded with a specific + * optional format. This optional format describes how the data is encoded + * and how it can be skipped by the unmarshaling code if the optional ID + * isn't known to the receiver. + */ +#ifdef ICE_CPP11_MAPPING +enum class OptionalFormat : unsigned char +{ + /** Fixed 1-byte encoding. */ + F1 = 0, + /** Fixed 2-byte encoding. */ + F2 = 1, + /** Fixed 4-byte encoding. */ + F4 = 2, + /** Fixed 8-byte encoding. */ + F8 = 3, + /** "Size encoding" using 1 to 5 bytes, e.g., enum, class identifier. */ + Size = 4, + /** + * "Size encoding" using 1 to 5 bytes followed by data, e.g., string, fixed size + * struct, or containers whose size can be computed prior to marshaling. + */ + VSize = 5, + /** Fixed size using 4 bytes followed by data, e.g., variable-size struct, container. */ + FSize = 6, + /** Class instance. */ + Class = 7 +}; +#else +enum OptionalFormat +{ + /** Fixed 1-byte encoding. */ + OptionalFormatF1 = 0, + /** Fixed 2-byte encoding. */ + OptionalFormatF2 = 1, + /** Fixed 4-byte encoding. */ + OptionalFormatF4 = 2, + /** Fixed 8-byte encoding. */ + OptionalFormatF8 = 3, + /** "Size encoding" using 1 to 5 bytes, e.g., enum, class identifier. */ + OptionalFormatSize = 4, + /** + * "Size encoding" using 1 to 5 bytes followed by data, e.g., string, fixed size + * struct, or containers whose size can be computed prior to marshaling. + */ + OptionalFormatVSize = 5, + /** Fixed size using 4 bytes followed by data, e.g., variable-size struct, container. */ + OptionalFormatFSize = 6, + /** Class instance. */ + OptionalFormatClass = 7 +}; +#endif + +/** + * Determines whether the provided type is a container. For now, the implementation only checks + * if there is a T::iterator typedef using SFINAE. + * \headerfile Ice/Ice.h + */ +template +struct IsContainer +{ + template + static char test(typename C::iterator*); + + template + static long test(...); + + static const bool value = sizeof(test(0)) == sizeof(char); +}; + +/** + * Determines whether the provided type is a map. For now, the implementation only checks if there + * is a T::mapped_type typedef using SFINAE. + * \headerfile Ice/Ice.h + */ +template +struct IsMap +{ + template + static char test(typename C::mapped_type*); + + template + static long test(...); + + static const bool value = IsContainer::value && sizeof(test(0)) == sizeof(char); +}; + +#ifdef ICE_CPP11_MAPPING + +/** + * Base traits template. Types with no specialized trait use this trait. + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryUnknown; + + // + // When extracting a sequence from a stream, we can ensure the + // stream has at least StreamableTraits::minWireSize * size bytes + // For containers, the minWireSize is 1 (just 1 byte for an empty container). + // + //static const int minWireSize = 1; + + // + // Is this type encoded on a fixed number of bytes? + // Used only for marshaling/unmarshaling optional data members and parameters. + // + //static const bool fixedLength = false; +}; + +/** + * Specialization for sequence and dictionary types. + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits::value || IsContainer::value>::type> +{ + static const StreamHelperCategory helper = IsMap::value ? StreamHelperCategoryDictionary : StreamHelperCategorySequence; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +/** + * Specialization for exceptions. + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits::value>::type> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; + + // + // There is no sequence/dictionary of UserException (so no need for minWireSize) + // and no optional UserException (so no need for fixedLength) + // +}; + +/** + * Specialization for arrays (std::pair). + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits> +{ + static const StreamHelperCategory helper = StreamHelperCategorySequence; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +#else + +/** + * Base traits template. Types with no specialized trait use this trait, including sequence and + * dictionary types. + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits +{ + static const StreamHelperCategory helper = IsMap::value ? StreamHelperCategoryDictionary : + (IsContainer::value ? StreamHelperCategorySequence : StreamHelperCategoryUnknown); + + /** + * When extracting a sequence from a stream, we can ensure the + * stream has at least StreamableTraits::minWireSize * size bytes. + * For containers, the minWireSize is 1 (just 1 byte for an empty container). + */ + static const int minWireSize = 1; + + /** + * Is this type encoded on a fixed number of bytes? + * Used only for marshaling/unmarshaling optional data members and parameters. + */ + static const bool fixedLength = false; +}; + +/** + * Specialization for exceptions. + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; + + // + // There is no sequence/dictionary of UserException (so no need for minWireSize) + // and no optional UserException (so no need for fixedLength) + // +}; + +/** + * Specialization for array / range mapped sequences. The type can be a std::pair or a + * std::pair, std::pair >. + * \headerfile Ice/Ice.h + */ +template +struct StreamableTraits< ::std::pair > +{ + static const StreamHelperCategory helper = StreamHelperCategorySequence; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; +#endif + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 2; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 4; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 8; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 4; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 8; + static const bool fixedLength = true; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits< ::std::string> +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +/** + * Specialization for built-in type (this is needed for sequence + * marshaling to figure out the minWireSize of each type). + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits< ::std::wstring> +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +/** + * vector is a special type in C++: the streams handle it like a built-in type. + * \headerfile Ice/Ice.h + */ +template<> +struct StreamableTraits< ::std::vector > +{ + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; + +/** + * Specialization for proxy types. + * \headerfile Ice/Ice.h + */ +#ifdef ICE_CPP11_MAPPING +template +struct StreamableTraits<::std::shared_ptr, typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type> +{ + static const StreamHelperCategory helper = StreamHelperCategoryProxy; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; +#else +template +struct StreamableTraits< ::IceInternal::ProxyHandle > +{ + static const StreamHelperCategory helper = StreamHelperCategoryProxy; + static const int minWireSize = 2; + static const bool fixedLength = false; +}; +#endif + +/** + * Specialization for class types. + * \headerfile Ice/Ice.h + */ +#ifdef ICE_CPP11_MAPPING +template +struct StreamableTraits<::std::shared_ptr, typename ::std::enable_if<::std::is_base_of<::Ice::Value, T>::value>::type> +{ + static const StreamHelperCategory helper = StreamHelperCategoryClass; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; +#else +template +struct StreamableTraits< ::IceInternal::Handle > +{ + static const StreamHelperCategory helper = StreamHelperCategoryClass; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; +#endif + +// +// StreamHelper templates used by streams to read and write data. +// + +/** Base StreamHelper template; it must be specialized for each type. */ +template +struct StreamHelper; + +/** + * Helper for built-ins, delegates read/write to the stream. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->read(v); + } +}; + +// +// "helpers" for the StreamHelper below +// slice2cpp generates specializations as needed +// + +/** + * General writer. slice2cpp generates specializations as needed. + * \headerfile Ice/Ice.h + */ +template +struct StreamWriter +{ +#ifdef ICE_CPP11_MAPPING + static inline void write(S* stream, const T& v) + { + stream->writeAll(v.ice_tuple()); + } +#else + static inline void write(S*, const T&) + { + // Default is to write nothing for C++98 + } +#endif +}; + +/** + * General reader. slice2cpp generates specializations as needed. + * \headerfile Ice/Ice.h + */ +template +struct StreamReader +{ + static inline void read(S*, T&) + { + // Default is to read nothing + } +}; + +/** + * Helper for structs. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + StreamWriter::write(stream, v); + } + + template static inline void + read(S* stream, T& v) + { + StreamReader::read(stream, v); + } +}; + +/** + * Helper for class structs. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + StreamWriter::write(stream, v); + } + + template static inline void + read(S* stream, T& v) + { + v = new typename T::element_type; + StreamReader::read(stream, v); + } +}; + +/** + * Helper for enums. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + if(static_cast(v) < StreamableTraits::minValue || static_cast(v) > StreamableTraits::maxValue) + { + IceInternal::Ex::throwMarshalException(__FILE__, __LINE__, "enumerator out of range"); + } + stream->writeEnum(static_cast(v), StreamableTraits::maxValue); + } + + template static inline void + read(S* stream, T& v) + { + Int value = stream->readEnum(StreamableTraits::maxValue); + if(value < StreamableTraits::minValue || value > StreamableTraits::maxValue) + { + IceInternal::Ex::throwMarshalException(__FILE__, __LINE__, "enumerator out of range"); + } + v = static_cast(value); + } +}; + +/** + * Helper for sequences. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->writeSize(static_cast(v.size())); + for(typename T::const_iterator p = v.begin(); p != v.end(); ++p) + { + stream->write(*p); + } + } + + template static inline void + read(S* stream, T& v) + { + Int sz = stream->readAndCheckSeqSize(StreamableTraits::minWireSize); + T(static_cast(sz)).swap(v); + for(typename T::iterator p = v.begin(); p != v.end(); ++p) + { + stream->read(*p); + } + } +}; + +/** + * Helper for array custom sequence parameters. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper, StreamHelperCategorySequence> +{ + template static inline void + write(S* stream, const std::pair& v) + { + stream->write(v.first, v.second); + } + + template static inline void + read(S* stream, std::pair& v) + { + stream->read(v); + } +}; + +#ifndef ICE_CPP11_MAPPING + +/** + * Helper for range custom sequence parameters. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper, StreamHelperCategorySequence> +{ + template static inline void + write(S* stream, const std::pair& v) + { + stream->writeSize(static_cast(IceUtilInternal::distance(v.first, v.second))); + for(T p = v.first; p != v.second; ++p) + { + stream->write(*p); + } + } + + template static inline void + read(S* stream, std::pair& v) + { + stream->read(v); + } +}; + +/** + * Specialization for sequence. + * \headerfile Ice/Ice.h + */ +template<> +struct StreamHelper::const_iterator, + ::std::vector::const_iterator>, StreamHelperCategorySequence> +{ + template static inline void + write(S* stream, const std::pair< ::std::vector::const_iterator, + ::std::vector::const_iterator>& v) + { + stream->writeSize(static_cast(IceUtilInternal::distance(v.first, v.second))); + for(::std::vector::const_iterator p = v.first; p != v.second; ++p) + { + stream->write(static_cast(*p)); + } + } +}; + +/** + * Helper for zero-copy array sequence parameters. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper, std::pair >, StreamHelperCategorySequence> +{ + template static inline void + read(S* stream, std::pair, std::pair >& v) + { + stream->read(v.second, v.first); + } + + // no write: only used for unmarshaling +}; +#endif + +/** + * Helper for dictionaries. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->writeSize(static_cast(v.size())); + for(typename T::const_iterator p = v.begin(); p != v.end(); ++p) + { + stream->write(p->first); + stream->write(p->second); + } + } + + template static inline void + read(S* stream, T& v) + { + Int sz = stream->readSize(); + v.clear(); + while(sz--) + { + typename T::value_type p; + stream->read(const_cast(p.first)); + typename T::iterator i = v.insert(v.end(), p); + stream->read(i->second); + } + } +}; + +/** + * Helper for user exceptions. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->writeException(v); + } + + // no read: only used for marshaling +}; + +/** + * Helper for proxies. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->read(v); + } +}; + +/** + * Helper for classes. + * \headerfile Ice/Ice.h + */ +template +struct StreamHelper +{ + template static inline void + write(S* stream, const T& v) + { + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->read(v); + } +}; + +// +// Helpers to read/write optional attributes or members. +// + +// +// Extract / compute the optionalFormat +// This is used _only_ for the base StreamOptionalHelper below +// /!\ Do not use in StreamOptionalHelper specializations, and do +// not provide specialization not handled by the base StreamOptionalHelper +// +/** + * Extract / compute the optionalFormat. + * \headerfile Ice/Ice.h + */ +template +struct GetOptionalFormat; + +/** + * Specialization for 1-byte built-in fixed-length types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, F1); +}; + +/** + * Specialization for 2-byte built-in fixed-length types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, F2); +}; + +/** + * Specialization for 4-byte built-in fixed-length types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, F4); +}; + +/** + * Specialization for 8-byte built-in fixed-length types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, F8); +}; + +/** + * Specialization for built-in variable-length types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, VSize); +}; + +/** + * Specialization for class types. + * \headerfile Ice/Ice.h + */ +template<> +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, Class); +}; + +/** + * Specialization for enum types. + * \headerfile Ice/Ice.h + */ +template +struct GetOptionalFormat +{ + static const OptionalFormat value = ICE_SCOPED_ENUM(OptionalFormat, Size); +}; + +/** + * Base helper for optional values: simply read/write the data. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper +{ + typedef StreamableTraits Traits; + + // If this optionalFormat fails to compile, you must either define your specialization + // for GetOptionalFormat (in which case the optional data will be marshaled/unmarshaled + // with straight calls to write/read on the stream), or define your own + // StreamOptionalHelper specialization (which gives you more control over marshaling) + // + static const OptionalFormat optionalFormat = GetOptionalFormat::value; + + template static inline void + write(S* stream, const T& v) + { + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->read(v); + } +}; + +/** + * Helper to write fixed-size structs. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper +{ + static const OptionalFormat optionalFormat = ICE_SCOPED_ENUM(OptionalFormat, VSize); + + template static inline void + write(S* stream, const T& v) + { + stream->writeSize(StreamableTraits::minWireSize); + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->skipSize(); + stream->read(v); + } +}; + +/** + * Helper to write variable-size structs. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper +{ + static const OptionalFormat optionalFormat = ICE_SCOPED_ENUM(OptionalFormat, FSize); + + template static inline void + write(S* stream, const T& v) + { + typename S::size_type pos = stream->startSize(); + stream->write(v); + stream->endSize(pos); + } + + template static inline void + read(S* stream, T& v) + { + stream->skip(4); + stream->read(v); + } +}; + +/** + * Class structs are encoded like structs. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper : StreamOptionalHelper +{ +}; + +/** + * Optional proxies are encoded like variable size structs, using the FSize encoding. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper : StreamOptionalHelper +{ +}; + +/** + * Helper to read/write optional sequences or dictionaries. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalContainerHelper; + +/** + * Encode containers of variable-size elements with the FSize optional + * type, since we can't easily figure out the size of the container + * before encoding. This is the same encoding as variable size structs + * so we just re-use its implementation. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalContainerHelper +{ + static const OptionalFormat optionalFormat = ICE_SCOPED_ENUM(OptionalFormat, FSize); + + template static inline void + write(S* stream, const T& v, Int) + { + StreamOptionalHelper::write(stream, v); + } + + template static inline void + read(S* stream, T& v) + { + StreamOptionalHelper::read(stream, v); + } +}; + +/** + * Encode containers of fixed-size elements with the VSize optional + * type since we can figure out the size of the container before + * encoding. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalContainerHelper +{ + static const OptionalFormat optionalFormat = ICE_SCOPED_ENUM(OptionalFormat, VSize); + + template static inline void + write(S* stream, const T& v, Int n) + { + // + // The container size is the number of elements * the size of + // an element and the size-encoded number of elements (1 or + // 5 depending on the number of elements). + // + stream->writeSize(sz * n + (n < 255 ? 1 : 5)); + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->skipSize(); + stream->read(v); + } +}; + +/** + * Optimization: containers of 1 byte elements are encoded with the + * VSize optional type. There's no need to encode an additional size + * for those, the number of elements of the container can be used to + * skip the optional. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalContainerHelper +{ + static const OptionalFormat optionalFormat = ICE_SCOPED_ENUM(OptionalFormat, VSize); + + template static inline void + write(S* stream, const T& v, Int) + { + stream->write(v); + } + + template static inline void + read(S* stream, T& v) + { + stream->read(v); + } +}; + +/** + * Helper to write sequences, delegates to the optional container + * helper template partial specializations. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper +{ + typedef typename T::value_type E; + static const int size = StreamableTraits::minWireSize; + static const bool fixedLength = StreamableTraits::fixedLength; + + // The optional type of a sequence depends on whether or not elements are fixed + // or variable size elements and their size. + static const OptionalFormat optionalFormat = StreamOptionalContainerHelper::optionalFormat; + + template static inline void + write(S* stream, const T& v) + { + StreamOptionalContainerHelper::write(stream, v, static_cast(v.size())); + } + + template static inline void + read(S* stream, T& v) + { + StreamOptionalContainerHelper::read(stream, v); + } +}; + +/** + * Helper to write sequences, delegates to the optional container + * helper template partial specializations. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper, StreamHelperCategorySequence, false> +{ + typedef std::pair P; + static const int size = StreamableTraits::minWireSize; + static const bool fixedLength = StreamableTraits::fixedLength; + + // The optional type of a sequence depends on whether or not elements are fixed + // or variable size elements and their size. + static const OptionalFormat optionalFormat = StreamOptionalContainerHelper::optionalFormat; + + template static inline void + write(S* stream, const P& v) + { + Int n = static_cast(v.second - v.first); + StreamOptionalContainerHelper::write(stream, v, n); + } + + template static inline void + read(S* stream, P& v) + { + StreamOptionalContainerHelper::read(stream, v); + } +}; + +#ifndef ICE_CPP11_MAPPING + +/** + * Helper to write sequences, delegates to the optional container + * helper template partial specializations. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper, StreamHelperCategorySequence, false> +{ + typedef std::pair P; + static const int size = StreamableTraits::minWireSize; + static const bool fixedLength = StreamableTraits::fixedLength; + + // The optional type of a sequence depends on whether or not elements are fixed + // or variable size elements and their size. + static const OptionalFormat optionalFormat = StreamOptionalContainerHelper::optionalFormat; + + template static inline void + write(S* stream, const P& v) + { + Int n = static_cast(v.second - v.first); + StreamOptionalContainerHelper::write(stream, v, n); + } + + template static inline void + read(S* stream, P& v) + { + StreamOptionalContainerHelper::read(stream, v); + } +}; + +/** + * Helper to write sequences, delegates to the optional container + * helper template partial specializations. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper, std::pair >, + StreamHelperCategorySequence, false> +{ + typedef std::pair, std::pair > P; + static const int size = StreamableTraits::minWireSize; + static const bool fixedLength = StreamableTraits::fixedLength; + + // The optional type of a sequence depends on whether or not elements are fixed + // or variable size elements and their size. + static const OptionalFormat optionalFormat = StreamOptionalContainerHelper::optionalFormat; + + template static inline void + read(S* stream, P& v) + { + StreamOptionalContainerHelper::read(stream, v); + } + + // no write: only used for unmarshaling +}; +#endif + +/** + * Helper to write dictionaries, delegates to the optional container + * helper template partial specializations. + * \headerfile Ice/Ice.h + */ +template +struct StreamOptionalHelper +{ + typedef typename T::key_type K; + typedef typename T::mapped_type V; + + static const int size = StreamableTraits::minWireSize + StreamableTraits::minWireSize; + static const bool fixedLength = StreamableTraits::fixedLength && StreamableTraits::fixedLength; + + // The optional type of a dictionary depends on whether or not elements are fixed + // or variable size elements. + static const OptionalFormat optionalFormat = StreamOptionalContainerHelper::optionalFormat; + + template static inline void + write(S* stream, const T& v) + { + StreamOptionalContainerHelper::write(stream, v, static_cast(v.size())); + } + + template static inline void + read(S* stream, T& v) + { + StreamOptionalContainerHelper::read(stream, v); + } +}; + +/// \endcond + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/StreamSocket.h b/Sources/IceCpp/include/Ice/StreamSocket.h new file mode 100644 index 0000000..6eb17bf --- /dev/null +++ b/Sources/IceCpp/include/Ice/StreamSocket.h @@ -0,0 +1,85 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STREAM_SOCKET_H +#define ICE_STREAM_SOCKET_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class ICE_API StreamSocket : public NativeInfo +{ +public: + + StreamSocket(const ProtocolInstancePtr&, const NetworkProxyPtr&, const Address&, const Address&); + StreamSocket(const ProtocolInstancePtr&, SOCKET); + virtual ~StreamSocket(); + + SocketOperation connect(Buffer&, Buffer&); + bool isConnected(); + size_t getSendPacketSize(size_t); + size_t getRecvPacketSize(size_t); + + void setBufferSize(int rcvSize, int sndSize); + + SocketOperation read(Buffer&); + SocketOperation write(Buffer&); + + ssize_t read(char*, size_t); + ssize_t write(const char*, size_t); + +#if defined(ICE_USE_IOCP) + AsyncInfo* getAsyncInfo(SocketOperation); +#endif + +#if defined(ICE_USE_IOCP) + bool startWrite(Buffer&); + void finishWrite(Buffer&); + void startRead(Buffer&); + void finishRead(Buffer&); +#endif + + void close(); + const std::string& toString() const; + +private: + + void init(); + + enum State + { + StateNeedConnect, + StateConnectPending, + StateProxyWrite, + StateProxyRead, + StateProxyConnected, + StateConnected + }; + State toState(SocketOperation) const; + + const ProtocolInstancePtr _instance; + const NetworkProxyPtr _proxy; + const Address _addr; + const Address _sourceAddr; + + State _state; + std::string _desc; + +#if defined(ICE_USE_IOCP) + size_t _maxSendPacketSize; + size_t _maxRecvPacketSize; + AsyncInfo _read; + AsyncInfo _write; +#endif +}; +typedef IceUtil::Handle StreamSocketPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/StringConverter.h b/Sources/IceCpp/include/Ice/StringConverter.h new file mode 100644 index 0000000..025063c --- /dev/null +++ b/Sources/IceCpp/include/Ice/StringConverter.h @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STRING_CONVERTER_H +#define ICE_STRING_CONVERTER_H + +#include +#include +#include + +namespace Ice +{ + +/** Encapsulates bytes in the UTF-8 encoding. */ +typedef IceUtil::UTF8Buffer UTF8Buffer; + +/** Narrow string converter. */ +typedef IceUtil::StringConverter StringConverter; +typedef IceUtil::StringConverterPtr StringConverterPtr; + +/** Wide string converter. */ +typedef IceUtil::WstringConverter WstringConverter; +typedef IceUtil::WstringConverterPtr WstringConverterPtr; + +/** Indicates an error occurred during string conversion. */ +typedef IceUtil::IllegalConversionException IllegalConversionException; + +#ifdef ICE_CPP11_MAPPING +/** Base class for a string converter. */ +template +using BasicStringConverter = IceUtil::BasicStringConverter; +#endif + +#ifdef _WIN32 +/** + * Creates a string converter that converts between multi-byte and UTF-8 strings and uses MultiByteToWideChar + * and WideCharToMultiByte for its implementation. + */ +using IceUtil::createWindowsStringConverter; +#endif + +/** Creates a string converter that converts between Unicode wide strings and UTF-8 strings. */ +using IceUtil::createUnicodeWstringConverter; + +/** Installs a default narrow string converter for the process. */ +using IceUtil::setProcessStringConverter; + +/** Obtains the default narrow string converter for the process. */ +using IceUtil::getProcessStringConverter; + +/** Installs a default wide string converter for the process. */ +using IceUtil::setProcessWstringConverter; + +/** Obtains the default wide string converter for the process. */ +using IceUtil::getProcessWstringConverter; + +/** Converts a wide string to a narrow string. */ +using IceUtil::wstringToString; + +/** Converts a narrow string to a wide string. */ +using IceUtil::stringToWstring; + +/** + * Converts a narrow string to a UTF-8 encoded string using a string converter. + * No conversion is performed if the string converter is nil. + */ +using IceUtil::nativeToUTF8; + +/** + * Converts a UTF-8 encoded string to a narrow string using a string converter. + * No conversion is performed if the string converter is nil. + */ +using IceUtil::UTF8ToNative; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/StringUtil.h b/Sources/IceCpp/include/Ice/StringUtil.h new file mode 100644 index 0000000..81b9878 --- /dev/null +++ b/Sources/IceCpp/include/Ice/StringUtil.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_STRING_UTIL_H +#define ICE_STRING_UTIL_H + +#include +#include + +namespace IceInternal +{ + +// +// Adapter for ToStringMode +// +inline std::string +escapeString(const std::string& s, const std::string& special, Ice::ToStringMode mode) +{ + return IceUtilInternal::escapeString(s, special, static_cast(mode)); +} + +// +// Provided for consistency with escapeString +// +using IceUtilInternal::unescapeString; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SysLoggerI.h b/Sources/IceCpp/include/Ice/SysLoggerI.h new file mode 100644 index 0000000..1495ae6 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SysLoggerI.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SYS_LOGGER_I_H +#define ICE_SYS_LOGGER_I_H + +#include +#include + +namespace Ice +{ + +class SysLoggerI : public Logger, public ::IceUtil::Mutex +{ +public: + + SysLoggerI(const std::string&, const std::string&); + SysLoggerI(const std::string&, int); + ~SysLoggerI(); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual LoggerPtr cloneWithPrefix(const std::string&); + +private: + + int _facility; + const std::string _prefix; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/SystemdJournalI.h b/Sources/IceCpp/include/Ice/SystemdJournalI.h new file mode 100644 index 0000000..cd0b171 --- /dev/null +++ b/Sources/IceCpp/include/Ice/SystemdJournalI.h @@ -0,0 +1,39 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_SYSTEMD_JOURNAL_I_H +#define ICE_SYSTEMD_JOURNAL_I_H + +#ifdef ICE_USE_SYSTEMD + +#include + +namespace Ice +{ + +class SystemdJournalI : public Logger +{ +public: + + SystemdJournalI(const std::string&); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual LoggerPtr cloneWithPrefix(const std::string&); + +private: + + void write(int, const std::string&) const; + + const std::string _prefix; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/TcpAcceptor.h b/Sources/IceCpp/include/Ice/TcpAcceptor.h new file mode 100644 index 0000000..66b9594 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TcpAcceptor.h @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TCP_ACCEPTOR_H +#define ICE_TCP_ACCEPTOR_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class TcpEndpoint; + +class TcpAcceptor : public Acceptor, public NativeInfo +{ +public: + + virtual NativeInfoPtr getNativeInfo(); +#if defined(ICE_USE_IOCP) + virtual AsyncInfo* getAsyncInfo(SocketOperation); +#endif + + virtual void close(); + virtual EndpointIPtr listen(); +#if defined(ICE_USE_IOCP) + virtual void startAccept(); + virtual void finishAccept(); +#endif + + virtual TransceiverPtr accept(); + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + + int effectivePort() const; + +private: + + TcpAcceptor(const TcpEndpointIPtr&, const ProtocolInstancePtr&, const std::string&, int); + virtual ~TcpAcceptor(); + friend class TcpEndpointI; + + TcpEndpointIPtr _endpoint; + const ProtocolInstancePtr _instance; + const Address _addr; + + int _backlog; +#if defined(ICE_USE_IOCP) + SOCKET _acceptFd; + int _acceptError; + std::vector _acceptBuf; + AsyncInfo _info; +#endif +}; + +} +#endif diff --git a/Sources/IceCpp/include/Ice/TcpConnector.h b/Sources/IceCpp/include/Ice/TcpConnector.h new file mode 100644 index 0000000..e7726f9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TcpConnector.h @@ -0,0 +1,45 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TCP_CONNECTOR_H +#define ICE_TCP_CONNECTOR_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class TcpConnector : public Connector +{ +public: + + virtual TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const Connector&) const; + virtual bool operator<(const Connector&) const; + +private: + + TcpConnector(const ProtocolInstancePtr&, const Address&, const NetworkProxyPtr&, const Address&, Ice::Int, + const std::string&); + virtual ~TcpConnector(); + friend class TcpEndpointI; + + const ProtocolInstancePtr _instance; + const Address _addr; + const NetworkProxyPtr _proxy; + const Address _sourceAddr; + const Ice::Int _timeout; + const std::string _connectionId; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TcpEndpointI.h b/Sources/IceCpp/include/Ice/TcpEndpointI.h new file mode 100644 index 0000000..9a08df6 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TcpEndpointI.h @@ -0,0 +1,90 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TCP_ENDPOINT_I_H +#define ICE_TCP_ENDPOINT_I_H + +#include +#include +#include +#include // for IceIternal::Address + +namespace IceInternal +{ + +class TcpEndpointI : public IPEndpointI +{ +public: + + TcpEndpointI(const ProtocolInstancePtr&, const std::string&, Ice::Int, const Address&, Ice::Int, const std::string&, + bool); + TcpEndpointI(const ProtocolInstancePtr&); + TcpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + + virtual Ice::Int timeout() const; + virtual EndpointIPtr timeout(Ice::Int) const; + virtual bool compress() const; + virtual EndpointIPtr compress(bool) const; + virtual bool datagram() const; + + virtual TransceiverPtr transceiver() const; + virtual AcceptorPtr acceptor(const std::string&) const; + virtual std::string options() const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + TcpEndpointIPtr endpoint(const TcpAcceptorPtr&) const; + + using IPEndpointI::connectionId; + +protected: + + virtual void hashInit(Ice::Int&) const; + virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + + virtual ConnectorPtr createConnector(const Address&, const NetworkProxyPtr&) const; + virtual IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const; + +private: + + // + // All members are const, because endpoints are immutable. + // + const Ice::Int _timeout; + const bool _compress; +}; + +class TcpEndpointFactory : public EndpointFactory +{ +public: + + TcpEndpointFactory(const ProtocolInstancePtr&); + virtual ~TcpEndpointFactory(); + + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual EndpointIPtr create(std::vector&, bool) const; + virtual EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + +private: + + ProtocolInstancePtr _instance; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TcpTransceiver.h b/Sources/IceCpp/include/Ice/TcpTransceiver.h new file mode 100644 index 0000000..67ebec7 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TcpTransceiver.h @@ -0,0 +1,58 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TCP_TRANSCEIVER_H +#define ICE_TCP_TRANSCEIVER_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class TcpConnector; +class TcpAcceptor; + +class TcpTransceiver : public Transceiver +{ +public: + + virtual NativeInfoPtr getNativeInfo(); + + virtual SocketOperation initialize(Buffer&, Buffer&); + virtual SocketOperation closing(bool, const Ice::LocalException&); + + virtual void close(); + virtual SocketOperation write(Buffer&); + virtual SocketOperation read(Buffer&); +#if defined(ICE_USE_IOCP) + virtual bool startWrite(Buffer&); + virtual void finishWrite(Buffer&); + virtual void startRead(Buffer&); + virtual void finishRead(Buffer&); +#endif + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const Buffer&); + virtual void setBufferSize(int rcvSize, int sndSize); + +private: + + TcpTransceiver(const ProtocolInstancePtr&, const StreamSocketPtr&); + virtual ~TcpTransceiver(); + + friend class TcpConnector; + friend class TcpAcceptor; + + const ProtocolInstancePtr _instance; + const StreamSocketPtr _stream; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/ThreadPool.h b/Sources/IceCpp/include/Ice/ThreadPool.h new file mode 100644 index 0000000..51c8ecf --- /dev/null +++ b/Sources/IceCpp/include/Ice/ThreadPool.h @@ -0,0 +1,393 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_THREAD_POOL_H +#define ICE_THREAD_POOL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace IceInternal +{ + +class ThreadPoolCurrent; + +class ThreadPoolWorkQueue; +ICE_DEFINE_PTR(ThreadPoolWorkQueuePtr, ThreadPoolWorkQueue); + +class ThreadPoolWorkItem : public virtual IceUtil::Shared +{ +public: + + virtual void execute(ThreadPoolCurrent&) = 0; +}; +typedef IceUtil::Handle ThreadPoolWorkItemPtr; + +class DispatchWorkItem : public ThreadPoolWorkItem, public Ice::DispatcherCall +{ +public: + + DispatchWorkItem(); + DispatchWorkItem(const Ice::ConnectionPtr& connection); + + const Ice::ConnectionPtr& + getConnection() + { + return _connection; + } + +private: + + virtual void execute(ThreadPoolCurrent&); + + const Ice::ConnectionPtr _connection; +}; +typedef IceUtil::Handle DispatchWorkItemPtr; + +class ThreadPool : public IceUtil::Shared, private IceUtil::Monitor +{ + class EventHandlerThread : public IceUtil::Thread + { + public: + + EventHandlerThread(const ThreadPoolPtr&, const std::string&); + virtual void run(); + + void updateObserver(); + void setState(Ice::Instrumentation::ThreadState); + + private: + + ThreadPoolPtr _pool; + ObserverHelperT _observer; + Ice::Instrumentation::ThreadState _state; + }; + typedef IceUtil::Handle EventHandlerThreadPtr; + +public: + + ThreadPool(const InstancePtr&, const std::string&, int); + virtual ~ThreadPool(); + + void destroy(); + + void updateObservers(); + + void initialize(const EventHandlerPtr&); + void _register(const EventHandlerPtr& handler, SocketOperation status) + { + update(handler, SocketOperationNone, status); + } + void update(const EventHandlerPtr&, SocketOperation, SocketOperation); + void unregister(const EventHandlerPtr& handler, SocketOperation status) + { + update(handler, status, SocketOperationNone); + } + bool finish(const EventHandlerPtr&, bool); + void ready(const EventHandlerPtr&, SocketOperation, bool); + + void dispatchFromThisThread(const DispatchWorkItemPtr&); + void dispatch(const DispatchWorkItemPtr&); + + void joinWithAllThreads(); + + std::string prefix() const; + +#ifdef ICE_SWIFT + dispatch_queue_t getDispatchQueue() const ICE_NOEXCEPT; +#endif + +private: + + void run(const EventHandlerThreadPtr&); + + bool ioCompleted(ThreadPoolCurrent&); + +#if defined(ICE_USE_IOCP) + bool startMessage(ThreadPoolCurrent&); + void finishMessage(ThreadPoolCurrent&); +#else + void promoteFollower(ThreadPoolCurrent&); + bool followerWait(ThreadPoolCurrent&); +#endif + + std::string nextThreadId(); + + const InstancePtr _instance; +#ifdef ICE_SWIFT + const dispatch_queue_t _dispatchQueue; +#else // Ice for Swift does not support a dispatcher +# ifdef ICE_CPP11_MAPPING + std::function, const std::shared_ptr&)> _dispatcher; +# else + const Ice::DispatcherPtr _dispatcher; +# endif +#endif + ThreadPoolWorkQueuePtr _workQueue; + bool _destroyed; + const std::string _prefix; + Selector _selector; + int _nextThreadId; + + friend class EventHandlerThread; + friend class ThreadPoolCurrent; + friend class ThreadPoolWorkQueue; + + const int _size; // Number of threads that are pre-created. + const int _sizeIO; // Maximum number of threads that can concurrently perform IO. + const int _sizeMax; // Maximum number of threads. + const int _sizeWarn; // If _inUse reaches _sizeWarn, a "low on threads" warning will be printed. + const bool _serialize; // True if requests need to be serialized over the connection. + const bool _hasPriority; + const int _priority; + const int _serverIdleTime; + const int _threadIdleTime; + const size_t _stackSize; + + std::set _threads; // All threads, running or not. + int _inUse; // Number of threads that are currently in use. +#if !defined(ICE_USE_IOCP) + int _inUseIO; // Number of threads that are currently performing IO. + std::vector > _handlers; + std::vector >::const_iterator _nextHandler; +#endif + + bool _promote; +}; + +class ThreadPoolCurrent +{ +public: + + ThreadPoolCurrent(const InstancePtr&, const ThreadPoolPtr&, const ThreadPool::EventHandlerThreadPtr&); + + SocketOperation operation; + Ice::InputStream stream; // A per-thread stream to be used by event handlers for optimization. + + bool ioCompleted() const + { + return _threadPool->ioCompleted(const_cast(*this)); + } + +#if defined(ICE_USE_IOCP) + bool startMessage() + { + return _threadPool->startMessage(const_cast(*this)); + } + + void finishMessage() + { + _threadPool->finishMessage(const_cast(*this)); + } +#else + bool ioReady() + { + return (_handler->_registered & operation) != 0; + } +#endif + + void dispatchFromThisThread(const DispatchWorkItemPtr& workItem) + { + _threadPool->dispatchFromThisThread(workItem); + } + +private: + + ThreadPool* _threadPool; + ThreadPool::EventHandlerThreadPtr _thread; + EventHandlerPtr _handler; + bool _ioCompleted; +#if !defined(ICE_USE_IOCP) + bool _leader; +#else + DWORD _count; + int _error; +#endif + friend class ThreadPool; +}; + +class ThreadPoolWorkQueue : public EventHandler +{ +public: + + ThreadPoolWorkQueue(ThreadPool&); + + void destroy(); + void queue(const ThreadPoolWorkItemPtr&); + +#if defined(ICE_USE_IOCP) + bool startAsync(SocketOperation); + bool finishAsync(SocketOperation); +#endif + + virtual void message(ThreadPoolCurrent&); + virtual void finished(ThreadPoolCurrent&, bool); + virtual std::string toString() const; + virtual NativeInfoPtr getNativeInfo(); + +private: + + ThreadPool& _threadPool; + bool _destroyed; + std::list _workItems; +}; + +// +// The ThreadPoolMessage class below hides the IOCP implementation details from +// the event handler implementations. Only event handler implementation that +// require IO need to use this class. +// +// An instance of the IOScope subclass must be created within the synchronization +// of the event handler. It takes care of calling startMessage/finishMessage for +// the IOCP implementation and ensures that finishMessage isn't called multiple +// times. +// +#if !defined(ICE_USE_IOCP) +template class ThreadPoolMessage +{ +public: + + class IOScope + { + public: + + IOScope(ThreadPoolMessage& message) : _message(message) + { + // Nothing to do. + } + + ~IOScope() + { + // Nothing to do. + } + + operator bool() + { + return _message._current.ioReady(); // Ensure the handler is still interested in the operation. + } + + void completed() + { + _message._current.ioCompleted(); + } + + private: + + ThreadPoolMessage& _message; + }; + friend class IOScope; + + ThreadPoolMessage(ThreadPoolCurrent& current, const T&) : _current(current) + { + } + + ~ThreadPoolMessage() + { + // Nothing to do. + } + +private: + + ThreadPoolCurrent& _current; +}; + +#else + +template class ThreadPoolMessage +{ +public: + + class IOScope + { + public: + + IOScope(ThreadPoolMessage& message) : _message(message) + { + // This must be called with the handler locked. + _finish = _message._current.startMessage(); + } + + ~IOScope() + { + if(_finish) + { + // This must be called with the handler locked. + _message._current.finishMessage(); + } + } + + operator bool() + { + return _finish; + } + + void + completed() + { + // + // Call finishMessage once IO is completed only if serialization is not enabled. + // Otherwise, finishMessage will be called when the event handler is done with + // the message (it will be called from ~ThreadPoolMessage below). + // + assert(_finish); + if(_message._current.ioCompleted()) + { + _finish = false; + _message._finish = true; + } + } + + private: + + ThreadPoolMessage& _message; + bool _finish; + }; + friend class IOScope; + + ThreadPoolMessage(ThreadPoolCurrent& current, const T& mutex) : + _current(current), _mutex(mutex), _finish(false) + { + } + + ~ThreadPoolMessage() + { + if(_finish) + { + // + // A ThreadPoolMessage instance must be created outside the synchronization + // of the event handler. We need to lock the event handler here to call + // finishMessage. + // + IceUtil::LockT sync(_mutex); + _current.finishMessage(); + } + } + +private: + + ThreadPoolCurrent& _current; + const T& _mutex; + bool _finish; +}; +#endif + +}; + +#endif diff --git a/Sources/IceCpp/include/Ice/ThreadPoolF.h b/Sources/IceCpp/include/Ice/ThreadPoolF.h new file mode 100644 index 0000000..29db5db --- /dev/null +++ b/Sources/IceCpp/include/Ice/ThreadPoolF.h @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_THREAD_POOL_F_H +#define ICE_THREAD_POOL_F_H + +#include + +#include + +namespace IceInternal +{ + +class ThreadPool; +ICE_API IceUtil::Shared* upCast(ThreadPool*); +typedef Handle ThreadPoolPtr; + +class ThreadPoolCurrent; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TraceLevels.h b/Sources/IceCpp/include/Ice/TraceLevels.h new file mode 100644 index 0000000..d6aac9f --- /dev/null +++ b/Sources/IceCpp/include/Ice/TraceLevels.h @@ -0,0 +1,45 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TRACE_LEVELS_H +#define ICE_TRACE_LEVELS_H + +#include +#include +#include + +namespace IceInternal +{ + +class TraceLevels : public ::IceUtil::Shared +{ +public: + + TraceLevels(const ::Ice::PropertiesPtr&); + + const int network; + const char* networkCat; + + const int protocol; + const char* protocolCat; + + const int retry; + const char* retryCat; + + const int location; + const char* locationCat; + + const int slicing; + const char* slicingCat; + + const int gc; + const char* gcCat; + + const int threadPool; + const char* threadPoolCat; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TraceLevelsF.h b/Sources/IceCpp/include/Ice/TraceLevelsF.h new file mode 100644 index 0000000..12bd188 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TraceLevelsF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TRACE_LEVELS_F_H +#define ICE_TRACE_LEVELS_F_H + +#include + +#include + +namespace IceInternal +{ + +class TraceLevels; +IceUtil::Shared* upCast(TraceLevels*); +typedef Handle TraceLevelsPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TraceUtil.h b/Sources/IceCpp/include/Ice/TraceUtil.h new file mode 100644 index 0000000..c32ee25 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TraceUtil.h @@ -0,0 +1,30 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TRACE_UTIL_H +#define ICE_TRACE_UTIL_H + +#include +#include + +namespace Ice +{ + +class OutputStream; +class InputStream; + +} + +namespace IceInternal +{ + +void traceSend(const ::Ice::OutputStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void traceRecv(const ::Ice::InputStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void trace(const char*, const ::Ice::OutputStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void trace(const char*, const ::Ice::InputStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void traceSlicing(const char*, const ::std::string&, const char *, const ::Ice::LoggerPtr&); + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Transceiver.h b/Sources/IceCpp/include/Ice/Transceiver.h new file mode 100644 index 0000000..51e5134 --- /dev/null +++ b/Sources/IceCpp/include/Ice/Transceiver.h @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TRANSCEIVER_H +#define ICE_TRANSCEIVER_H + +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class Buffer; + +class ICE_API Transceiver : public virtual ::IceUtil::Shared +{ +public: + + virtual NativeInfoPtr getNativeInfo() = 0; + + virtual SocketOperation initialize(Buffer&, Buffer&) = 0; + virtual SocketOperation closing(bool, const Ice::LocalException&) = 0; + + virtual void close() = 0; + virtual EndpointIPtr bind(); + virtual SocketOperation write(Buffer&) = 0; + virtual SocketOperation read(Buffer&) = 0; +#if defined(ICE_USE_IOCP) + virtual bool startWrite(Buffer&) = 0; + virtual void finishWrite(Buffer&) = 0; + virtual void startRead(Buffer&) = 0; + virtual void finishRead(Buffer&) = 0; +#endif + + virtual std::string protocol() const = 0; + virtual std::string toString() const = 0; + virtual std::string toDetailedString() const = 0; + virtual Ice::ConnectionInfoPtr getInfo() const = 0; + virtual void checkSendSize(const Buffer&) = 0; + virtual void setBufferSize(int, int) = 0; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/TransceiverF.h b/Sources/IceCpp/include/Ice/TransceiverF.h new file mode 100644 index 0000000..d40a592 --- /dev/null +++ b/Sources/IceCpp/include/Ice/TransceiverF.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_TRANSCEIVER_F_H +#define ICE_TRANSCEIVER_F_H + +#include + +#include + +namespace IceInternal +{ + +class Transceiver; +ICE_API IceUtil::Shared* upCast(Transceiver*); +typedef Handle TransceiverPtr; + +class TcpTransceiver; +ICE_API IceUtil::Shared* upCast(TcpTransceiver*); +typedef Handle TcpTransceiverPtr; + +class UdpTransceiver; +ICE_API IceUtil::Shared* upCast(UdpTransceiver*); +typedef Handle UdpTransceiverPtr; + +class WSTransceiver; +ICE_API IceUtil::Shared* upCast(WSTransceiver*); +typedef Handle WSTransceiverPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/UUID.h b/Sources/IceCpp/include/Ice/UUID.h new file mode 100644 index 0000000..5a036e4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/UUID.h @@ -0,0 +1,19 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UUID_H +#define ICE_UUID_H + +#include +#include + +namespace Ice +{ + +/** Generates a UUID. */ +using IceUtil::generateUUID; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/UdpConnector.h b/Sources/IceCpp/include/Ice/UdpConnector.h new file mode 100644 index 0000000..56bd2f6 --- /dev/null +++ b/Sources/IceCpp/include/Ice/UdpConnector.h @@ -0,0 +1,45 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UDP_CONNECTOR_H +#define ICE_UDP_CONNECTOR_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class UdpConnector : public Connector +{ +public: + + virtual TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const Connector&) const; + virtual bool operator<(const Connector&) const; + +private: + + UdpConnector(const ProtocolInstancePtr&, const Address&, const Address&, const std::string&, int, + const std::string&); + + virtual ~UdpConnector(); + friend class UdpEndpointI; + + const ProtocolInstancePtr _instance; + const Address _addr; + const Address _sourceAddr; + const std::string _mcastInterface; + const int _mcastTtl; + const std::string _connectionId; +}; + +} +#endif diff --git a/Sources/IceCpp/include/Ice/UdpEndpointI.h b/Sources/IceCpp/include/Ice/UdpEndpointI.h new file mode 100644 index 0000000..6341493 --- /dev/null +++ b/Sources/IceCpp/include/Ice/UdpEndpointI.h @@ -0,0 +1,95 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UDP_ENDPOINT_I_H +#define ICE_UDP_ENDPOINT_I_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class UdpEndpointI : public IPEndpointI +{ +public: + + UdpEndpointI(const ProtocolInstancePtr&, const std::string&, Ice::Int, const Address&, const std::string&, + Ice::Int, bool, const std::string&, bool); + UdpEndpointI(const ProtocolInstancePtr&); + UdpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*); + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + + virtual Ice::Int timeout() const; + virtual EndpointIPtr timeout(Ice::Int) const; + virtual bool compress() const; + virtual EndpointIPtr compress(bool) const; + virtual bool datagram() const; + + virtual TransceiverPtr transceiver() const; + virtual AcceptorPtr acceptor(const std::string&) const; + virtual std::string options() const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + + UdpEndpointIPtr endpoint(const UdpTransceiverPtr&) const; + + using IPEndpointI::connectionId; + + virtual void initWithOptions(std::vector&, bool); + +protected: + + virtual void hashInit(Ice::Int&) const; + virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const; + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + + virtual ConnectorPtr createConnector(const Address&, const NetworkProxyPtr&) const; + virtual IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const; + +private: + + // + // All members are const, because endpoints are immutable. + // + const Ice::Int _mcastTtl; + const std::string _mcastInterface; + const bool _connect; + const bool _compress; +}; + +class UdpEndpointFactory : public EndpointFactory +{ +public: + + UdpEndpointFactory(const ProtocolInstancePtr&); + virtual ~UdpEndpointFactory(); + + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual EndpointIPtr create(std::vector&, bool) const; + virtual EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const; + +private: + + ProtocolInstancePtr _instance; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/UdpTransceiver.h b/Sources/IceCpp/include/Ice/UdpTransceiver.h new file mode 100644 index 0000000..95212ed --- /dev/null +++ b/Sources/IceCpp/include/Ice/UdpTransceiver.h @@ -0,0 +1,96 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UDP_TRANSCEIVER_H +#define ICE_UDP_TRANSCEIVER_H + +#include + +#include +#include +#include + +namespace IceInternal +{ + +class UdpEndpoint; + +class UdpTransceiver : public Transceiver, public NativeInfo +{ + enum State + { + StateNeedConnect, + StateConnectPending, + StateConnected, + StateNotConnected + }; + +public: + + virtual NativeInfoPtr getNativeInfo(); +#if defined(ICE_USE_IOCP) + virtual AsyncInfo* getAsyncInfo(SocketOperation); +#endif + + virtual SocketOperation initialize(Buffer&, Buffer&); + virtual SocketOperation closing(bool, const Ice::LocalException&); + virtual void close(); + virtual EndpointIPtr bind(); + virtual SocketOperation write(Buffer&); + virtual SocketOperation read(Buffer&); +#if defined(ICE_USE_IOCP) + virtual bool startWrite(Buffer&); + virtual void finishWrite(Buffer&); + virtual void startRead(Buffer&); + virtual void finishRead(Buffer&); +#endif + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const Buffer&); + virtual void setBufferSize(int rcvSize, int sndSize); + + int effectivePort() const; + +private: + + UdpTransceiver(const ProtocolInstancePtr&, const Address&, const Address&, const std::string&, int); + UdpTransceiver(const UdpEndpointIPtr&, const ProtocolInstancePtr&, const std::string&, int, const std::string&, + bool); + + virtual ~UdpTransceiver(); + + void setBufSize(int, int); + + friend class UdpEndpointI; + friend class UdpConnector; + + UdpEndpointIPtr _endpoint; + const ProtocolInstancePtr _instance; + const bool _incoming; + bool _bound; + + const Address _addr; + Address _mcastAddr; + const std::string _mcastInterface; + Address _peerAddr; + int _port; + + State _state; + int _rcvSize; + int _sndSize; + static const int _udpOverhead; + static const int _maxPacketSize; + +#if defined(ICE_USE_IOCP) + AsyncInfo _read; + AsyncInfo _write; + Address _readAddr; + socklen_t _readAddrLen; +#endif +}; + +} +#endif diff --git a/Sources/IceCpp/include/Ice/UniquePtr.h b/Sources/IceCpp/include/Ice/UniquePtr.h new file mode 100644 index 0000000..c1ba3e5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/UniquePtr.h @@ -0,0 +1,95 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UNIQUE_PTR_H +#define ICE_UNIQUE_PTR_H + +#include + +namespace IceInternal +{ + +#ifdef ICE_CPP11_MAPPING + +template +using UniquePtr = std::unique_ptr; + +#else + +template +class UniquePtr +{ +public: + + explicit UniquePtr(T* ptr = 0) : + _ptr(ptr) + { + } + + ~UniquePtr() + { + if(_ptr != 0) + { + delete _ptr; + } + } + + T* release() + { + T* r = _ptr; + _ptr = 0; + return r; + } + + void reset(T* ptr = 0) + { + assert(ptr == 0 || ptr != _ptr); + + if(_ptr != 0) + { + delete _ptr; + } + _ptr = ptr; + } + + T& operator*() const + { + return *_ptr; + } + + T* operator->() const + { + return _ptr; + } + + T* get() const + { + return _ptr; + } + + operator bool() const + { + return _ptr != 0; + } + + void swap(UniquePtr& a) + { + T* tmp = a._ptr; + a._ptr = _ptr; + _ptr = tmp; + } + +private: + + UniquePtr(UniquePtr&); + UniquePtr& operator=(UniquePtr&); + + T* _ptr; +}; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/UniqueRef.h b/Sources/IceCpp/include/Ice/UniqueRef.h new file mode 100644 index 0000000..b506cf9 --- /dev/null +++ b/Sources/IceCpp/include/Ice/UniqueRef.h @@ -0,0 +1,97 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UNIQUE_REF_H +#define ICE_UNIQUE_REF_H + +#ifdef __APPLE__ + +#include + +namespace IceInternal +{ + +// +// UniqueRef helper class for CoreFoundation classes, comparable to std::unique_ptr +// +template +class UniqueRef +{ +public: + + explicit UniqueRef(R ref = 0) : + _ref(ref) + { + } + + ~UniqueRef() + { + if(_ref != 0) + { + CFRelease(_ref); + } + } + + R release() + { + R r = _ref; + _ref = 0; + return r; + } + + void reset(R ref = 0) + { + // + // Support "self-reset" for CF objects. This is useful if CF allocation methods return + // the same object with an increased reference count. + // + //assert(ref == 0 || ref != _ref); + + if(_ref != 0) + { + CFRelease(_ref); + } + _ref = ref; + } + + void retain(R ref) + { + reset(ref ? (R)CFRetain(ref) : ref); + } + + R& get() + { + return _ref; + } + + R get() const + { + return _ref; + } + + operator bool() const + { + return _ref != 0; + } + + void swap(UniqueRef& a) + { + R tmp = a._ref; + a._ref = _ref; + _ref = tmp; + } + +private: + + UniqueRef(UniqueRef&); + UniqueRef& operator=(UniqueRef&); + + R _ref; +}; + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/Ice/UserExceptionFactory.h b/Sources/IceCpp/include/Ice/UserExceptionFactory.h new file mode 100644 index 0000000..61feafb --- /dev/null +++ b/Sources/IceCpp/include/Ice/UserExceptionFactory.h @@ -0,0 +1,88 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_USER_EXCEPTION_FACTORY_H +#define ICE_USER_EXCEPTION_FACTORY_H + +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING + +namespace Ice +{ + +/** Creates and throws a user exception. */ +using UserExceptionFactory = std::function; + +} + +namespace IceInternal +{ + +template +void +#ifdef NDEBUG +defaultUserExceptionFactory(const std::string&) +#else +defaultUserExceptionFactory(const std::string& typeId) +#endif +{ + assert(typeId == E::ice_staticId()); + throw E(); +} + +} +#else + +namespace Ice +{ + +/** + * Creates and throws a user exception. + * \headerfile Ice/Ice.h + */ +class ICE_API UserExceptionFactory : public IceUtil::Shared +{ +public: + + virtual void createAndThrow(const ::std::string&) = 0; + virtual ~UserExceptionFactory(); +}; +typedef ::IceUtil::Handle UserExceptionFactoryPtr; + +} + +namespace IceInternal +{ + +template +class DefaultUserExceptionFactory : public Ice::UserExceptionFactory +{ +public: + + DefaultUserExceptionFactory(const ::std::string& typeId) : + _typeId(typeId) + { + } + +#ifdef NDEBUG + virtual void createAndThrow(const ::std::string&) +#else + virtual void createAndThrow(const ::std::string& typeId) +#endif + { + assert(typeId == _typeId); + throw E(); + } + +private: + const ::std::string _typeId; +}; + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/Value.h b/Sources/IceCpp/include/Ice/Value.h new file mode 100644 index 0000000..fa7f50c --- /dev/null +++ b/Sources/IceCpp/include/Ice/Value.h @@ -0,0 +1,139 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_VALUE_H +#define ICE_VALUE_H + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +#include +#include + +#include +#include + +namespace Ice +{ + +/** + * The base class for instances of Slice classes. + * \headerfile Ice/Ice.h + */ +class ICE_API Value +{ +public: + + // See "Rule of zero" at http://en.cppreference.com/w/cpp/language/rule_of_three + // The virtual dtor is actually not stricly necessary since Values are always stored + // in std::shared_ptr + + Value() = default; + Value(const Value&) = default; + Value(Value&&) = default; + Value& operator=(const Value&) = default; + Value& operator=(Value&&) = default; + virtual ~Value() = default; + + /** + * The Ice run time invokes this method prior to marshaling an object's data members. This allows a subclass + * to override this method in order to validate its data members. + */ + virtual void ice_preMarshal(); + + /** + * The Ice run time invokes this method after unmarshaling an object's data members. This allows a + * subclass to override this method in order to perform additional initialization. + */ + virtual void ice_postUnmarshal(); + + /** + * Obtains the Slice type ID of the most-derived class supported by this object. + * @return The type ID. + */ + virtual std::string ice_id() const; + + /** + * Obtains the Slice type ID of this type. + * @return The return value is always "::Ice::Object". + */ + static const std::string& ice_staticId(); + + /** + * Returns a shallow copy of the object. + * @return The cloned value. + */ + std::shared_ptr ice_clone() const; + + /** + * Obtains the sliced data associated with this instance. + * @return The sliced data if the value has a preserved-slice base class and has been sliced during + * unmarshaling of the value, nil otherwise. + */ + virtual std::shared_ptr ice_getSlicedData() const; + + /// \cond STREAM + virtual void _iceWrite(Ice::OutputStream*) const; + virtual void _iceRead(Ice::InputStream*); + /// \endcond + +protected: + + /// \cond INTERNAL + virtual std::shared_ptr _iceCloneImpl() const = 0; + /// \endcond + + /// \cond STREAM + virtual void _iceWriteImpl(Ice::OutputStream*) const {} + virtual void _iceReadImpl(Ice::InputStream*) {} + /// \endcond +}; + +/// \cond INTERNAL +template class ValueHelper : public Base +{ +public: + + using Base::Base; + + ValueHelper() = default; + + std::shared_ptr ice_clone() const + { + return std::static_pointer_cast(_iceCloneImpl()); + } + + virtual std::string ice_id() const override + { + return T::ice_staticId(); + } + +protected: + + virtual std::shared_ptr _iceCloneImpl() const override + { + return std::make_shared(static_cast(*this)); + } + + virtual void _iceWriteImpl(Ice::OutputStream* os) const override + { + os->startSlice(T::ice_staticId(), -1, std::is_same::value ? true : false); + Ice::StreamWriter::write(os, static_cast(*this)); + os->endSlice(); + Base::_iceWriteImpl(os); + } + + virtual void _iceReadImpl(Ice::InputStream* is) override + { + is->startSlice(); + Ice::StreamReader::read(is, static_cast(*this)); + is->endSlice(); + Base::_iceReadImpl(is); + } +}; +/// \endcond + +} +#endif // C++11 mapping end + +#endif diff --git a/Sources/IceCpp/include/Ice/ValueF.h b/Sources/IceCpp/include/Ice/ValueF.h new file mode 100644 index 0000000..414be67 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ValueF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_VALUE_F_H +#define ICE_VALUE_F_H + +#ifdef ICE_CPP11_MAPPING +#include + +namespace Ice +{ + +class Value; +/// \cond INTERNAL +using ValuePtr = ::std::shared_ptr; +/// \endcond + +} +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/ValueFactory.h b/Sources/IceCpp/include/Ice/ValueFactory.h new file mode 100644 index 0000000..82f1c86 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ValueFactory.h @@ -0,0 +1,330 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ValueFactory.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_ValueFactory_h__ +#define __Ice_ValueFactory_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +class ValueFactoryManager; + +} + +namespace Ice +{ + +/** + * Create a new value for a given value type. The type is the + * absolute Slice type id, i.e., the id relative to the + * unnamed top-level Slice module. For example, the absolute + * Slice type id for an interface Bar in the module + * Foo is "::Foo::Bar". + * + * Note that the leading "::" is required. + * @param type The value type. + * @return The value created for the given type, or nil if the + * factory is unable to create the value. + */ +using ValueFactory = ::std::function<::std::shared_ptr(const ::std::string& type)>; + +/** + * A value factory manager maintains a collection of value factories. + * An application can supply a custom implementation during communicator + * initialization, otherwise Ice provides a default implementation. + * @see ValueFactory + * \headerfile Ice/Ice.h + */ +class ICE_CLASS(ICE_API) ValueFactoryManager +{ +public: + + ICE_MEMBER(ICE_API) virtual ~ValueFactoryManager(); + + /** + * Add a value factory. Attempting to add a factory with an id for + * which a factory is already registered throws AlreadyRegisteredException. + * + * When unmarshaling an Ice value, the Ice run time reads the + * most-derived type id off the wire and attempts to create an + * instance of the type using a factory. If no instance is created, + * either because no factory was found, or because all factories + * returned nil, the behavior of the Ice run time depends on the + * format with which the value was marshaled: + * + * If the value uses the "sliced" format, Ice ascends the class + * hierarchy until it finds a type that is recognized by a factory, + * or it reaches the least-derived type. If no factory is found that + * can create an instance, the run time throws NoValueFactoryException. + * + * If the value uses the "compact" format, Ice immediately raises + * NoValueFactoryException. + * + * The following order is used to locate a factory for a type: + * + *

    + * + *
  1. The Ice run-time looks for a factory registered + * specifically for the type.
  2. + * + *
  3. If no instance has been created, the Ice run-time looks + * for the default factory, which is registered with an empty type id. + *
  4. + * + *
  5. If no instance has been created by any of the preceding + * steps, the Ice run-time looks for a factory that may have been + * statically generated by the language mapping for non-abstract classes. + *
  6. + * + *
+ * @param factory The factory to add. + * @param id The type id for which the factory can create instances, or + * an empty string for the default factory. + */ + virtual void add(ValueFactory factory, const ::std::string& id) = 0; + + /** + * Find an value factory registered with this communicator. + * @param id The type id for which the factory can create instances, + * or an empty string for the default factory. + * @return The value factory, or null if no value factory was + * found for the given id. + */ + virtual ::Ice::ValueFactory find(const ::std::string& id) const noexcept = 0; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace Ice +{ + +using ValueFactoryManagerPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +class ValueFactory; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ValueFactory*); +/// \endcond +typedef ::IceInternal::Handle< ValueFactory> ValueFactoryPtr; + +class ValueFactoryManager; +/// \cond INTERNAL +ICE_API LocalObject* upCast(ValueFactoryManager*); +/// \endcond +typedef ::IceInternal::Handle< ValueFactoryManager> ValueFactoryManagerPtr; + +} + +namespace Ice +{ + +/** + * A factory for values. Value factories are used in several + * places, such as when Ice receives a class instance and + * when Freeze restores a persistent value. Value factories + * must be implemented by the application writer and registered + * with the communicator. + * \headerfile Ice/Ice.h + */ +class ICE_API ValueFactory : public virtual LocalObject +{ +public: + + typedef ValueFactoryPtr PointerType; + + virtual ~ValueFactory(); + +#ifdef ICE_CPP11_COMPILER + ValueFactory() = default; + ValueFactory(const ValueFactory&) = default; + ValueFactory& operator=(const ValueFactory&) = default; +#endif + + /** + * Create a new value for a given value type. The type is the + * absolute Slice type id, i.e., the id relative to the + * unnamed top-level Slice module. For example, the absolute + * Slice type id for an interface Bar in the module + * Foo is "::Foo::Bar". + * + * Note that the leading "::" is required. + * @param type The value type. + * @return The value created for the given type, or nil if the + * factory is unable to create the value. + */ + virtual ValuePtr create(const ::std::string& type) = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ValueFactory& lhs, const ValueFactory& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ValueFactory& lhs, const ValueFactory& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * A value factory manager maintains a collection of value factories. + * An application can supply a custom implementation during communicator + * initialization, otherwise Ice provides a default implementation. + * @see ValueFactory + * \headerfile Ice/Ice.h + */ +class ICE_API ValueFactoryManager : public virtual LocalObject +{ +public: + + typedef ValueFactoryManagerPtr PointerType; + + virtual ~ValueFactoryManager(); + +#ifdef ICE_CPP11_COMPILER + ValueFactoryManager() = default; + ValueFactoryManager(const ValueFactoryManager&) = default; + ValueFactoryManager& operator=(const ValueFactoryManager&) = default; +#endif + + /** + * Add a value factory. Attempting to add a factory with an id for + * which a factory is already registered throws AlreadyRegisteredException. + * + * When unmarshaling an Ice value, the Ice run time reads the + * most-derived type id off the wire and attempts to create an + * instance of the type using a factory. If no instance is created, + * either because no factory was found, or because all factories + * returned nil, the behavior of the Ice run time depends on the + * format with which the value was marshaled: + * + * If the value uses the "sliced" format, Ice ascends the class + * hierarchy until it finds a type that is recognized by a factory, + * or it reaches the least-derived type. If no factory is found that + * can create an instance, the run time throws NoValueFactoryException. + * + * If the value uses the "compact" format, Ice immediately raises + * NoValueFactoryException. + * + * The following order is used to locate a factory for a type: + * + *
    + * + *
  1. The Ice run-time looks for a factory registered + * specifically for the type.
  2. + * + *
  3. If no instance has been created, the Ice run-time looks + * for the default factory, which is registered with an empty type id. + *
  4. + * + *
  5. If no instance has been created by any of the preceding + * steps, the Ice run-time looks for a factory that may have been + * statically generated by the language mapping for non-abstract classes. + *
  6. + * + *
+ * @param factory The factory to add. + * @param id The type id for which the factory can create instances, or + * an empty string for the default factory. + */ + virtual void add(const ValueFactoryPtr& factory, const ::std::string& id) = 0; + + /** + * Find an value factory registered with this communicator. + * @param id The type id for which the factory can create instances, + * or an empty string for the default factory. + * @return The value factory, or null if no value factory was + * found for the given id. + */ + virtual ValueFactoryPtr find(const ::std::string& id) const ICE_NOEXCEPT = 0; +}; + +/// \cond INTERNAL +inline bool operator==(const ValueFactoryManager& lhs, const ValueFactoryManager& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ValueFactoryManager& lhs, const ValueFactoryManager& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/ValueFactoryManagerI.h b/Sources/IceCpp/include/Ice/ValueFactoryManagerI.h new file mode 100644 index 0000000..df8e5f5 --- /dev/null +++ b/Sources/IceCpp/include/Ice/ValueFactoryManagerI.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_VALUE_FACTORY_MANAGER_I_H +#define ICE_VALUE_FACTORY_MANAGER_I_H + +#include +#include + +namespace IceInternal +{ + +class ValueFactoryManagerI; +ICE_DEFINE_PTR(ValueFactoryManagerIPtr, ValueFactoryManagerI); + +class ValueFactoryManagerI : public Ice::ValueFactoryManager, + public IceUtil::Mutex +{ +public: + + ValueFactoryManagerI(); + + virtual void add(ICE_IN(ICE_DELEGATE(::Ice::ValueFactory)), const std::string&); + virtual ICE_DELEGATE(::Ice::ValueFactory) find(const std::string&) const ICE_NOEXCEPT; + +private: + + typedef std::map FactoryMap; + + FactoryMap _factoryMap; + mutable FactoryMap::iterator _factoryMapHint; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/Version.h b/Sources/IceCpp/include/Ice/Version.h new file mode 100644 index 0000000..177de3d --- /dev/null +++ b/Sources/IceCpp/include/Ice/Version.h @@ -0,0 +1,357 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Version.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __Ice_Version_h__ +#define __Ice_Version_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace Ice +{ + +/** + * A version structure for the protocol version. + * \headerfile Ice/Ice.h + */ +struct ProtocolVersion +{ + ::Ice::Byte major; + ::Ice::Byte minor; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(major, minor); + } +}; + +/** + * A version structure for the encoding version. + * \headerfile Ice/Ice.h + */ +struct EncodingVersion +{ + ::Ice::Byte major; + ::Ice::Byte minor; + + /** + * Obtains a tuple containing all of the struct's data members. + * @return The data members in a tuple. + */ + std::tuple ice_tuple() const + { + return std::tie(major, minor); + } +}; + +using Ice::operator<; +using Ice::operator<=; +using Ice::operator>; +using Ice::operator>=; +using Ice::operator==; +using Ice::operator!=; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits<::Ice::ProtocolVersion> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = true; +}; + +template +struct StreamReader<::Ice::ProtocolVersion, S> +{ + static void read(S* istr, ::Ice::ProtocolVersion& v) + { + istr->readAll(v.major, v.minor); + } +}; + +template<> +struct StreamableTraits<::Ice::EncodingVersion> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = true; +}; + +template +struct StreamReader<::Ice::EncodingVersion, S> +{ + static void read(S* istr, ::Ice::EncodingVersion& v) + { + istr->readAll(v.major, v.minor); + } +}; + +} +/// \endcond + +#else // C++98 mapping + +namespace Ice +{ + +/** + * A version structure for the protocol version. + * \headerfile Ice/Ice.h + */ +struct ProtocolVersion +{ + ::Ice::Byte major; + ::Ice::Byte minor; + + bool operator==(const ProtocolVersion& rhs_) const + { + if(this == &rhs_) + { + return true; + } + if(major != rhs_.major) + { + return false; + } + if(minor != rhs_.minor) + { + return false; + } + return true; + } + + bool operator<(const ProtocolVersion& rhs_) const + { + if(this == &rhs_) + { + return false; + } + if(major < rhs_.major) + { + return true; + } + else if(rhs_.major < major) + { + return false; + } + if(minor < rhs_.minor) + { + return true; + } + else if(rhs_.minor < minor) + { + return false; + } + return false; + } + + bool operator!=(const ProtocolVersion& rhs_) const + { + return !operator==(rhs_); + } + bool operator<=(const ProtocolVersion& rhs_) const + { + return operator<(rhs_) || operator==(rhs_); + } + bool operator>(const ProtocolVersion& rhs_) const + { + return !operator<(rhs_) && !operator==(rhs_); + } + bool operator>=(const ProtocolVersion& rhs_) const + { + return !operator<(rhs_); + } +}; + +/** + * A version structure for the encoding version. + * \headerfile Ice/Ice.h + */ +struct EncodingVersion +{ + ::Ice::Byte major; + ::Ice::Byte minor; + + bool operator==(const EncodingVersion& rhs_) const + { + if(this == &rhs_) + { + return true; + } + if(major != rhs_.major) + { + return false; + } + if(minor != rhs_.minor) + { + return false; + } + return true; + } + + bool operator<(const EncodingVersion& rhs_) const + { + if(this == &rhs_) + { + return false; + } + if(major < rhs_.major) + { + return true; + } + else if(rhs_.major < major) + { + return false; + } + if(minor < rhs_.minor) + { + return true; + } + else if(rhs_.minor < minor) + { + return false; + } + return false; + } + + bool operator!=(const EncodingVersion& rhs_) const + { + return !operator==(rhs_); + } + bool operator<=(const EncodingVersion& rhs_) const + { + return operator<(rhs_) || operator==(rhs_); + } + bool operator>(const EncodingVersion& rhs_) const + { + return !operator<(rhs_) && !operator==(rhs_); + } + bool operator>=(const EncodingVersion& rhs_) const + { + return !operator<(rhs_); + } +}; + +} + +/// \cond STREAM +namespace Ice +{ + +template<> +struct StreamableTraits< ::Ice::ProtocolVersion> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = true; +}; + +template +struct StreamWriter< ::Ice::ProtocolVersion, S> +{ + static void write(S* ostr, const ::Ice::ProtocolVersion& v) + { + ostr->write(v.major); + ostr->write(v.minor); + } +}; + +template +struct StreamReader< ::Ice::ProtocolVersion, S> +{ + static void read(S* istr, ::Ice::ProtocolVersion& v) + { + istr->read(v.major); + istr->read(v.minor); + } +}; + +template<> +struct StreamableTraits< ::Ice::EncodingVersion> +{ + static const StreamHelperCategory helper = StreamHelperCategoryStruct; + static const int minWireSize = 2; + static const bool fixedLength = true; +}; + +template +struct StreamWriter< ::Ice::EncodingVersion, S> +{ + static void write(S* ostr, const ::Ice::EncodingVersion& v) + { + ostr->write(v.major); + ostr->write(v.minor); + } +}; + +template +struct StreamReader< ::Ice::EncodingVersion, S> +{ + static void read(S* istr, ::Ice::EncodingVersion& v) + { + istr->read(v.major); + istr->read(v.minor); + } +}; + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/Ice/VirtualShared.h b/Sources/IceCpp/include/Ice/VirtualShared.h new file mode 100644 index 0000000..9b8f4a4 --- /dev/null +++ b/Sources/IceCpp/include/Ice/VirtualShared.h @@ -0,0 +1,38 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_VIRTUAL_SHARED_H +#define ICE_VIRTUAL_SHARED_H + +#ifdef ICE_CPP11_MAPPING + +namespace IceInternal +{ + +class VirtualEnableSharedFromThisBase : public std::enable_shared_from_this +{ +public: + + virtual ~VirtualEnableSharedFromThisBase() = default; +}; + +template +class EnableSharedFromThis : public virtual VirtualEnableSharedFromThisBase +{ +public: + + std::shared_ptr shared_from_this() + { + return std::dynamic_pointer_cast(VirtualEnableSharedFromThisBase::shared_from_this()); + } + + std::shared_ptr shared_from_this() const + { + return std::dynamic_pointer_cast(VirtualEnableSharedFromThisBase::shared_from_this()); + } +}; + +} +#endif +#endif diff --git a/Sources/IceCpp/include/Ice/WSAcceptor.h b/Sources/IceCpp/include/Ice/WSAcceptor.h new file mode 100644 index 0000000..b23b3b2 --- /dev/null +++ b/Sources/IceCpp/include/Ice/WSAcceptor.h @@ -0,0 +1,52 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_WS_ACCEPTOR_I_H +#define ICE_WS_ACCEPTOR_I_H + +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class WSEndpoint; + +class WSAcceptor : public Acceptor, public NativeInfo +{ +public: + + virtual NativeInfoPtr getNativeInfo(); +#if defined(ICE_USE_IOCP) + virtual AsyncInfo* getAsyncInfo(SocketOperation); +#endif + + virtual void close(); + virtual EndpointIPtr listen(); +#if defined(ICE_USE_IOCP) + virtual void startAccept(); + virtual void finishAccept(); +#endif + virtual TransceiverPtr accept(); + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + +private: + + WSAcceptor(const WSEndpointPtr&, const ProtocolInstancePtr&, const AcceptorPtr&); + virtual ~WSAcceptor(); + friend class WSEndpoint; + + WSEndpointPtr _endpoint; + const ProtocolInstancePtr _instance; + const AcceptorPtr _delegate; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/WSConnector.h b/Sources/IceCpp/include/Ice/WSConnector.h new file mode 100644 index 0000000..c4f3004 --- /dev/null +++ b/Sources/IceCpp/include/Ice/WSConnector.h @@ -0,0 +1,43 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_WSCONNECTOR_I_H +#define ICE_WSCONNECTOR_I_H + +#include +#include +#include +#include + +namespace IceInternal +{ + +class WSEndpoint; + +class WSConnector : public Connector +{ +public: + + virtual TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const Connector&) const; + virtual bool operator<(const Connector&) const; + + WSConnector(const ProtocolInstancePtr&, const ConnectorPtr&, const std::string&, const std::string&); + virtual ~WSConnector(); + +private: + + const ProtocolInstancePtr _instance; + const ConnectorPtr _delegate; + const std::string _host; + const std::string _resource; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/WSEndpoint.h b/Sources/IceCpp/include/Ice/WSEndpoint.h new file mode 100644 index 0000000..64f312f --- /dev/null +++ b/Sources/IceCpp/include/Ice/WSEndpoint.h @@ -0,0 +1,93 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_WS_ENDPOINT_I_H +#define ICE_WS_ENDPOINT_I_H + +#include +#include +#include +#include +#include +#include + +namespace IceInternal +{ + +class WSEndpoint : public EndpointI +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, const std::string&); + WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, std::vector&); + WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, Ice::InputStream*); + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; + + virtual Ice::Int timeout() const; + virtual EndpointIPtr timeout(Ice::Int) const; + virtual const std::string& connectionId() const; + virtual EndpointIPtr connectionId(const ::std::string&) const; + virtual bool compress() const; + virtual EndpointIPtr compress(bool) const; + virtual bool datagram() const; + virtual bool secure() const; + + virtual TransceiverPtr transceiver() const; + virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; + virtual AcceptorPtr acceptor(const std::string&) const; + virtual std::vector expandIfWildcard() const; + virtual std::vector expandHost(EndpointIPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; + virtual ::Ice::Int hash() const; + virtual std::string options() const; + + WSEndpointPtr endpoint(const EndpointIPtr&) const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + +protected: + + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + +private: + + // + // All members are const, because endpoints are immutable. + // + const ProtocolInstancePtr _instance; + const EndpointIPtr _delegate; + const std::string _resource; +}; + +class ICE_API WSEndpointFactory : public EndpointFactoryWithUnderlying +{ +public: + + WSEndpointFactory(const ProtocolInstancePtr&, Ice::Short); + + virtual EndpointFactoryPtr cloneWithUnderlying(const ProtocolInstancePtr&, Ice::Short) const; + +protected: + + virtual EndpointIPtr createWithUnderlying(const EndpointIPtr&, std::vector&, bool) const; + virtual EndpointIPtr readWithUnderlying(const EndpointIPtr&, Ice::InputStream*) const; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/Ice/WSTransceiver.h b/Sources/IceCpp/include/Ice/WSTransceiver.h new file mode 100644 index 0000000..44773f2 --- /dev/null +++ b/Sources/IceCpp/include/Ice/WSTransceiver.h @@ -0,0 +1,141 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_WS_TRANSCEIVER_I_H +#define ICE_WS_TRANSCEIVER_I_H + +#include +#include + +#include +#include +#include +#include + +namespace IceInternal +{ + +class ConnectorI; +class AcceptorI; + +class WSTransceiver : public Transceiver +{ +public: + + virtual NativeInfoPtr getNativeInfo(); +#if defined(ICE_USE_IOCP) + virtual AsyncInfo* getAsyncInfo(SocketOperation); +#endif + + virtual SocketOperation initialize(Buffer&, Buffer&); + virtual SocketOperation closing(bool, const Ice::LocalException&); + virtual void close(); + virtual SocketOperation write(Buffer&); + virtual SocketOperation read(Buffer&); +#if defined(ICE_USE_IOCP) + virtual bool startWrite(Buffer&); + virtual void finishWrite(Buffer&); + virtual void startRead(Buffer&); + virtual void finishRead(Buffer&); +#endif + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const Buffer&); + virtual void setBufferSize(int rcvSize, int sndSize); + +private: + + WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&, const std::string&, const std::string&); + WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&); + virtual ~WSTransceiver(); + + void handleRequest(Buffer&); + void handleResponse(); + + bool preRead(Buffer&); + bool postRead(Buffer&); + + bool preWrite(Buffer&); + bool postWrite(Buffer&); + + bool readBuffered(Buffer::Container::size_type); + void prepareWriteHeader(Ice::Byte, Buffer::Container::size_type); + + friend class WSConnector; + friend class WSAcceptor; + + const ProtocolInstancePtr _instance; + const TransceiverPtr _delegate; + const std::string _host; + const std::string _resource; + const bool _incoming; + + enum State + { + StateInitializeDelegate, + StateConnected, + StateUpgradeRequestPending, + StateUpgradeResponsePending, + StateOpened, + StatePingPending, + StatePongPending, + StateClosingRequestPending, + StateClosingResponsePending, + StateClosed + }; + + State _state; + State _nextState; + + HttpParserPtr _parser; + std::string _key; + + enum ReadState + { + ReadStateOpcode, + ReadStateHeader, + ReadStateControlFrame, + ReadStatePayload, + }; + + ReadState _readState; + Buffer _readBuffer; + Buffer::Container::iterator _readI; + const Buffer::Container::size_type _readBufferSize; + + bool _readLastFrame; + int _readOpCode; + size_t _readHeaderLength; + size_t _readPayloadLength; + Buffer::Container::iterator _readStart; + Buffer::Container::iterator _readFrameStart; + unsigned char _readMask[4]; + + enum WriteState + { + WriteStateHeader, + WriteStatePayload, + WriteStateControlFrame, + }; + + WriteState _writeState; + Buffer _writeBuffer; + const Buffer::Container::size_type _writeBufferSize; + unsigned char _writeMask[4]; + size_t _writePayloadLength; + + bool _readPending; + bool _writePending; + + bool _closingInitiator; + int _closingReason; + + std::vector _pingPayload; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceIAP/ConnectionInfo.h b/Sources/IceCpp/include/IceIAP/ConnectionInfo.h new file mode 100644 index 0000000..b50535a --- /dev/null +++ b/Sources/IceCpp/include/IceIAP/ConnectionInfo.h @@ -0,0 +1,263 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceIAP_ConnectionInfo_h__ +#define __IceIAP_ConnectionInfo_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICEIAP_API +# if defined(ICE_STATIC_LIBS) +# define ICEIAP_API /**/ +# elif defined(ICEIAP_API_EXPORTS) +# define ICEIAP_API ICE_DECLSPEC_EXPORT +# else +# define ICEIAP_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceIAP +{ + +class ConnectionInfo; + +} + +namespace IceIAP +{ + +/** + * Provides access to the connection details of an IAP connection + * \headerfile IceIAP/IceIAP.h + */ +class ICE_CLASS(ICEIAP_API) ConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + ICE_MEMBER(ICEIAP_API) virtual ~ConnectionInfo(); + + ConnectionInfo() = default; + + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo(ConnectionInfo&&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; + ConnectionInfo& operator=(ConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param name The accessory name. + * @param manufacturer The accessory manufacturer. + * @param modelNumber The accessory model number. + * @param firmwareRevision The accessory firmare revision. + * @param hardwareRevision The accessory hardware revision. + * @param protocol The protocol used by the accessory. + */ + ConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& name, const ::std::string& manufacturer, const ::std::string& modelNumber, const ::std::string& firmwareRevision, const ::std::string& hardwareRevision, const ::std::string& protocol) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + name(name), + manufacturer(manufacturer), + modelNumber(modelNumber), + firmwareRevision(firmwareRevision), + hardwareRevision(hardwareRevision), + protocol(protocol) + { + } + + /** + * The accessory name. + */ + ::std::string name; + /** + * The accessory manufacturer. + */ + ::std::string manufacturer; + /** + * The accessory model number. + */ + ::std::string modelNumber; + /** + * The accessory firmare revision. + */ + ::std::string firmwareRevision; + /** + * The accessory hardware revision. + */ + ::std::string hardwareRevision; + /** + * The protocol used by the accessory. + */ + ::std::string protocol; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceIAP +{ + +using ConnectionInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceIAP +{ + +class ConnectionInfo; +/// \cond INTERNAL +ICEIAP_API ::Ice::LocalObject* upCast(ConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionInfo> ConnectionInfoPtr; + +} + +namespace IceIAP +{ + +/** + * Provides access to the connection details of an IAP connection + * \headerfile IceIAP/IceIAP.h + */ +class ICEIAP_API ConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + typedef ConnectionInfoPtr PointerType; + + virtual ~ConnectionInfo(); + + ConnectionInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param name The accessory name. + * @param manufacturer The accessory manufacturer. + * @param modelNumber The accessory model number. + * @param firmwareRevision The accessory firmare revision. + * @param hardwareRevision The accessory hardware revision. + * @param protocol The protocol used by the accessory. + */ + ConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& name, const ::std::string& manufacturer, const ::std::string& modelNumber, const ::std::string& firmwareRevision, const ::std::string& hardwareRevision, const ::std::string& protocol) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + name(name), + manufacturer(manufacturer), + modelNumber(modelNumber), + firmwareRevision(firmwareRevision), + hardwareRevision(hardwareRevision), + protocol(protocol) + { + } + +#ifdef ICE_CPP11_COMPILER + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; +#endif + + /** + * The accessory name. + */ + ::std::string name; + /** + * The accessory manufacturer. + */ + ::std::string manufacturer; + /** + * The accessory model number. + */ + ::std::string modelNumber; + /** + * The accessory firmare revision. + */ + ::std::string firmwareRevision; + /** + * The accessory hardware revision. + */ + ::std::string hardwareRevision; + /** + * The protocol used by the accessory. + */ + ::std::string protocol; +}; + +/// \cond INTERNAL +inline bool operator==(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/IceIAP/EndpointInfo.h b/Sources/IceCpp/include/IceIAP/EndpointInfo.h new file mode 100644 index 0000000..9f2670c --- /dev/null +++ b/Sources/IceCpp/include/IceIAP/EndpointInfo.h @@ -0,0 +1,242 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceIAP_EndpointInfo_h__ +#define __IceIAP_EndpointInfo_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICEIAP_API +# if defined(ICE_STATIC_LIBS) +# define ICEIAP_API /**/ +# elif defined(ICEIAP_API_EXPORTS) +# define ICEIAP_API ICE_DECLSPEC_EXPORT +# else +# define ICEIAP_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceIAP +{ + +class EndpointInfo; + +} + +namespace IceIAP +{ + +/** + * Provides access to an IAP endpoint information. + * \headerfile IceIAP/IceIAP.h + */ +class ICE_CLASS(ICEIAP_API) EndpointInfo : public ::Ice::EndpointInfo +{ +public: + + ICE_MEMBER(ICEIAP_API) virtual ~EndpointInfo(); + + EndpointInfo() = default; + + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo(EndpointInfo&&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; + EndpointInfo& operator=(EndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param manufacturer The accessory manufacturer or empty to not match against a manufacturer. + * @param modelNumber The accessory model number or empty to not match against a model number. + * @param name The accessory name or empty to not match against the accessory name. + * @param protocol The protocol supported by the accessory. + */ + EndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress, const ::std::string& manufacturer, const ::std::string& modelNumber, const ::std::string& name, const ::std::string& protocol) : + ::Ice::EndpointInfo(underlying, timeout, compress), + manufacturer(manufacturer), + modelNumber(modelNumber), + name(name), + protocol(protocol) + { + } + + /** + * The accessory manufacturer or empty to not match against + * a manufacturer. + */ + ::std::string manufacturer; + /** + * The accessory model number or empty to not match against + * a model number. + */ + ::std::string modelNumber; + /** + * The accessory name or empty to not match against + * the accessory name. + */ + ::std::string name; + /** + * The protocol supported by the accessory. + */ + ::std::string protocol; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceIAP +{ + +using EndpointInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceIAP +{ + +class EndpointInfo; +/// \cond INTERNAL +ICEIAP_API ::Ice::LocalObject* upCast(EndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< EndpointInfo> EndpointInfoPtr; + +} + +namespace IceIAP +{ + +/** + * Provides access to an IAP endpoint information. + * \headerfile IceIAP/IceIAP.h + */ +class ICEIAP_API EndpointInfo : public ::Ice::EndpointInfo +{ +public: + + typedef EndpointInfoPtr PointerType; + + virtual ~EndpointInfo(); + + EndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + * @param manufacturer The accessory manufacturer or empty to not match against a manufacturer. + * @param modelNumber The accessory model number or empty to not match against a model number. + * @param name The accessory name or empty to not match against the accessory name. + * @param protocol The protocol supported by the accessory. + */ + EndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress, const ::std::string& manufacturer, const ::std::string& modelNumber, const ::std::string& name, const ::std::string& protocol) : + ::Ice::EndpointInfo(underlying, timeout, compress), + manufacturer(manufacturer), + modelNumber(modelNumber), + name(name), + protocol(protocol) + { + } + +#ifdef ICE_CPP11_COMPILER + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; +#endif + + /** + * The accessory manufacturer or empty to not match against + * a manufacturer. + */ + ::std::string manufacturer; + /** + * The accessory model number or empty to not match against + * a model number. + */ + ::std::string modelNumber; + /** + * The accessory name or empty to not match against + * the accessory name. + */ + ::std::string name; + /** + * The protocol supported by the accessory. + */ + ::std::string protocol; +}; + +/// \cond INTERNAL +inline bool operator==(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceCpp/include/IceIAP/IceIAP.h b/Sources/IceCpp/include/IceIAP/IceIAP.h new file mode 100644 index 0000000..5d4bdd2 --- /dev/null +++ b/Sources/IceCpp/include/IceIAP/IceIAP.h @@ -0,0 +1,13 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IAP_ICE_IAP_H +#define ICE_IAP_ICE_IAP_H + +#include +#include +#include +#include + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Atomic.h b/Sources/IceCpp/include/IceUtil/Atomic.h new file mode 100644 index 0000000..244b67c --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Atomic.h @@ -0,0 +1,179 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_ATOMIC_H +#define ICE_UTIL_ATOMIC_H + +#if ((defined(ICE_CPP11_COMPILER) && defined(_MSC_VER) && (_MSC_VER > 1600)) || \ + (defined(ICE_CPP11_COMPILER) && !defined(_MSC_VER))) +# define ICE_CPP11_COMPILER_HAS_ATOMIC +#endif + +#if defined(ICE_CPP11_COMPILER_HAS_ATOMIC) +# include +#elif defined(ICE_USE_MUTEX_SHARED) + +# include + +// Using the gcc builtins requires gcc 4.1 or better. For Linux, i386 +// doesn't work. Apple is supported for all architectures. Sun only +// supports sparc (32 and 64 bit). + +#elif ((defined(__GNUC__) && (((__GNUC__* 100) + __GNUC_MINOR__) >= 401)) || __clang__) && \ + ((defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \ + defined(__APPLE__) || \ + (defined(__linux__) && \ + (defined(__i486) || defined(__i586) || \ + defined(__i686) || defined(__x86_64)))) + +# define ICE_HAS_GCC_BUILTINS + +#elif defined(_WIN32) +// Nothing to include +#else +// Use a simple mutex +# include +#endif + +namespace IceUtilInternal +{ + +#ifdef ICE_CPP11_COMPILER_HAS_ATOMIC +typedef std::atomic Atomic; +#else + +#if defined(_WIN32) +// +// volatile here is required by InterlockedExchangeXXX +// family functions. +// +# if defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER <= 1500)) +typedef volatile LONG ATOMIC_T; +# else +typedef unsigned int ATOMIC_T; +# endif +#else +typedef int ATOMIC_T; +#endif + +// +// This is temporary and very partial placeholder for std::atomic, +// which is not yet widely available. +// +class ICE_API Atomic : public IceUtil::noncopyable +{ +public: + + Atomic() : + _ref(0) + { + } + + Atomic(int desired) : + _ref(desired) + { + } + + inline int fetch_add(int value) + { +#if defined(_WIN32) + return InterlockedExchangeAdd(&_ref, value); +#elif defined(ICE_HAS_GCC_BUILTINS) + return __sync_fetch_and_add(&_ref, value); +#else + IceUtil::Mutex::Lock sync(_mutex); + int tmp = _ref; + _ref += value; + return tmp; +#endif + } + + inline int fetch_sub(int value) + { +#if defined(_WIN32) +# if defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER <= 1500)) + return InterlockedExchangeAdd(&_ref, -value); +# else + return InterlockedExchangeSubtract(&_ref, value); +#endif +#elif defined(ICE_HAS_GCC_BUILTINS) + return __sync_fetch_and_sub(&_ref, value); +#else + IceUtil::Mutex::Lock sync(_mutex); + ATOMIC_T tmp = _ref; + _ref -= value; + return tmp; +#endif + } + + inline int load() const + { +#if defined(_WIN32) + return InterlockedExchangeAdd(const_cast(&_ref), 0); +#elif defined(ICE_HAS_GCC_BUILTINS) + return __sync_fetch_and_add(const_cast(&_ref), 0); +#else + IceUtil::Mutex::Lock sync(_mutex); + return _ref; +#endif + } + + inline int exchange(int value) + { +#if defined(_WIN32) + return InterlockedExchange(&_ref, value); +#elif defined(ICE_HAS_GCC_BUILTINS) + __sync_synchronize(); + return __sync_lock_test_and_set(&_ref, value); +#else + IceUtil::Mutex::Lock sync(_mutex); + int tmp = _ref; + _ref = value; + return tmp; +#endif + } + + inline int operator++() + { + return fetch_add(1) + 1; + } + + inline int operator--() + { + return fetch_sub(1) - 1; + } + + inline int operator++(int) + { + return fetch_add(1); + } + + inline int operator--(int) + { + return fetch_sub(1); + } + + inline operator int() + { + return load(); + } + + inline operator int() const + { + return load(); + } + +private: + + ATOMIC_T _ref; +#if !defined(_WIN32) && !defined(ICE_HAS_GCC_BUILTINS) + IceUtil::Mutex _mutex; +#endif +}; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Cond.h b/Sources/IceCpp/include/IceUtil/Cond.h new file mode 100644 index 0000000..eca7512 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Cond.h @@ -0,0 +1,317 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_COND_H +#define ICE_UTIL_COND_H + +#include +#include +#include + +#if defined(_WIN32) && !defined(ICE_HAS_WIN32_CONDVAR) +# include + +namespace IceUtilInternal +{ +// +// Needed for implementation. +// +class Semaphore +{ +public: + + Semaphore(long = 0); + ICE_API ~Semaphore(); + + void wait() const; + bool timedWait(const IceUtil::Time&) const; + void post(int = 1) const; + +private: + + mutable HANDLE _sem; +}; +} +#endif + +namespace IceUtil +{ + +// +// Forward declaration (for friend declarations). +// +template class Monitor; +class RecMutex; +class Mutex; + +// +// Condition variable implementation. Conforms to the same semantics +// as a POSIX threads condition variable. +// +class ICE_API Cond : private noncopyable +{ +public: + + Cond(); + ~Cond(); + + // + // signal restarts one of the threads that are waiting on the + // condition variable cond. If no threads are waiting on cond, + // nothing happens. If several threads are waiting on cond, + // exactly one is restarted, but it is not specified which. + // + void signal(); + + // + // broadcast restarts all the threads that are waiting on the + // condition variable cond. Nothing happens if no threads are + // waiting on cond. + // + void broadcast(); + + // + // MSVC doesn't support out-of-class definitions of member + // templates. See KB Article Q241949 for details. + // + + // + // wait atomically unlocks the mutex and waits for the condition + // variable to be signaled. Before returning to the calling thread + // the mutex is reaquired. + // + template inline void + wait(const Lock& lock) const + { + if(!lock.acquired()) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + waitImpl(lock._mutex); + } + + // + // wait atomically unlocks the mutex and waits for the condition + // variable to be signaled for up to the given timeout. Before + // returning to the calling thread the mutex is reaquired. Returns + // true if the condition variable was signaled, false on a + // timeout. + // + template inline bool + timedWait(const Lock& lock, const Time& timeout) const + { + if(!lock.acquired()) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + return timedWaitImpl(lock._mutex, timeout); + } + +private: + + friend class Monitor; + friend class Monitor; + + // + // The Monitor implementation uses waitImpl & timedWaitImpl. + // +#if defined(_WIN32) && !defined(ICE_HAS_WIN32_CONDVAR) + + template void + waitImpl(const M& mutex) const + { + preWait(); + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + + try + { + dowait(); + mutex.lock(state); + } + catch(...) + { + mutex.lock(state); + throw; + } + } + template bool + timedWaitImpl(const M& mutex, const Time& timeout) const + { + preWait(); + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + + try + { + bool rc = timedDowait(timeout); + mutex.lock(state); + return rc; + } + catch(...) + { + mutex.lock(state); + throw; + } + } + +#else + + template void waitImpl(const M&) const; + template bool timedWaitImpl(const M&, const Time&) const; + +#endif + +#ifdef _WIN32 +# ifdef ICE_HAS_WIN32_CONDVAR + mutable CONDITION_VARIABLE _cond; +# else + void wake(bool); + void preWait() const; + void postWait(bool) const; + bool timedDowait(const Time&) const; + void dowait() const; + + Mutex _internal; + IceUtilInternal::Semaphore _gate; + IceUtilInternal::Semaphore _queue; + mutable long _blocked; + mutable long _unblocked; + enum State + { + StateIdle, + StateSignal, + StateBroadcast + }; + mutable State _state; +# endif +#else + mutable pthread_cond_t _cond; +#endif + +}; + +#ifdef _WIN32 + +# ifdef ICE_HAS_WIN32_CONDVAR + +template inline void +Cond::waitImpl(const M& mutex) const +{ + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + BOOL ok = SleepConditionVariableCS(&_cond, state.mutex, INFINITE); + mutex.lock(state); + + if(!ok) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} + +template inline bool +Cond::timedWaitImpl(const M& mutex, const Time& timeout) const +{ + IceUtil::Int64 msTimeout = timeout.toMilliSeconds(); + if(msTimeout < 0 || msTimeout > 0x7FFFFFFF) + { + throw IceUtil::InvalidTimeoutException(__FILE__, __LINE__, timeout); + } + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + BOOL ok = SleepConditionVariableCS(&_cond, state.mutex, static_cast(msTimeout)); + mutex.lock(state); + + if(!ok) + { + DWORD err = GetLastError(); + + if(err != ERROR_TIMEOUT) + { + throw ThreadSyscallException(__FILE__, __LINE__, err); + } + return false; + } + return true; +} + +# endif + +#else +template inline void +Cond::waitImpl(const M& mutex) const +{ + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + int rc = pthread_cond_wait(&_cond, state.mutex); + mutex.lock(state); + + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +template inline bool +Cond::timedWaitImpl(const M& mutex, const Time& timeout) const +{ + if(timeout < Time::microSeconds(0)) + { + throw InvalidTimeoutException(__FILE__, __LINE__, timeout); + } + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + +# ifdef __APPLE__ + // + // The monotonic time is based on mach_absolute_time and pthread + // condition variables require time from gettimeofday so we get + // the realtime time. + // + timeval tv = Time::now(Time::Realtime) + timeout; +# else + timeval tv = Time::now(Time::Monotonic) + timeout; +# endif + timespec ts; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + int rc = pthread_cond_timedwait(&_cond, state.mutex, &ts); + mutex.lock(state); + + if(rc != 0) + { + // + // pthread_cond_timedwait returns ETIMEOUT in the event of a + // timeout. + // + if(rc != ETIMEDOUT) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + return false; + } + return true; +} + +#endif + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Config.h b/Sources/IceCpp/include/IceUtil/Config.h new file mode 100644 index 0000000..74b56d6 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Config.h @@ -0,0 +1,392 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_CONFIG_H +#define ICE_UTIL_CONFIG_H + +// +// Use the system headers as preferred way to detect endianness +// and fallback to architecture based checks. +// +// +#include + +#if defined(__GLIBC__) +# include +#elif defined(__APPLE__) +# include +#elif defined(__FreeBSD__) +# include +#endif + +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || \ + (defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + +# define ICE_LITTLE_ENDIAN + +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)) || \ + (defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + +# define ICE_BIG_ENDIAN + +#elif defined(__i386) || \ + defined(_M_IX86) || \ + defined(__x86_64) || \ + defined(_M_X64) || \ + defined(_M_IA64) || \ + defined(__alpha__) || \ + defined(__ARMEL__) || \ + defined(_M_ARM64) || \ + defined(_M_ARM_FP) || \ + defined(__arm64) || \ + defined(__MIPSEL__) + +# define ICE_LITTLE_ENDIAN + +#elif defined(__sparc) || \ + defined(__sparc__) || \ + defined(__hppa) || \ + defined(__ppc__) || \ + defined(__powerpc) || \ + defined(_ARCH_COM) || \ + defined(__MIPSEB__) + +# define ICE_BIG_ENDIAN + +#else + +# error "Unknown architecture" + +#endif + +#ifdef _MSC_VER + +# ifdef _WIN64 +# define ICE_64 +# else +# define ICE_32 +# endif + +#else + + // + // Use system headers as preferred way to detect 32 or 64 bit mode and + // fallback to architecture based checks + // +# include + +# if defined(__WORDSIZE) && (__WORDSIZE == 64) +# define ICE_64 +# elif defined(__WORDSIZE) && (__WORDSIZE == 32) +# define ICE_32 +# elif defined(__sun) && (defined(__sparcv9) || defined(__x86_64)) || \ + defined(__linux__) && defined(__x86_64) || \ + defined(__APPLE__) && defined(__x86_64) || \ + defined(__hppa) && defined(__LP64__) || \ + defined(_ARCH_COM) && defined(__64BIT__) || \ + defined(__alpha__) || \ + defined(_WIN64) +# define ICE_64 +# else +# define ICE_32 +# endif +#endif + +#if defined(_MSVC_LANG) +# define ICE_CPLUSPLUS _MSVC_LANG +#else +# define ICE_CPLUSPLUS __cplusplus +#endif + +// +// Check for C++ 11 support +// +// For GCC, we recognize --std=c++0x only for GCC version 4.5 and greater, +// as C++11 support in prior releases was too limited. +// +#if (ICE_CPLUSPLUS >= 201103) || \ + ((defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && ((__GNUC__* 100) + __GNUC_MINOR__) >= 405)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1900)) +# define ICE_CPP11_COMPILER +#endif + +// +// Ensure the C++ compiler supports C++11 when using the C++11 mapping +// +#if defined(ICE_CPP11_MAPPING) && !defined(ICE_CPP11_COMPILER) +# error "you need a C++11 capable compiler to use the C++11 mapping" +#endif + +#if defined(ICE_CPP11_COMPILER) +# define ICE_NOEXCEPT noexcept +# define ICE_NOEXCEPT_FALSE noexcept(false) +# define ICE_FINAL final +#else +# define ICE_NOEXCEPT throw() +# define ICE_NOEXCEPT_FALSE /**/ +# define ICE_FINAL /**/ +#endif + +// +// Does the C++ compiler library provide std::codecvt_utf8 and +// std::codecvt_utf8_utf16? +// +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || \ + defined(__clang__) || \ + (defined(ICE_CPP11_COMPILER) && defined(__GNUC__) && (__GNUC__ >= 5)) +# define ICE_HAS_CODECVT_UTF8 +#endif + +// +// Support for thread-safe function local static initialization +// (a.k.a. "magic statics") +// +#if defined(ICE_CPP11_MAPPING) || defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && (_MSC_VER >= 1900)) +# define ICE_HAS_THREAD_SAFE_LOCAL_STATIC +#endif + +// +// Compiler extensions to export and import symbols: see the documentation +// for Visual Studio, Solaris Studio and GCC. +// +#if defined(_MSC_VER) +# define ICE_DECLSPEC_EXPORT __declspec(dllexport) +# define ICE_DECLSPEC_IMPORT __declspec(dllimport) +// With Visual Studio, we can import/export member functions without importing/ +// exporting the whole class +# define ICE_MEMBER_IMPORT_EXPORT +#elif (defined(__GNUC__) || defined(__clang__) || defined(__IBMCPP__)) && !defined(__ibmxl__) +# define ICE_DECLSPEC_EXPORT __attribute__((visibility ("default"))) +# define ICE_DECLSPEC_IMPORT __attribute__((visibility ("default"))) +#elif defined(__SUNPRO_CC) +# define ICE_DECLSPEC_EXPORT __global +# define ICE_DECLSPEC_IMPORT /**/ +#else +# define ICE_DECLSPEC_EXPORT /**/ +# define ICE_DECLSPEC_IMPORT /**/ +#endif + +#ifdef ICE_MEMBER_IMPORT_EXPORT +# define ICE_CLASS(API) /**/ +# define ICE_MEMBER(API) API +#else +# define ICE_CLASS(API) API +# define ICE_MEMBER(API) /**/ +#endif + +// With IBM xlC, the visibility attribute must be at the end of the +// declaration of global variables. +#if defined(__IBMCPP__) && !defined(ICE_STATIC_LIBS) +# define ICE_GLOBAL_VAR_SUFFIX __attribute__((visibility ("default"))) +#else +# define ICE_GLOBAL_VAR_SUFFIX /**/ +#endif + +// +// Let's use these extensions with Ice: +// +#ifndef ICE_API +# if defined(ICE_STATIC_LIBS) +# define ICE_API /**/ +# elif defined(ICE_API_EXPORTS) +# define ICE_API ICE_DECLSPEC_EXPORT +# else +# define ICE_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#if defined(_MSC_VER) +# define ICE_DEPRECATED_API(msg) __declspec(deprecated(msg)) +#elif defined(__clang__) +# if __has_extension(attribute_deprecated_with_message) +# define ICE_DEPRECATED_API(msg) __attribute__((deprecated(msg))) +# else +# define ICE_DEPRECATED_API(msg) __attribute__((deprecated)) +# endif +#elif defined(__GNUC__) +# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +// The message option was introduced in GCC 4.5 +# define ICE_DEPRECATED_API(msg) __attribute__((deprecated(msg))) +# else +# define ICE_DEPRECATED_API(msg) __attribute__((deprecated)) +# endif +#else +# define ICE_DEPRECATED_API(msg) /**/ +#endif + +#if defined(__clang__) || defined(__GNUC__) +# define ICE_MAYBE_UNUSED __attribute__((unused)) +#else +# define ICE_MAYBE_UNUSED /**/ +#endif + +#ifdef _WIN32 +# include + +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x600) +// +// Windows provides native condition variables on Vista and later +// +# ifndef ICE_HAS_WIN32_CONDVAR +# define ICE_HAS_WIN32_CONDVAR +# endif +# endif +#endif + +// +// Some include files we need almost everywhere. +// +#include +#include +#include +#include +#include + +#ifndef _WIN32 +# include +# include +# include +#endif + +#ifdef __APPLE__ +# include +#endif + +#if defined(_AIX) && defined(_LARGE_FILES) + // defines macros such as open that we want to use consistently everywhere +# include +#endif + +#ifdef __IBMCPP__ + // TODO: better fix for this warning +# pragma report(disable, "1540-0198") // private inheritance without private keyword +#endif + +// +// The Ice version. +// +#define ICE_STRING_VERSION "3.7.10" // "A.B.C", with A=major, B=minor, C=patch +#define ICE_INT_VERSION 30710 // AABBCC, with AA=major, BB=minor, CC=patch +#define ICE_SO_VERSION "37" // "ABC", with A=major, B=minor, C=patch + +#if !defined(ICE_BUILDING_ICE) && defined(ICE_API_EXPORTS) +# define ICE_BUILDING_ICE +#endif + +#if defined(_MSC_VER) +# if !defined(ICE_STATIC_LIBS) && (!defined(_DLL) || !defined(_MT)) +# error "Only multi-threaded DLL libraries can be used with Ice!" +# endif + +# ifdef ICE_CPP11_MAPPING +# if defined(_DEBUG) +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11D.lib" +# else +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11.lib" +# endif +# else +# if defined(_DEBUG) +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "D.lib" +# else +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION ".lib" +# endif +# endif + +// +// Automatically link with Ice[D|++11|++11D].lib +// +# if !defined(ICE_BUILDING_ICE) && !defined(ICE_BUILDING_SLICE_COMPILERS) +# pragma comment(lib, ICE_LIBNAME("Ice")) +# endif +#endif + +namespace IceUtil +{ + +// +// By deriving from this class, other classes are made non-copyable. +// +class ICE_API noncopyable +{ +protected: + + noncopyable() { } + ~noncopyable() { } // May not be virtual! Classes without virtual + // operations also derive from noncopyable. + +private: + + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +}; + +typedef unsigned char Byte; + +// +// Int64 typedef and ICE_INT64 macro for Int64 literal values +// +// Note that on Windows, long is always 32-bit +// +#if defined(_WIN32) && defined(_MSC_VER) +typedef __int64 Int64; +# define ICE_INT64(n) n##i64 +# define ICE_INT64_FORMAT "%lld" +#elif defined(ICE_64) && !defined(_WIN32) +typedef long Int64; +# define ICE_INT64(n) n##L +# define ICE_INT64_FORMAT "%ld" +#else +typedef long long Int64; +# define ICE_INT64(n) n##LL +# define ICE_INT64_FORMAT "%lld" +#endif + +} + +// +// Macros to facilitate C++98 -> C++11 transition +// +#ifdef ICE_CPP11_MAPPING // C++11 mapping +# include +# include +# define ICE_HANDLE ::std::shared_ptr +# define ICE_INTERNAL_HANDLE ::std::shared_ptr +# define ICE_PROXY_HANDLE ::std::shared_ptr +# define ICE_MAKE_SHARED(T, ...) ::std::make_shared(__VA_ARGS__) +# define ICE_DEFINE_PTR(TPtr, T) using TPtr = ::std::shared_ptr +# define ICE_ENUM(CLASS,ENUMERATOR) CLASS::ENUMERATOR +# define ICE_SCOPED_ENUM(CLASS,ENUMERATOR) CLASS::ENUMERATOR +# define ICE_NULLPTR nullptr +# define ICE_DYNAMIC_CAST(T,V) ::std::dynamic_pointer_cast(V) +# define ICE_SHARED_FROM_THIS shared_from_this() +# define ICE_SHARED_FROM_CONST_THIS(T) const_cast(this)->shared_from_this() +# define ICE_GET_SHARED_FROM_THIS(p) p->shared_from_this() +# define ICE_CHECKED_CAST(T, ...) Ice::checkedCast(__VA_ARGS__) +# define ICE_UNCHECKED_CAST(T, ...) Ice::uncheckedCast(__VA_ARGS__) +# define ICE_DELEGATE(T) T +# define ICE_IN(...) __VA_ARGS__ +# define ICE_SET_EXCEPTION_FROM_CLONE(T, V) T = V +#else // C++98 mapping +# define ICE_HANDLE ::IceUtil::Handle +# define ICE_INTERNAL_HANDLE ::IceInternal::Handle +# define ICE_PROXY_HANDLE ::IceInternal::ProxyHandle +# define ICE_MAKE_SHARED(T, ...) new T(__VA_ARGS__) +# define ICE_DEFINE_PTR(TPtr, T) typedef ::IceUtil::Handle TPtr +# define ICE_ENUM(CLASS,ENUMERATOR) ENUMERATOR +# define ICE_SCOPED_ENUM(CLASS,ENUMERATOR) CLASS##ENUMERATOR +# define ICE_NULLPTR 0 +# define ICE_DYNAMIC_CAST(T,V) T##Ptr::dynamicCast(V) +# define ICE_SHARED_FROM_THIS this +# define ICE_SHARED_FROM_CONST_THIS(T) const_cast(this) +# define ICE_GET_SHARED_FROM_THIS(p) p +# define ICE_CHECKED_CAST(T, ...) T::checkedCast(__VA_ARGS__) +# define ICE_UNCHECKED_CAST(T, ...) T::uncheckedCast(__VA_ARGS__) +# define ICE_DELEGATE(T) T##Ptr +# define ICE_IN(...) const __VA_ARGS__& +# define ICE_SET_EXCEPTION_FROM_CLONE(T, V) T.reset(V) +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ConsoleUtil.h b/Sources/IceCpp/include/IceUtil/ConsoleUtil.h new file mode 100644 index 0000000..735d266 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ConsoleUtil.h @@ -0,0 +1,92 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_CONSOLE_UTIL_H +#define ICE_UTIL_CONSOLE_UTIL_H + +#include +#include +#include + +namespace IceUtilInternal +{ + +#if defined(_WIN32) + +class ConsoleUtil; +ICE_DEFINE_PTR(ConsoleUtilPtr, ConsoleUtil); + +class ICE_API ConsoleUtil +# ifndef ICE_CPP11_MAPPING + : public IceUtil::Shared +# endif +{ +public: + + ConsoleUtil(); + void output(const std::string&) const; + void error(const std::string&) const; + +private: + + std::string toConsoleEncoding(const std::string&) const; + IceUtil::StringConverterPtr _converter; + IceUtil::StringConverterPtr _consoleConverter; +}; + +const ICE_API ConsoleUtil& getConsoleUtil(); + +class ICE_API ConsoleOut +{ +public: + + ConsoleOut& operator<<(ConsoleOut& (*pf)(ConsoleOut&)); +}; + +class ICE_API ConsoleErr +{ +public: + + ConsoleErr& operator<<(ConsoleErr& (*pf)(ConsoleErr&)); +}; + +template +ConsoleOut& +operator<<(ConsoleOut& out, const T& val) +{ + std::ostringstream s; + s << val; + getConsoleUtil().output(s.str()); + return out; +} + +ICE_API ConsoleOut& endl(ConsoleOut&); +ICE_API ConsoleOut& flush(ConsoleOut&); + +template +ConsoleErr& +operator<<(ConsoleErr& err, const T& val) +{ + std::ostringstream s; + s << val; + getConsoleUtil().error(s.str()); + return err; +} + +ICE_API ConsoleErr& endl(ConsoleErr&); +ICE_API ConsoleErr& flush(ConsoleErr&); + +extern ICE_API ConsoleOut consoleOut ICE_GLOBAL_VAR_SUFFIX; +extern ICE_API ConsoleErr consoleErr ICE_GLOBAL_VAR_SUFFIX; + +#else + +extern ICE_API std::ostream& consoleOut ICE_GLOBAL_VAR_SUFFIX; +extern ICE_API std::ostream& consoleErr ICE_GLOBAL_VAR_SUFFIX; + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ConvertUTF.h b/Sources/IceCpp/include/IceUtil/ConvertUTF.h new file mode 100644 index 0000000..2b4b365 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ConvertUTF.h @@ -0,0 +1,147 @@ +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_CONVERT_UTF_H +#define ICE_UTIL_CONVERT_UTF_H + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Header file. + + Several funtions are included here, forming a complete set of + conversions between the three formats. UTF-7 is not included + here, but is handled in a separate source file. + + Each of these routines takes pointers to input buffers and output + buffers. The input buffers are const. + + Each routine converts the text between *sourceStart and sourceEnd, + putting the result into the buffer between *targetStart and + targetEnd. Note: the end pointers are *after* the last item: e.g. + *(sourceEnd - 1) is the last item. + + The return result indicates whether the conversion was successful, + and if not, whether the problem was in the source or target buffers. + (Only the first encountered problem is indicated.) + + After the conversion, *sourceStart and *targetStart are both + updated to point to the end of last text successfully converted in + the respective buffers. + + Input parameters: + sourceStart - pointer to a pointer to the source buffer. + The contents of this are modified on return so that + it points at the next thing to be converted. + targetStart - similarly, pointer to pointer to the target buffer. + sourceEnd, targetEnd - respectively pointers to the ends of the + two buffers, for overflow checking only. + + These conversion functions take a ConversionFlags argument. When this + flag is set to strict, both irregular sequences and isolated surrogates + will cause an error. When the flag is set to lenient, both irregular + sequences and isolated surrogates are converted. + + Whether the flag is strict or lenient, all illegal sequences will cause + an error return. This includes sequences such as: , , + or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code + must check for illegal sequences. + + When the flag is set to lenient, characters over 0x10FFFF are converted + to the replacement character; otherwise (when the flag is set to strict) + they constitute an error. + + Output parameters: + The value "sourceIllegal" is returned from some routines if the input + sequence is malformed. When "sourceIllegal" is returned, the source + value will point to the illegal value that caused the problem. E.g., + in UTF-8 when a sequence is malformed, it points to the start of the + malformed sequence. + + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Fixes & updates, Sept 2001. + +------------------------------------------------------------------------ */ + +namespace IceUtilInternal +{ + +enum ConversionFlags +{ + strictConversion = 0, + lenientConversion +}; + +enum ConversionResult +{ + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +}; + +/* --------------------------------------------------------------------- + The following 4 definitions are compiler-specific. + The C standard does not guarantee that wchar_t has at least + 16 bits, so wchar_t is no less portable than unsigned short! + All should be unsigned values to avoid sign extension during + bit mask & shift operations. +------------------------------------------------------------------------ */ + +typedef unsigned int UTF32; /* at least 32 bits */ +typedef unsigned short UTF16; /* at least 16 bits */ +typedef unsigned char UTF8; /* typically 8 bits */ +typedef bool Boolean; /* 0 or 1 */ + +/* Some fundamental constants */ +#define UNI_REPLACEMENT_CHAR static_cast(0x0000FFFD) +#define UNI_MAX_BMP static_cast(0x0000FFFF) +#define UNI_MAX_UTF16 static_cast(0x0010FFFF) +#define UNI_MAX_UTF32 static_cast(0x7FFFFFFF) +#define UNI_MAX_LEGAL_UTF32 static_cast(0x0010FFFF) + +ConversionResult ConvertUTF8toUTF16( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF16toUTF8 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF8toUTF32( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF32toUTF8( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +bool isLegalUTF8Sequence(const UTF8* source, const UTF8* end); + +/* --------------------------------------------------------------------- */ + +} +#endif diff --git a/Sources/IceCpp/include/IceUtil/CountDownLatch.h b/Sources/IceCpp/include/IceUtil/CountDownLatch.h new file mode 100644 index 0000000..7622df6 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/CountDownLatch.h @@ -0,0 +1,45 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_COUNT_DOWN_LATCH_H +#define ICE_UTIL_COUNT_DOWN_LATCH_H + +#include + +namespace IceUtilInternal +{ + +// +// See java.util.concurrent.CountDownLatch in Java 1.5 +// + +class ICE_API CountDownLatch +{ +public: + + CountDownLatch(int); + ~CountDownLatch(); + + void await() const; + void countDown(); + int getCount() const; + +private: + +#ifdef _WIN32 + mutable LONG _count; + HANDLE _event; +#else + int _count; + mutable pthread_mutex_t _mutex; + mutable pthread_cond_t _cond; + + inline void lock() const; + inline void unlock() const; +#endif +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/CtrlCHandler.h b/Sources/IceCpp/include/IceUtil/CtrlCHandler.h new file mode 100644 index 0000000..0793068 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/CtrlCHandler.h @@ -0,0 +1,92 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_CTRL_C_HANDLER_H +#define ICE_UTIL_CTRL_C_HANDLER_H + +#include +#include + +namespace IceUtil +{ + +/** + * Invoked when a signal occurs. The callback must not raise exceptions. + * On Linux and macOS, the callback is NOT a signal handler and can call + * functions that are not async-signal safe. + * @param sig The signal number that occurred. + */ +#ifdef ICE_CPP11_MAPPING +using CtrlCHandlerCallback = std::function; +#else +typedef void (*CtrlCHandlerCallback)(int sig); +#endif + +/** + * Provides a portable way to handle Ctrl-C and Ctrl-C like signals. + * On Linux and macOS, the CtrlCHandler handles SIGHUP, SIGINT and SIGTERM. + * On Windows, it is essentially a wrapper for SetConsoleCtrlHandler(). + * + * \headerfile Ice/Ice.h + */ +class ICE_API CtrlCHandler +{ +public: + + /** + * Registers a callback function that handles Ctrl-C like signals. + * On Linux and macOS, this constructor masks the SIGHUP, SIGINT and SIGTERM + * signals and then creates a thread that waits for these signals using sigwait. + * On Windows, this constructor calls SetConsoleCtrlCHandler to register a handler + * routine that calls the supplied callback function. + * Only a single CtrlCHandler object can exist in a process at a give time. + * @param cb The callback function to invoke when a signal is received. + */ + explicit CtrlCHandler(CtrlCHandlerCallback cb = ICE_NULLPTR); + + /** + * Unregisters the callback function. + * On Linux and macOS, this destructor joins and terminates the thread created + * by the constructor but does not "unmask" SIGHUP, SIGINT and SIGTERM. As a result, + * these signals are ignored after this destructor completes. + * On Windows, this destructor unregisters the SetConsoleCtrlHandler handler + * routine, and as a result a Ctrl-C or similar signal will terminate the application + * after this destructor completes. + */ + ~CtrlCHandler(); + + /** + * Replaces the signal callback. + * @param cb The new callback. + * @return The old callback, or nil if no callback is currently set. + */ + CtrlCHandlerCallback setCallback(CtrlCHandlerCallback cb); + + /** + * Obtains the signal callback. + * @return The callback. + */ + CtrlCHandlerCallback getCallback() const; +}; + +/** + * Raised by the CtrlCHandler constructor if another CtrlCHandler already exists. + * + * \headerfile Ice/Ice.h + */ +class ICE_API CtrlCHandlerException : public ExceptionHelper +{ +public: + + CtrlCHandlerException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual CtrlCHandlerException* ice_clone() const; +#endif +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/DisableWarnings.h b/Sources/IceCpp/include/IceUtil/DisableWarnings.h new file mode 100644 index 0000000..e12ac38 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/DisableWarnings.h @@ -0,0 +1,44 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_DISABLEWARNINGS_H +#define ICE_UTIL_DISABLEWARNINGS_H + +// +// This header file disables various compiler warnings that we don't want. +// +// IMPORTANT: Do *not* include this header file in another public header file! +// Doing this may potentially disable the warnings in the source +// code of our customers, which would be bad. Only include this +// header file in Ice *source* files! +// + +// +// Microsoft Visual C++ +// +#if defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE 1 // C4996 '' was declared deprecated +# pragma warning(disable:4996) // C4996 '' was declared deprecated +# pragma warning(disable:4800) // C4800 forcing value to bool 'true' or 'false' (performance warning) + +# if (_MSC_VER < 1700) +# pragma warning(disable:4355) // C4355 'this' : used in base member initializer list +# endif +#endif + +// +// GCC +// +#if defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +// +// Clang +// +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Exception.h b/Sources/IceCpp/include/IceUtil/Exception.h new file mode 100644 index 0000000..249dd05 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Exception.h @@ -0,0 +1,394 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_EXCEPTION_H +#define ICE_UTIL_EXCEPTION_H + +#include + +#include +#include + +namespace IceUtil +{ + +/** + * Abstract base class for all Ice exceptions. Use the Ice::Exception alias instead + * of IceUtil::Exception. + * \headerfile Ice/Ice.h + */ +class ICE_API Exception : public std::exception +{ +public: + + /** + * Constructs the exception. Equivalent to Exception(nullptr, 0). + */ + Exception(); + + /** + * Constructs the exception. + * @param file The file where this exception is constructed. + * @param line The line where this exception is constructed. + */ + Exception(const char* file, int line); + +#ifndef ICE_CPP11_COMPILER + virtual ~Exception() throw() = 0; +#endif + + /** + * Returns the type ID of this exception. This corresponds to the Slice + * type ID for Slice-defined exceptions, and to a similar fully scoped name + * for other exceptions. For example "::IceUtil::SyscallException". + * @return The type ID of this exception + */ + virtual std::string ice_id() const = 0; + + /** + * Outputs a description of this exception to a stream. + * @param os The output stream. + */ + virtual void ice_print(std::ostream& os) const; + + /** + * Returns a description of this exception. + * @return The description. + */ + virtual const char* what() const ICE_NOEXCEPT; +#ifdef ICE_CPP11_MAPPING + + /** + * Returns a shallow polymorphic copy of this exception. + * @return A unique_ptr to the new shallow copy. + */ + std::unique_ptr ice_clone() const; +#else + /** + * Returns a shallow polymorphic copy of this exception. + * @return A pointer to the new shallow copy. The caller owns the returned object. + */ + virtual Exception* ice_clone() const = 0; + + ICE_DEPRECATED_API("ice_name() is deprecated, use ice_id() instead.") + std::string ice_name() const; +#endif + + /** + * Throws this exception. + */ + virtual void ice_throw() const = 0; + + /** + * Returns the name of the file where this exception was constructed. + * @return The file name. + */ + const char* ice_file() const; + + /** + * Returns the line number where this exception was constructed. + * @return The line number. + */ + int ice_line() const; + + /** + * Returns the stack trace at the point this exception was constructed + * @return The stack trace as a string. + */ + std::string ice_stackTrace() const; + +protected: + +#ifdef ICE_CPP11_MAPPING + /// \cond INTERNAL + virtual Exception* ice_cloneImpl() const = 0; + /// \endcond +#endif + +private: + + const char* _file; + int _line; + const std::vector _stackFrames; + mutable ::std::string _str; // Initialized lazily in what(). +}; + +ICE_API std::ostream& operator<<(std::ostream&, const Exception&); + +#ifdef ICE_CPP11_MAPPING + +/** + * Helper template for the implementation of Ice::Exception. + * It implements ice_clone and ice_throw. + * \headerfile Ice/Ice.h + */ +template +class ExceptionHelper : public B +{ +public: + + using B::B; + + std::unique_ptr ice_clone() const + { + return std::unique_ptr(static_cast(ice_cloneImpl())); + } + + virtual void ice_throw() const override + { + throw static_cast(*this); + } + +protected: + + /// \cond INTERNAL + virtual Exception* ice_cloneImpl() const override + { + return new E(static_cast(*this)); + } + /// \endcond +}; + +#else // C++98 mapping + +/** + * Helper template for the implementation of Ice::Exception. It implements ice_throw. + * \headerfile Ice/Ice.h + */ +template +class ExceptionHelper : public Exception +{ +public: + + ExceptionHelper() + { + } + + ExceptionHelper(const char* file, int line) : Exception(file, line) + { + } + + virtual void ice_throw() const + { + throw static_cast(*this); + } +}; + +#endif + +/** + * This exception indicates an attempt to dereference a null IceUtil::Handle or + * IceInternal::Handle. + * \headerfile Ice/Ice.h + */ +class ICE_API NullHandleException : public ExceptionHelper +{ +public: + + NullHandleException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual NullHandleException* ice_clone() const; +#endif +}; + +/** + * This exception indicates that a function was called with an illegal parameter + * value. It is used only by the Slice to C++98 mapping; std::invalid_argument is + * used by the Slice to C++11 mapping. + * \headerfile Ice/Ice.h + */ +class ICE_API IllegalArgumentException : public ExceptionHelper +{ +public: + + IllegalArgumentException(const char*, int); + IllegalArgumentException(const char*, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~IllegalArgumentException() throw(); +#endif + + virtual std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual IllegalArgumentException* ice_clone() const; +#endif + + /** + * Provides the reason this exception was thrown. + * @return The reason. + */ + std::string reason() const; + +private: + + const std::string _reason; +}; + +/** + * This exception indicates the failure of a string conversion. + * \headerfile Ice/Ice.h + */ +class ICE_API IllegalConversionException : public ExceptionHelper +{ +public: + + IllegalConversionException(const char*, int); + IllegalConversionException(const char*, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~IllegalConversionException() throw(); +#endif + + virtual std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual IllegalConversionException* ice_clone() const; +#endif + + /** + * Provides the reason this exception was thrown. + * @return The reason. + */ + std::string reason() const; + +private: + + const std::string _reason; +}; + +/** + * This exception indicates the failure of a system call. + * \headerfile Ice/Ice.h + */ +class ICE_API SyscallException : public ExceptionHelper +{ +public: + + SyscallException(const char*, int, int); + +#ifndef ICE_CPP11_COMPILER + virtual ~SyscallException() throw(); +#endif + + virtual std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual SyscallException* ice_clone() const; +#endif + + /** + * Provides the error number returned by the system call. + * @return The error number. + */ + int error() const; + +private: + + const int _error; +}; + +#ifdef ICE_CPP11_MAPPING + +template +using SyscallExceptionHelper = ExceptionHelper; + +#else // C++98 mapping + +/** +* Helper template for the implementation of SyscallException. It implements +* ice_throw. +* \headerfile Ice/Ice.h +*/ +template +class SyscallExceptionHelper : public SyscallException +{ +public: + + SyscallExceptionHelper(const char* file, int line, int errorCode) : + SyscallException(file, line, errorCode) + { + } + + virtual void ice_throw() const + { + throw static_cast(*this); + } +}; + +#endif + +/** + * This exception indicates the failure to lock a file. + * \headerfile Ice/Ice.h + */ +class ICE_API FileLockException : public ExceptionHelper +{ +public: + + FileLockException(const char*, int, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~FileLockException() throw(); +#endif + + virtual std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual FileLockException* ice_clone() const; +#endif + + /** + * Returns the path to the file. + * @return The file path. + */ + std::string path() const; + + /** + * Returns the error number for the failed locking attempt. + * @return The error number. + */ + int error() const; + +private: + + const int _error; + std::string _path; +}; + +/** + * This exception indicates an IceUtil::Optional is not set. + * Used only by the Slice to C++98 mapping. + * \headerfile Ice/Ice.h + */ +class ICE_API OptionalNotSetException : public ExceptionHelper +{ +public: + + OptionalNotSetException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual OptionalNotSetException* ice_clone() const; +#endif +}; + +} + +namespace IceUtilInternal +{ + +enum StackTraceImpl { STNone, STDbghelp, STLibbacktrace, STLibbacktracePlus, STBacktrace }; + +ICE_API StackTraceImpl stackTraceImpl(); + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/FileUtil.h b/Sources/IceCpp/include/IceUtil/FileUtil.h new file mode 100644 index 0000000..dbde8d3 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/FileUtil.h @@ -0,0 +1,140 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_FILE_UTIL_H +#define ICE_FILE_UTIL_H + +#include +#include +#include + +#include +#include +#include + +namespace IceUtilInternal +{ + +extern const ICE_API std::string pathsep; +extern const ICE_API std::string separator; + +// +// Detemine if path is an absolute path. +// +ICE_API bool isAbsolutePath(const std::string&); + +// +// Determine if a file exists. +// +ICE_API bool fileExists(const std::string&); + +// +// Determine if a directory exists. +// +ICE_API bool directoryExists(const std::string&); + +// +// Determine if a directory exists and is empty. +// +ICE_API bool isEmptyDirectory(const std::string&); + +#ifdef _WIN32 + +#if defined(__MINGW32__) +typedef struct _stat structstat; +#else +typedef struct _stat64i32 structstat; +#endif + +#ifdef _MSC_VER +#ifndef O_RDONLY +# define O_RDONLY _O_RDONLY +#endif + +#ifndef O_BINARY +# define O_BINARY _O_BINARY +#endif + +#ifndef S_ISDIR +# define S_ISDIR(mode) ((mode) & _S_IFDIR) +#endif + +#ifndef S_ISREG +# define S_ISREG(mode) ((mode) & _S_IFREG) +#endif +#endif + +#else + +typedef struct stat structstat; +# define O_BINARY 0 + +#endif + +// +// OS stat +// +ICE_API int stat(const std::string&, structstat*); +ICE_API int remove(const std::string&); +ICE_API int rename(const std::string&, const std::string&); +ICE_API int rmdir(const std::string&); + +ICE_API int mkdir(const std::string&, int); +ICE_API FILE* fopen(const std::string&, const std::string&); +ICE_API FILE* freopen(const std::string&, const std::string&, FILE*); +ICE_API int open(const std::string&, int); +ICE_API int getcwd(std::string&); + +ICE_API int unlink(const std::string&); +ICE_API int close(int); + +// +// This class is used to implement process file locking. This class +// is not intended to do file locking within the same process. +// +class ICE_API FileLock : public IceUtil::Shared, public IceUtil::noncopyable +{ +public: + // + // The constructor opens the given file (eventually creating it) + // and acquires a lock on the file or throws FileLockException if + // the file couldn't be locked. + // + // If the lock can be acquired, the process pid is written to the + // file. + // + FileLock(const std::string&); + + // + // The destructor releases the lock and removes the file. + // + virtual ~FileLock(); + +private: + +#ifdef _WIN32 + HANDLE _fd; +#else + int _fd; +#endif + std::string _path; +}; + +typedef IceUtil::Handle FileLockPtr; + +// +// Use streamFilename to construct the filename given to std stream classes +// like ifstream and ofstream. +// +#if defined(_WIN32) && !defined(__MINGW32__) +ICE_API std::wstring streamFilename(const std::string&); +#else +inline std::string streamFilename(const std::string& filename) +{ + return filename; +} +#endif + +} +#endif diff --git a/Sources/IceCpp/include/IceUtil/Functional.h b/Sources/IceCpp/include/IceUtil/Functional.h new file mode 100644 index 0000000..1bcce87 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Functional.h @@ -0,0 +1,389 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_FUNCTIONAL_H +#define ICE_UTIL_FUNCTIONAL_H + +#include + +#if !defined(ICE_CPP11_MAPPING) && (ICE_CPLUSPLUS < 201703L) + +#include +#include + +namespace IceUtilInternal +{ + +// ---------------------------------------------------------------------- +// Various function objects that work with handles instead of plain +// pointers. +// ---------------------------------------------------------------------- + +template +class MemFun : public std::unary_function +{ + typedef R (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit MemFun(MemberFN p) : _mfn(p) { } + R operator()(H handle) const + { + return (handle.get() ->* _mfn)(); + } +}; + +template +class MemFun1 : public std::binary_function +{ + typedef R (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit MemFun1(MemberFN p) : _mfn(p) { } + R operator()(H handle, A arg) const + { + return (handle.get() ->* _mfn)(arg); + } +}; + +template +class VoidMemFun : public std::unary_function +{ + typedef void (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit VoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(H handle) const + { + (handle.get() ->* _mfn)(); + } +}; + +template +class VoidMemFun1 : public std::binary_function +{ + typedef void (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit VoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(H handle, A arg) const + { + (handle.get() ->* _mfn)(arg); + } +}; + +template +class SecondMemFun : public std::unary_function, R> +{ + typedef R (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit SecondMemFun(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair) const + { + return (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondMemFun1 : public std::binary_function, A, R> +{ + typedef R (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit SecondMemFun1(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair, A arg) const + { + return (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class SecondVoidMemFun : public std::unary_function, void> +{ + typedef void (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit SecondVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair) const + { + (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondVoidMemFun1 : public std::binary_function, A, void> +{ + typedef void (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit SecondVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair, A arg) const + { + (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class ConstMemFun : public std::unary_function +{ + typedef R (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit ConstMemFun(MemberFN p) : _mfn(p) { } + R operator()(H handle) const + { + return (handle.get() ->* _mfn)(); + } +}; + +template +class ConstMemFun1 : public std::binary_function +{ + typedef R (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit ConstMemFun1(MemberFN p) : _mfn(p) { } + R operator()(H handle, A arg) const + { + return (handle.get() ->* _mfn)(arg); + } +}; + +template +class ConstVoidMemFun : public std::unary_function +{ + typedef void (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit ConstVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(H handle) const + { + (handle.get() ->* _mfn)(); + } +}; + +template +class ConstVoidMemFun1 : public std::binary_function +{ + typedef void (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit ConstVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(H handle, A arg) const + { + (handle.get() ->* _mfn)(arg); + } +}; + +template +class SecondConstMemFun : public std::unary_function, R> +{ + typedef R (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit SecondConstMemFun(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair) const + { + return (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondConstMemFun1 : public std::binary_function, A, R> +{ + typedef R (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit SecondConstMemFun1(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair, A arg) const + { + return (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class SecondConstVoidMemFun : public std::unary_function, void> +{ + typedef void (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit SecondConstVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair) const + { + (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondConstVoidMemFun1 : public std::binary_function, A, void> +{ + typedef void (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit SecondConstVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair, A arg) const + { + (pair.second.get() ->* _mfn)(arg); + } +}; + +} + +// ---------------------------------------------------------------------- +// Inline functions that return function objects that work with +// IceUtil::Handle +// ---------------------------------------------------------------------- + +namespace IceUtil +{ + +template +inline ::IceUtilInternal::MemFun > +memFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::MemFun >(p); +} + +template +inline ::IceUtilInternal::MemFun1, A> +memFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::MemFun1, A>(p); +} + +template +inline ::IceUtilInternal::VoidMemFun > +voidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::VoidMemFun >(p); +} + +template +inline ::IceUtilInternal::VoidMemFun1, A> +voidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::VoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondMemFun > +secondMemFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::SecondMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondMemFun1, A> +secondMemFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::SecondMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun > +secondVoidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::SecondVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun1, A> +secondVoidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::SecondVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstMemFun > +constMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstMemFun1, A> +constMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun > +constVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun1, A> +constVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun > +secondConstMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun1, A> +secondConstMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun > +secondConstVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun1, A> +secondConstVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun1, A>(p); +} + +} + +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Handle.h b/Sources/IceCpp/include/IceUtil/Handle.h new file mode 100644 index 0000000..57bd499 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Handle.h @@ -0,0 +1,261 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_HANDLE_H +#define ICE_UTIL_HANDLE_H + +#include +#include + +// +// "Handle" or "smart pointer" class for classes derived from +// IceUtil::Shared, IceUtil::SimpleShared, or IceInternal::GCShared. +// +namespace IceUtil +{ + +template +class HandleBase +{ +public: + + typedef T element_type; + + T* get() const + { + return _ptr; + } + + T* operator->() const + { + if(!_ptr) + { + // + // We don't throw directly NullHandleException here to + // keep the code size of this method to a minimun (the + // assembly code for throwing an exception is much bigger + // than just a function call). This maximises the chances + // of inlining by compiler optimization. + // + throwNullHandleException(__FILE__, __LINE__); + } + + return _ptr; + } + + T& operator*() const + { + if(!_ptr) + { + // + // We don't throw directly NullHandleException here to + // keep the code size of this method to a minimun (the + // assembly code for throwing an exception is much bigger + // than just a function call). This maximises the chances + // of inlining by compiler optimization. + // + throwNullHandleException(__FILE__, __LINE__); + } + + return *_ptr; + } + + operator bool() const + { + return _ptr ? true : false; + } + + void swap(HandleBase& other) + { + std::swap(_ptr, other._ptr); + } + + T* _ptr; + +private: + + void throwNullHandleException(const char *, int) const; +}; + +template inline void +HandleBase::throwNullHandleException(const char* file, int line) const +{ + throw NullHandleException(file, line); +} + +template +inline bool operator==(const HandleBase& lhs, const HandleBase& rhs) +{ + T* l = lhs.get(); + U* r = rhs.get(); + if(l && r) + { + return *l == *r; + } + + // Note: don't use if { } else { }. This causes lots warnings when + // compiling with GCC and optimization enabled. See bug 2330. + return !l && !r; +} + +template +inline bool operator!=(const HandleBase& lhs, const HandleBase& rhs) +{ + return !operator==(lhs, rhs); +} + +template +inline bool operator<(const HandleBase& lhs, const HandleBase& rhs) +{ + T* l = lhs.get(); + U* r = rhs.get(); + if(l && r) + { + return *l < *r; + } + + // Note: don't use if { } else { }. This causes lots warnings when + // compiling with GCC and optimization enabled. See bug 2330. + return !l && r; +} + +template +inline bool operator<=(const HandleBase& lhs, const HandleBase& rhs) +{ + return lhs < rhs || lhs == rhs; +} + +template +inline bool operator>(const HandleBase& lhs, const HandleBase& rhs) +{ + return !(lhs < rhs || lhs == rhs); +} + +template +inline bool operator>=(const HandleBase& lhs, const HandleBase& rhs) +{ + return !(lhs < rhs); +} + +template +class Handle : public HandleBase +{ +public: + + Handle(T* p = 0) + { + this->_ptr = p; + + if(this->_ptr) + { + this->_ptr->__incRef(); + } + } + + template + Handle(const Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + this->_ptr->__incRef(); + } + } + + Handle(const Handle& r) + { + this->_ptr = r._ptr; + + if(this->_ptr) + { + this->_ptr->__incRef(); + } + } + + ~Handle() + { + if(this->_ptr) + { + this->_ptr->__decRef(); + } + } + + Handle& operator=(T* p) + { + if(this->_ptr != p) + { + if(p) + { + p->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = p; + + if(ptr) + { + ptr->__decRef(); + } + } + return *this; + } + + template + Handle& operator=(const Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + r._ptr->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = r._ptr; + + if(ptr) + { + ptr->__decRef(); + } + } + return *this; + } + + Handle& operator=(const Handle& r) + { + if(this->_ptr != r._ptr) + { + if(r._ptr) + { + r._ptr->__incRef(); + } + + T* ptr = this->_ptr; + this->_ptr = r._ptr; + + if(ptr) + { + ptr->__decRef(); + } + } + return *this; + } + + template + static Handle dynamicCast(const HandleBase& r) + { + return Handle(dynamic_cast(r._ptr)); + } + + template + static Handle dynamicCast(Y* p) + { + return Handle(dynamic_cast(p)); + } +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/IceUtil.h b/Sources/IceCpp/include/IceUtil/IceUtil.h new file mode 100644 index 0000000..a64922f --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/IceUtil.h @@ -0,0 +1,40 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_ICE_UTIL_H +#define ICE_UTIL_ICE_UTIL_H + +#include + +// +// This file must include *all* headers of IceUtil, except +// for DisableWarnings.h and headers with only IceUtilInternal symbols +// + +#include +#include +#include +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#endif diff --git a/Sources/IceCpp/include/IceUtil/InputUtil.h b/Sources/IceCpp/include/IceUtil/InputUtil.h new file mode 100644 index 0000000..7b80875 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/InputUtil.h @@ -0,0 +1,42 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_INPUT_UTIL_H +#define ICE_UTIL_INPUT_UTIL_H + +#include +#include + +namespace IceUtilInternal +{ + +// +// Portable strtoll/_strtoi64 +// +ICE_API IceUtil::Int64 strToInt64(const char*, char**, int); + +// +// stringToInt64 converts a string into a signed 64-bit integer. +// It's a simple wrapper around strToInt64. +// +// Semantics: +// +// - Ignore leading whitespace +// +// - If the string starts with '0', parse as octal +// +// - If the string starts with "0x" or "0X", parse as hexadecimal +// +// - Otherwise, parse as decimal +// +// - return value == true indicates a successful conversion and result contains the converted value +// - return value == false indicates an unsuccessful conversion: +// - result == 0 indicates that no digits were available for conversion +// - result == "Int64 Min" or result == "Int64 Max" indicate underflow or overflow. +// +ICE_API bool stringToInt64(const std::string&, IceUtil::Int64&); + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Iterator.h b/Sources/IceCpp/include/IceUtil/Iterator.h new file mode 100644 index 0000000..948305b --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Iterator.h @@ -0,0 +1,31 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_ITERATOR_H +#define ICE_UTIL_ITERATOR_H + +#include + +namespace IceUtilInternal +{ + +template +inline typename ForwardIterator::difference_type +distance(ForwardIterator first, ForwardIterator last) +{ +// +// Work-around for a limitation in the standard library provided +// with the Sun C++ 5.x compilers +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + + ForwardIterator::difference_type result = 0; + std::distance(first, last, result); + return result; +#else + return ::std::distance(first, last); +#endif +} + +} +#endif diff --git a/Sources/IceCpp/include/IceUtil/Lock.h b/Sources/IceCpp/include/IceUtil/Lock.h new file mode 100644 index 0000000..ad713e3 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Lock.h @@ -0,0 +1,128 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_LOCK_H +#define ICE_UTIL_LOCK_H + +#include +#include + +namespace IceUtil +{ + +// +// Forward declarations. +// +class Cond; + +// LockT and TryLockT are the preferred construct to lock/tryLock/unlock +// simple and recursive mutexes. You typically allocate them on the +// stack to hold a lock on a mutex. +// LockT and TryLockT are not recursive: you cannot acquire several times +// in a row a lock with the same Lock or TryLock object. +// +// We must name this LockT instead of Lock, because otherwise some +// compilers (such as Sun C++ 5.4) have problems with constructs +// such as: +// +// class Foo +// { +// // ... +// typedef Lock Lock; +// } +// +template +class LockT +{ +public: + + LockT(const T& mutex) : + _mutex(mutex) + { + _mutex.lock(); + _acquired = true; + } + + ~LockT() + { + if (_acquired) + { + _mutex.unlock(); + } + } + + void acquire() const + { + if (_acquired) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + _mutex.lock(); + _acquired = true; + } + + bool tryAcquire() const + { + if (_acquired) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + _acquired = _mutex.tryLock(); + return _acquired; + } + + void release() const + { + if (!_acquired) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + _mutex.unlock(); + _acquired = false; + } + + bool acquired() const + { + return _acquired; + } + +protected: + + // TryLockT's contructor + LockT(const T& mutex, bool) : + _mutex(mutex) + { + _acquired = _mutex.tryLock(); + } + +private: + + // Not implemented; prevents accidental use. + // + LockT(const LockT&); + LockT& operator=(const LockT&); + + const T& _mutex; + mutable bool _acquired; + + friend class Cond; +}; + +// +// Must be named TryLockT, not TryLock. See the comment for LockT for +// an explanation. +// +template +class TryLockT : public LockT +{ +public: + + TryLockT(const T& mutex) : + LockT(mutex, true) + {} +}; + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Monitor.h b/Sources/IceCpp/include/IceUtil/Monitor.h new file mode 100644 index 0000000..9e8cc8f --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Monitor.h @@ -0,0 +1,243 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_MONITOR_H +#define ICE_UTIL_MONITOR_H + +#include +#include +#include + +namespace IceUtil +{ + +// +// This monitor implements the Mesa monitor semantics. That is any +// calls to notify() or notifyAll() are delayed until the monitor is +// unlocked. +// +template +class Monitor +{ +public: + + typedef LockT > Lock; + typedef TryLockT > TryLock; + + Monitor(); + ~Monitor(); + + // + // Note that lock/tryLock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + void lock() const; + void unlock() const; + bool tryLock() const; + + void wait() const; + bool timedWait(const Time&) const; + void notify(); + void notifyAll(); + +private: + + // noncopyable + Monitor(const Monitor&); + void operator=(const Monitor&); + + void notifyImpl(int) const; + + mutable Cond _cond; + T _mutex; + mutable int _nnotify; +}; + +} // End namespace IceUtil + +// +// Since this monitor implements the Mesa monitor semantics calls to +// notify() or notifyAll() are delayed until the monitor is +// unlocked. This can happen either due to a call to unlock(), or a +// call to wait(). The _nnotify flag keeps track of the number of +// pending notification calls. -1 indicates a broadcast, a positive +// number indicates calls to notify(). The _nnotify flag is reset +// upon initial acquisition of the monitor lock (either through a call +// to lock(), or a return from wait(). +// + +template inline +IceUtil::Monitor::Monitor() : + _nnotify(0) +{ +} + +template inline +IceUtil::Monitor::~Monitor() +{ +} + +template inline void +IceUtil::Monitor::lock() const +{ + _mutex.lock(); + if(_mutex.willUnlock()) + { + // + // On the first mutex acquisition reset the number pending + // notifications. + // + _nnotify = 0; + } +} + +template inline void +IceUtil::Monitor::unlock() const +{ + if(_mutex.willUnlock()) + { + // + // Perform any pending notifications. + // + notifyImpl(_nnotify); + } + _mutex.unlock(); + +/* + int nnotify = _nnotify; + if(_mutex.unlock()) + { + // + // Perform any pending notifications. + // + notifyImpl(nnotify); + } +*/ +} + +template inline bool +IceUtil::Monitor::tryLock() const +{ + bool result = _mutex.tryLock(); + if(result && _mutex.willUnlock()) + { + // + // On the first mutex acquisition reset the number pending + // notifications. + // + _nnotify = 0; + } + return result; +} + +template inline void +IceUtil::Monitor::wait() const +{ + // + // Perform any pending notifies + // + notifyImpl(_nnotify); + + // + // Wait for a notification + // + try + { + _cond.waitImpl(_mutex); + // + // Reset the nnotify count once wait() returns. + // + } + catch(...) + { + _nnotify = 0; + throw; + } + + _nnotify = 0; +} + +template inline bool +IceUtil::Monitor::timedWait(const Time& timeout) const +{ + // + // Perform any pending notifies. + // + notifyImpl(_nnotify); + + bool rc; + // + // Wait for a notification. + // + try + { + rc = _cond.timedWaitImpl(_mutex, timeout); + + // + // Reset the nnotify count once wait() returns. + // + } + catch(...) + { + _nnotify = 0; + throw; + } + + _nnotify = 0; + return rc; +} + +template inline void +IceUtil::Monitor::notify() +{ + // + // Increment the _nnotify flag, unless a broadcast has already + // been requested. + // + if(_nnotify != -1) + { + ++_nnotify; + } +} + +template inline void +IceUtil::Monitor::notifyAll() +{ + // + // -1 (indicates broadcast) + // + _nnotify = -1; +} + +template inline void +IceUtil::Monitor::notifyImpl(int nnotify) const +{ + // + // Zero indicates no notifies. + // + if(nnotify != 0) + { + // + // -1 means notifyAll. + // + if(nnotify == -1) + { + _cond.broadcast(); + return; + } + else + { + // + // Otherwise notify n times. + // + while(nnotify > 0) + { + _cond.signal(); + --nnotify; + } + } + } +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Mutex.h b/Sources/IceCpp/include/IceUtil/Mutex.h new file mode 100644 index 0000000..6f387bb --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Mutex.h @@ -0,0 +1,349 @@ + +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_MUTEX_H +#define ICE_UTIL_MUTEX_H + +#include +#include +#include +#include + +namespace IceUtil +{ + +// +// Forward declaration for friend. +// +class Cond; + +// +// Simple non-recursive Mutex implementation. +// +// Don't use noncopyable otherwise you end up with warnings like this: +// +// In file included from Connection.cpp:20: +// ../../include/Ice/Outgoing.h:88: warning: direct base +// `IceUtil::noncopyable' inaccessible in `IceInternal::Outgoing' due +// to ambiguity +// +class ICE_API Mutex +{ +public: + + // + // Lock & TryLock typedefs. + // + typedef LockT Lock; + typedef TryLockT TryLock; + + inline Mutex(); + inline Mutex(MutexProtocol); + ~Mutex(); + + // + // Note that lock/tryLock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + + void lock() const; + + // + // Returns true if the lock was acquired, and false otherwise. + // + bool tryLock() const; + + void unlock() const; + + // + // Returns true if the mutex will unlock when calling unlock() + // (false otherwise). For non-recursive mutexes, this will always + // return true. + // This function is used by the Monitor implementation to know whether + // the Mutex has been locked for the first time, or unlocked for the + // last time (that is another thread is able to acquire the mutex). + // Pre-condition: the mutex must be locked. + // + bool willUnlock() const; + +private: + + inline void init(MutexProtocol); + // noncopyable + Mutex(const Mutex&); + void operator=(const Mutex&); + + // + // LockState and the lock/unlock variations are for use by the + // Condition variable implementation. + // +#ifdef _WIN32 + struct LockState + { +# ifdef ICE_HAS_WIN32_CONDVAR + CRITICAL_SECTION* mutex; +# endif + }; +#else + struct LockState + { + pthread_mutex_t* mutex; + }; +#endif + + void unlock(LockState&) const; + void lock(LockState&) const; + + friend class Cond; + +#ifdef _WIN32 + mutable CRITICAL_SECTION _mutex; +#else + mutable pthread_mutex_t _mutex; +#endif +}; + +// +// For performance reasons the following functions are inlined. +// +inline +Mutex::Mutex() +{ +#ifdef _WIN32 + init(PrioNone); +#else + init(getDefaultMutexProtocol()); +#endif +} + +#ifdef _WIN32 +inline +Mutex::Mutex(MutexProtocol) +{ + init(PrioNone); +} +#else +inline +Mutex::Mutex(MutexProtocol protocol) +{ + init(protocol); +} +#endif + +#ifdef _WIN32 + +inline void +Mutex::init(MutexProtocol) +{ + InitializeCriticalSection(&_mutex); +} + +inline +Mutex::~Mutex() +{ + DeleteCriticalSection(&_mutex); +} + +inline void +Mutex::lock() const +{ + EnterCriticalSection(&_mutex); +#ifndef NDEBUG + if(_mutex.RecursionCount > 1) + { + LeaveCriticalSection(&_mutex); + throw ThreadLockedException(__FILE__, __LINE__); + } +#endif +} + +inline bool +Mutex::tryLock() const +{ + if(!TryEnterCriticalSection(&_mutex)) + { + return false; + } + if(_mutex.RecursionCount > 1) + { + LeaveCriticalSection(&_mutex); + throw ThreadLockedException(__FILE__, __LINE__); + } + return true; +} + +inline void +Mutex::unlock() const +{ + assert(_mutex.RecursionCount == 1); + LeaveCriticalSection(&_mutex); +} + +# ifdef ICE_HAS_WIN32_CONDVAR +inline void +Mutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; +} + +inline void +Mutex::lock(LockState&) const +{ +} +# else +inline void +Mutex::unlock(LockState&) const +{ + LeaveCriticalSection(&_mutex); +} + +inline void +Mutex::lock(LockState&) const +{ + EnterCriticalSection(&_mutex); +} +# endif + +#else + +inline void +Mutex::init(MutexProtocol +#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 + protocol +#endif + ) +{ + int rc; + pthread_mutexattr_t attr; + rc = pthread_mutexattr_init(&attr); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + // + // Enable mutex error checking + // + rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + // + // If system has support for priority inheritance we set the protocol + // attribute of the mutex + // +#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 + if(PrioInherit == protocol) + { + rc = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } +#endif + + rc = pthread_mutex_init(&_mutex, &attr); + assert(rc == 0); + if(rc != 0) + { + pthread_mutexattr_destroy(&attr); + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + + rc = pthread_mutexattr_destroy(&attr); + assert(rc == 0); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +inline +Mutex::~Mutex() +{ +#ifndef NDEBUG + int rc = 0; + rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); +#else + pthread_mutex_destroy(&_mutex); +#endif +} + +inline void +Mutex::lock() const +{ + int rc = pthread_mutex_lock(&_mutex); + if(rc != 0) + { + if(rc == EDEADLK) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + else + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } +} + +inline bool +Mutex::tryLock() const +{ + int rc = pthread_mutex_trylock(&_mutex); + if(rc != 0 && rc != EBUSY) + { + if(rc == EDEADLK) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + else + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } + } + return (rc == 0); +} + +inline void +Mutex::unlock() const +{ + int rc = pthread_mutex_unlock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, rc); + } +} + +inline void +Mutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; +} + +inline void +Mutex::lock(LockState&) const +{ +} + +#endif + +inline bool +Mutex::willUnlock() const +{ + return true; +} + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/MutexProtocol.h b/Sources/IceCpp/include/IceUtil/MutexProtocol.h new file mode 100644 index 0000000..4a0295c --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/MutexProtocol.h @@ -0,0 +1,23 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_MUTEX_PROTOCOL_H +#define ICE_UTIL_MUTEX_PROTOCOL_H + +#include + +namespace IceUtil +{ + +enum MutexProtocol +{ + PrioInherit, + PrioNone +}; + +ICE_API MutexProtocol getDefaultMutexProtocol(); + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/MutexPtrLock.h b/Sources/IceCpp/include/IceUtil/MutexPtrLock.h new file mode 100644 index 0000000..9087193 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/MutexPtrLock.h @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_MUTEX_PTR_LOCK_H +#define ICE_UTIL_MUTEX_PTR_LOCK_H + +#include +#include + +namespace IceUtilInternal +{ + +template +class MutexPtrLock +{ +public: + + MutexPtrLock(T* mutex) : + _mutex(mutex), + _acquired(false) + { + if(_mutex) + { + _mutex->lock(); + _acquired = true; + } + } + + ~MutexPtrLock() + { + if(_mutex && _acquired) + { + _mutex->unlock(); + } + } + + void acquire() const + { + if(_mutex) + { + _mutex->lock(); + _acquired = true; + } + } + + void release() const + { + if(_mutex) + { + if(!_acquired) + { + throw IceUtil::ThreadLockedException(__FILE__, __LINE__); + } + _mutex->unlock(); + _acquired = false; + } + } + + bool acquired() const + { + return _acquired; + } + +private: + + // Not implemented; prevents accidental use. + // + MutexPtrLock(const MutexPtrLock&); + MutexPtrLock& operator=(const MutexPtrLock&); + + const T* _mutex; + mutable bool _acquired; +}; + +} // End namespace IceUtilInternal + +#endif diff --git a/Sources/IceCpp/include/IceUtil/MutexPtrTryLock.h b/Sources/IceCpp/include/IceUtil/MutexPtrTryLock.h new file mode 100644 index 0000000..66f313f --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/MutexPtrTryLock.h @@ -0,0 +1,77 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_MUTEX_PTR_TRY_LOCK_H +#define ICE_UTIL_MUTEX_PTR_TRY_LOCK_H + +#include +#include + +namespace IceUtilInternal +{ + +template +class MutexPtrTryLock +{ +public: + + MutexPtrTryLock(const T* mutex) : + _mutex(mutex), + _acquired(false) + { + if(_mutex) + { + _acquired = _mutex->tryLock(); + } + } + + ~MutexPtrTryLock() + { + if(_mutex && _acquired) + { + _mutex->unlock(); + } + } + + void acquire() const + { + if(_mutex) + { + _mutex->lock(); + _acquired = true; + } + } + + void release() const + { + if(_mutex) + { + if(!_acquired) + { + throw IceUtil::ThreadLockedException(__FILE__, __LINE__); + } + _mutex->unlock(); + _acquired = false; + } + } + + bool acquired() const + { + return _acquired; + } + +private: + + // Not implemented; prevents accidental use. + // + MutexPtrTryLock(const MutexPtrTryLock&); + MutexPtrTryLock& operator=(const MutexPtrTryLock&); + + const T* _mutex; + mutable bool _acquired; +}; + +} // End namespace IceUtilInternal + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Optional.h b/Sources/IceCpp/include/IceUtil/Optional.h new file mode 100644 index 0000000..fdb89b7 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Optional.h @@ -0,0 +1,433 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_OPTIONAL_H +#define ICE_UTIL_OPTIONAL_H + +#ifndef ICE_CPP11_MAPPING + +#include + +namespace IceUtilInternal +{ + +struct NoneType +{ +}; + +} + +namespace IceUtil +{ + +/** A sentinel value used to indicate that no optional value was provided. */ +const IceUtilInternal::NoneType None = {}; + +/** Encapsulates an optional value, which may or may not be present. */ +template +class Optional +{ +public: + + typedef T element_type; + + /** + * Constructs an empty optional with no value. + */ + Optional() : _isSet(false) + { + } + + /** + * Constructs an empty optional with no value. + */ + Optional(IceUtilInternal::NoneType) : _isSet(false) + { + } + + /** + * Constructs an optional as a copy of the given optional. + * @param r The source optional. + */ + Optional(const Optional& r) : _value(r._value), _isSet(r._isSet) + { + } + + /** + * Constructs an optional with the given value. + * @param p The initial value. + */ + template + Optional(Y p) : _value(p), _isSet(true) + { + } + + /** + * Constructs an optional as a copy of the given optional. + * @param r The source optional. + */ + template + Optional(const Optional& r) : _value(r._value), _isSet(r._isSet) + { + } + + ~Optional() + { + } + + /** + * Resets this optional to have no value. + */ + Optional& operator=(IceUtilInternal::NoneType) + { + _value = T(); + _isSet = false; + return *this; + } + + /** + * Resets this optional to have the given value. + * @param p The new value. + */ + template + Optional& operator=(Y p) + { + _value = p; + _isSet = true; + return *this; + } + + /** + * Resets this optional to be a copy of the given optional. + * @param r The source optional. + */ + template + Optional& operator=(const Optional& r) + { + _value = r._value; + _isSet = r._isSet; + return *this; + } + + /** + * Resets this optional to be a copy of the given optional. + * @param r The source optional. + */ + Optional& operator=(const Optional& r) + { + _value = r._value; + _isSet = r._isSet; + return *this; + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + const T& value() const + { + checkIsSet(); + return _value; + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + T& value() + { + checkIsSet(); + return _value; + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + const T& get() const + { + return value(); + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + T& get() + { + return value(); + } + + /** + * Obtains a pointer to the current value. + * @return A pointer to the current value. + * @throws OptionalNotSetException if this optional has no value. + */ + const T* operator->() const + { + return &value(); + } + + /** + * Obtains a pointer to the current value. + * @return A pointer to the current value. + * @throws OptionalNotSetException if this optional has no value. + */ + T* operator->() + { + return &value(); + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + const T& operator*() const + { + return value(); + } + + /** + * Obtains the current value. + * @return The current value. + * @throws OptionalNotSetException if this optional has no value. + */ + T& operator*() + { + return value(); + } + + /** + * Determines whether this optional has a value. + * @return True if the optional has a value, false otherwise. + */ + operator bool() const + { + return _isSet; + } + + /** + * Determines whether this optional has a value. + * @return True if the optional does not have a value, false otherwise. + */ + bool operator!() const + { + return !_isSet; + } + + /** + * Exchanges the state of this optional with another one. + * @param other The optional value with which to swap. + */ + void swap(Optional& other) + { + std::swap(_isSet, other._isSet); + std::swap(_value, other._value); + } + + /// \cond INTERNAL + void __setIsSet() + { + _isSet = true; + } + /// \endcond + +private: + + void checkIsSet() const + { + if(!_isSet) + { + throwOptionalNotSetException(__FILE__, __LINE__); + } + } + + void throwOptionalNotSetException(const char *, int) const; + + T _value; + bool _isSet; +}; + +/** + * Constructs an optional from the given value. + * @param v The optional's initial value. + * @return A new optional object. + */ +template inline Optional +makeOptional(const T& v) +{ + return Optional(v); +} + +/// \cond INTERNAL +template inline void +Optional::throwOptionalNotSetException(const char* file, int line) const +{ + throw OptionalNotSetException(file, line); +} +/// \endcond + +template +inline bool operator==(const Optional& lhs, const Optional& rhs) +{ + if(lhs && rhs) + { + return *lhs == *rhs; + } + else + { + return !lhs && !rhs; + } +} + +template +inline bool operator!=(const Optional& lhs, const Optional& rhs) +{ + return !operator==(lhs, rhs); +} + +template +inline bool operator<(const Optional& lhs, const Optional& rhs) +{ + if(lhs && rhs) + { + return *lhs < *rhs; + } + else + { + return !lhs && rhs; + } +} + +template +inline bool operator<=(const Optional& lhs, const Optional& rhs) +{ + return lhs < rhs || lhs == rhs; +} + +template +inline bool operator>(const Optional& lhs, const Optional& rhs) +{ + return !(lhs < rhs || lhs == rhs); +} + +template +inline bool operator>=(const Optional& lhs, const Optional& rhs) +{ + return !(lhs < rhs); +} + +// Optional vs Y + +template +inline bool operator==(const Optional& lhs, const Y& rhs) +{ + if(!lhs) + { + return false; + } + else + { + return *lhs == rhs; + } +} + +template +inline bool operator!=(const Optional& lhs, const Y& rhs) +{ + return !operator==(lhs, rhs); +} + +template +inline bool operator<(const Optional& lhs, const Y& rhs) +{ + if(lhs) + { + return *lhs < rhs; + } + else + { + return true; + } +} + +template +inline bool operator<=(const Optional& lhs, const Y& rhs) +{ + return lhs < rhs || lhs == rhs; +} + +template +inline bool operator>(const Optional& lhs, const Y& rhs) +{ + return !(lhs < rhs || lhs == rhs); +} + +template +inline bool operator>=(const Optional& lhs, const Y& rhs) +{ + return !(lhs < rhs); +} + +// Y vs Optional + +template +inline bool operator==(const Y& lhs, const Optional& rhs) +{ + if(!rhs) + { + return false; + } + else + { + return lhs == *rhs; + } +} + +template +inline bool operator!=(const Y& lhs, const Optional& rhs) +{ + return !operator==(lhs, rhs); +} + +template +inline bool operator<(const Y& lhs, const Optional& rhs) +{ + if(rhs) + { + return lhs < *rhs; + } + else + { + return false; + } +} + +template +inline bool operator<=(const Y& lhs, const Optional& rhs) +{ + return lhs < rhs || lhs == rhs; +} + +template +inline bool operator>(const Y& lhs, const Optional& rhs) +{ + return !(lhs < rhs || lhs == rhs); +} + +template +inline bool operator>=(const Y& lhs, const Optional& rhs) +{ + return !(lhs < rhs); +} + +} + +#endif +#endif diff --git a/Sources/IceCpp/include/IceUtil/Options.h b/Sources/IceCpp/include/IceUtil/Options.h new file mode 100644 index 0000000..6b9d7a5 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Options.h @@ -0,0 +1,135 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_OPTIONS_H +#define ICE_UTIL_OPTIONS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace IceUtilInternal +{ + +class ICE_API APIException : public IceUtil::ExceptionHelper +{ +public: + + APIException(const char*, int, const ::std::string&); +#ifndef ICE_CPP11_COMPILER + virtual ~APIException() throw(); +#endif + virtual ::std::string ice_id() const; + virtual void ice_print(std::ostream&) const; +#ifndef ICE_CPP11_MAPPING + virtual APIException* ice_clone() const; +#endif + + ::std::string reason; +}; + +ICE_API ::std::ostream& operator<<(::std::ostream&, const APIException&); + +class ICE_API BadOptException : public IceUtil::ExceptionHelper +{ +public: + + BadOptException(const char*, int, const ::std::string&); +#ifndef ICE_CPP11_COMPILER + virtual ~BadOptException() throw(); +#endif + virtual ::std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual BadOptException* ice_clone() const; +#endif + + ::std::string reason; +}; + +ICE_API ::std::ostream& operator<<(::std::ostream&, const BadOptException&); + +class ICE_API Options +{ +public: + + enum LengthType { ShortOpt, LongOpt }; + enum RepeatType { Repeat, NoRepeat }; + enum ArgType { NeedArg, NoArg }; + + Options(); + void addOpt(const ::std::string&, const ::std::string& = "", + ArgType = NoArg, ::std::string = "", RepeatType = NoRepeat); + + typedef ::std::vector< ::std::string> StringVector; + + static StringVector split(const ::std::string&); + StringVector parse(const StringVector&); + StringVector parse(int, const char* const []); + bool isSet(const ::std::string&) const; + ::std::string optArg(const ::std::string&) const; + StringVector argVec(const ::std::string&) const; + +private: + + struct OptionDetails : public IceUtil::Shared + { + LengthType length; + ArgType arg; + RepeatType repeat; + bool hasDefault; + }; + typedef IceUtil::Handle ODPtr; + + struct OptionValue : public IceUtil::Shared + { + ::std::string val; + }; + typedef IceUtil::Handle OValPtr; + + struct OptionValueVector : public IceUtil::Shared + { + ::std::vector< ::std::string> vals; + }; + typedef IceUtil::Handle OVecPtr; + + typedef ::std::map< ::std::string, ODPtr> ValidOpts; // Valid options and their details. + typedef ::std::map< ::std::string, OValPtr> Opts; // Value of non-repeating options. + typedef ::std::map< ::std::string, OVecPtr> ROpts; // Value of repeating options. + typedef ::std::map< ::std::string, ::std::string> Synonyms; // Map from short to long option and vice versa. + + void addValidOpt(const ::std::string&, const ::std::string&, ArgType, const ::std::string&, RepeatType); + ValidOpts::iterator checkOpt(const ::std::string&, LengthType); + void setOpt(const ::std::string&, const ::std::string&, const ::std::string&, RepeatType); + void setNonRepeatingOpt(const ::std::string&, const ::std::string&); + void setRepeatingOpt(const ::std::string&, const ::std::string&); + ValidOpts::const_iterator checkOptIsValid(const ::std::string&) const; + ValidOpts::const_iterator checkOptHasArg(const ::std::string&) const; + void updateSynonyms(const ::std::string&, const ::std::string&); + ::std::string getSynonym(const ::std::string&) const; + + ValidOpts _validOpts; + Opts _opts; + ROpts _ropts; + Synonyms _synonyms; + + bool parseCalled; + + IceUtil::RecMutex _m; + + Options(const Options&); // Not allowed. + void operator=(const Options&); // Not allowed. + + static void checkArgs(const ::std::string&, const ::std::string&, bool, const ::std::string&); +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/OutputUtil.h b/Sources/IceCpp/include/IceUtil/OutputUtil.h new file mode 100644 index 0000000..00f7146 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/OutputUtil.h @@ -0,0 +1,383 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_OUTPUT_UTIL_H +#define ICE_UTIL_OUTPUT_UTIL_H + +#include +#include +#include +#include + +namespace IceUtilInternal +{ + +ICE_API std::string int64ToString(IceUtil::Int64); + +// ---------------------------------------------------------------------- +// OutputBase +// ---------------------------------------------------------------------- + +// +// Technically it's not necessary to have print() & newline() as virtual +// since the opeator<< functions are specific to each OutputBase +// derivative. However, since it's possible to call print() & newline() +// manually I've decided to leave them as virtual. +// + +class ICE_API OutputBase : private ::IceUtil::noncopyable +{ +public: + + OutputBase(); + OutputBase(std::ostream&); + OutputBase(const std::string&); + virtual ~OutputBase(); + + void setIndent(int); // What is the indent level? + void setUseTab(bool); // Should we output tabs? + + void open(const std::string&); // Open output stream. + void close(); // Close output stream. + bool isOpen(); // Is a file stream open? + + virtual void print(const std::string&); // Print a string. + + void inc(); // Increment indentation level. + void dec(); // Decrement indentation level. + + void useCurrentPosAsIndent(); // Save the current position as indentation. + void zeroIndent(); // Use zero identation. + void restoreIndent(); // Restore indentation. + int currIndent(); // Return current indent value. + + virtual void newline(); // Print newline. + void separator(); // Print separator. + + bool operator!() const; // Check whether the output state is ok. + +protected: + + std::ofstream _fout; + std::ostream& _out; + int _pos; + int _indent; + int _indentSize; + std::stack _indentSave; + bool _useTab; + bool _separator; +}; + +class ICE_API NextLine +{ +}; +extern ICE_API NextLine nl ICE_GLOBAL_VAR_SUFFIX; + +class ICE_API Separator +{ +}; +extern ICE_API Separator sp ICE_GLOBAL_VAR_SUFFIX; + +// ---------------------------------------------------------------------- +// Output +// ---------------------------------------------------------------------- + +class ICE_API Output : public OutputBase +{ +public: + + Output(bool breakBeforeBlock = true, bool shortEmptyBlock = false); + Output(std::ostream&, bool = true, bool = false); + Output(const char*, bool = true, bool = false); + + virtual void print(const std::string&); // Print a string. + + void sb(); // Start a block. + void eb(); // End a block. + + void spar(char = '('); // Start a paramater list. + void epar(char = ')'); // End a paramater list. + +private: + + std::string _blockStart; + std::string _blockEnd; + int _par; // If >= 0, we are writing a parameter list. + const bool _breakBeforeBlock; // If true break before starting a new block. + const bool _shortEmptyBlock; // If true, an empty block is written . + bool _emptyBlock; +}; + +template +inline Output& +operator<<(Output& out, const T& val) +{ + std::ostringstream s; + s << val; + out.print(s.str()); + return out; +} + +template +inline Output& +operator<<(Output& out, const std::vector& val) +{ + for(typename std::vector::const_iterator p = val.begin(); p != val.end(); ++p) + { + out << *p; + } + return out; +} + +template<> +inline Output& +operator<<(Output& o, const NextLine&) +{ + o.newline(); + return o; +} + +template<> +inline Output& +operator<<(Output& o, const Separator&) +{ + o.separator(); + return o; +} + +class ICE_API StartBlock +{ +}; +extern ICE_API StartBlock sb ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const StartBlock&) +{ + o.sb(); + return o; +} + +class ICE_API EndBlock +{ +}; +extern ICE_API EndBlock eb ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const EndBlock&) +{ + o.eb(); + return o; +} + +class ICE_API StartPar +{ +}; +extern ICE_API StartPar spar ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const StartPar&) +{ + o.spar(); + return o; +} + +class ICE_API EndPar +{ +}; +extern ICE_API EndPar epar ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const EndPar&) +{ + o.epar(); + return o; +} + +class ICE_API StartAbrk +{ +}; +extern ICE_API StartAbrk sabrk ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const StartAbrk&) +{ + o.spar('<'); + return o; +} + +class ICE_API EndAbrk +{ +}; +extern ICE_API EndAbrk eabrk ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline Output& +operator<<(Output& o, const EndAbrk&) +{ + o.epar('>'); + return o; +} + +ICE_API Output& operator<<(Output&, std::ios_base& (*)(std::ios_base&)); + +// ---------------------------------------------------------------------- +// XMLOutput +// ---------------------------------------------------------------------- + +class ICE_API XMLOutput : public OutputBase +{ +public: + + XMLOutput(); + XMLOutput(std::ostream&); + XMLOutput(const char*); + + virtual void print(const std::string&); // Print a string. + + virtual void newline(); // Print newline. + + void startElement(const std::string&); // Start an element. + void endElement(); // End an element. + void attr(const std::string&, const std::string&); // Add an attribute to an element. + + void startEscapes(); + void endEscapes(); + + std::string currentElement() const; + +private: + + ::std::string escape(const ::std::string&) const; + + std::stack _elementStack; + + bool _se; + bool _text; + + bool _escape; +}; + +template +inline XMLOutput& +operator<<(XMLOutput& out, const T& val) +{ + std::ostringstream s; + s << val; + out.print(s.str()); + return out; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const NextLine&) +{ + o.newline(); + return o; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const Separator&) +{ + o.separator(); + return o; +} + +class ICE_API EndElement +{ +}; +extern ICE_API EndElement ee ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const EndElement&) +{ + o.endElement(); + return o; +} + +class ICE_API StartElement +{ +public: + + StartElement(const std::string&); + + const std::string& getName() const; + +private: + + const std::string _name; +}; + +typedef StartElement se; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const StartElement& e) +{ + o.startElement(e.getName()); + return o; +} + +class ICE_API Attribute +{ +public: + + Attribute(const ::std::string&, const ::std::string&); + + const ::std::string& getName() const; + const ::std::string& getValue() const; + +private: + + const ::std::string _name; + const ::std::string _value; +}; + +typedef Attribute attr; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const Attribute& e) +{ + o.attr(e.getName(), e.getValue()); + return o; +} + +class ICE_API StartEscapes +{ +}; +extern ICE_API StartEscapes startEscapes ICE_GLOBAL_VAR_SUFFIX; + +class ICE_API EndEscapes +{ +}; +extern ICE_API EndEscapes endEscapes ICE_GLOBAL_VAR_SUFFIX; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const StartEscapes&) +{ + o.startEscapes(); + return o; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const EndEscapes&) +{ + o.endEscapes(); + return o; +} + +ICE_API XMLOutput& operator<<(XMLOutput&, std::ios_base& (*)(std::ios_base&)); + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/PopDisableWarnings.h b/Sources/IceCpp/include/IceUtil/PopDisableWarnings.h new file mode 100644 index 0000000..317bbc8 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/PopDisableWarnings.h @@ -0,0 +1,14 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// No pragma once as this file can be included several times in a translation +// unit + +#if defined(_MSC_VER) +# pragma warning(pop) +#elif defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif diff --git a/Sources/IceCpp/include/IceUtil/PushDisableWarnings.h b/Sources/IceCpp/include/IceUtil/PushDisableWarnings.h new file mode 100644 index 0000000..40aae06 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/PushDisableWarnings.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// No pragma once as this file can be included several times in a translation +// unit + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable:4250) // ... : inherits ... via dominance +# pragma warning(disable:4251) // class ... needs to have dll-interface to be used by clients of class ... +# pragma warning(disable:4512) // ... assignment operator could not be generated + +# if _MSC_VER >= 1900 +# pragma warning(disable:4275) // non dll-interface class ... used as base for dll-interface class ... +# endif + +#elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wredundant-decls" // expected when using forward Slice declarations +# pragma clang diagnostic ignored "-Wdocumentation-deprecated-sync" // see zeroc-ice/ice issue #211 + +# if (__clang_major__ >= 4) +# pragma clang diagnostic ignored "-Wshadow-field-in-constructor" // expected in some generated header files +# else +# pragma clang diagnostic ignored "-Wshadow-all" // expected in some generated header files +# endif + +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wredundant-decls" // expected when using forward Slice declarations +# pragma GCC diagnostic ignored "-Wshadow" // expected in some generated header files +#endif diff --git a/Sources/IceCpp/include/IceUtil/Random.h b/Sources/IceCpp/include/IceUtil/Random.h new file mode 100644 index 0000000..a45a477 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Random.h @@ -0,0 +1,55 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_RANDOM_H +#define ICE_UTIL_RANDOM_H + +#include +#include + +#ifdef ICE_CPP11_COMPILER +# include +# include +#else +# include +#endif + +namespace IceUtilInternal +{ + +ICE_API void generateRandom(char*, size_t); +ICE_API unsigned int random(int = 0); + +#ifdef ICE_CPP11_COMPILER + +template +void shuffle(T first, T last) +{ + std::random_device rd; + std::mt19937 rng(rd()); + std::shuffle(first, last, rng); +} + +#else + +struct RandomNumberGenerator : public std::unary_function +{ + std::ptrdiff_t operator()(std::ptrdiff_t d) + { + return static_cast(IceUtilInternal::random(static_cast(d))); + } +}; + +template +void shuffle(T first, T last) +{ + RandomNumberGenerator rng; + random_shuffle(first, last, rng); +} + +#endif + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/RecMutex.h b/Sources/IceCpp/include/IceUtil/RecMutex.h new file mode 100644 index 0000000..a0d0943 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/RecMutex.h @@ -0,0 +1,107 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_RMUTEX_H +#define ICE_UTIL_RMUTEX_H + +#include +#include +#include +#include + +namespace IceUtil +{ + +// +// Forward declarations for friend. +// +class Cond; + +// +// Recursive Mutex implementation. +// +class ICE_API RecMutex +{ +public: + + // + // Lock & TryLock typedefs. + // + typedef LockT Lock; + typedef TryLockT TryLock; + + RecMutex(); + RecMutex(const MutexProtocol); + ~RecMutex(); + + // + // Note that lock/tryLock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + + void lock() const; + + // + // Returns true if the lock was acquired or was already acquired + // by the calling thread, and false otherwise. + // + bool tryLock() const; + + void unlock() const; + + // + // Returns true if the mutex will unlock when calling unlock() + // (false otherwise). For non-recursive mutexes, this will always + // return true. + // This function is used by the Monitor implementation to know whether + // the Mutex has been locked for the first time, or unlocked for the + // last time (that is another thread is able to acquire the mutex). + // Pre-condition: the mutex must be locked. + // + bool willUnlock() const; + +private: + + void init(const MutexProtocol); + // noncopyable + RecMutex(const RecMutex&); + void operator=(const RecMutex&); + + // + // LockState and the lock/unlock variations are for use by the + // Condition variable implementation. + // +#ifdef _WIN32 + struct LockState + { +# ifdef ICE_HAS_WIN32_CONDVAR + CRITICAL_SECTION* mutex; +# endif + int count; + }; +#else + struct LockState + { + pthread_mutex_t* mutex; + int count; + }; +#endif + + void unlock(LockState&) const; + void lock(LockState&) const; + + friend class Cond; + +#ifdef _WIN32 + mutable CRITICAL_SECTION _mutex; +#else + mutable pthread_mutex_t _mutex; +#endif + + mutable int _count; +}; + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ResourceConfig.h b/Sources/IceCpp/include/IceUtil/ResourceConfig.h new file mode 100644 index 0000000..c76641d --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ResourceConfig.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_RESOURCE_CONFIG_H +#define ICE_UTIL_RESOURCE_CONFIG_H + +#include "winver.h" + +#define ICE_VERSION 3,7,10,0 +#define ICE_STRING_VERSION "3.7.10\0" +#define ICE_SO_VERSION "37\0" +#define ICE_COMPANY_NAME "ZeroC, Inc.\0" +#define ICE_COPYRIGHT "\251 ZeroC, Inc.\0" +#define ICE_PRODUCT_NAME "Ice\0" + +#ifdef ICE_CPP11_MAPPING +# if defined(_DEBUG) +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11D" +# else +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11" +# endif +#else +# if defined(_DEBUG) +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "D" +# else +# define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "" +# endif +#endif + +#ifndef DEBUG +# define VER_DEBUG 0 +#else +# define VER_DEBUG VS_FF_DEBUG +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ScannerConfig.h b/Sources/IceCpp/include/IceUtil/ScannerConfig.h new file mode 100644 index 0000000..561dd98 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ScannerConfig.h @@ -0,0 +1,40 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_SCANNER_CONFIG_H +#define ICE_UTIL_SCANNER_CONFIG_H + +#include // Required by generated Scanners. + +// +// COMPILERFIX: VC compilers does not provide stdint.h header until v100 +// the header must be included before that macros for integral types +// in flex generated Scanners are defined. +// +// in C99 conformant compilers we don't need to include it because the +// header is included by inttypes.h, that is included by the gernated +// Scanners. +// +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# include +#endif + +// +// Clang++ >= 5.1 and VC++ using C++17 standard deprecate 'register' storage +// class specifier used by lex generated Scanners. +// +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wdeprecated-register" +#elif defined(_MSC_VER) && (_MSC_VER >= 1900) +# pragma warning(disable:5033) +#endif + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wconversion" +# pragma clang diagnostic ignored "-Wsign-conversion" +# pragma clang diagnostic ignored "-Wdocumentation" +# pragma clang diagnostic ignored "-Wunused-but-set-variable" +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ScopedArray.h b/Sources/IceCpp/include/IceUtil/ScopedArray.h new file mode 100644 index 0000000..6ccfce6 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ScopedArray.h @@ -0,0 +1,98 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_SCOPED_ARRAY_H +#define ICE_UTIL_SCOPED_ARRAY_H + +#include + +#ifndef ICE_CPP11_MAPPING + +// +// Only for the C++98 mapping +// + +namespace IceUtil +{ + +template +class ScopedArray +{ +public: + + explicit ScopedArray(T* ptr = 0) : + _ptr(ptr) + { + } + + ScopedArray(const ScopedArray& other) + { + _ptr = other._ptr; + const_cast(other)._ptr = 0; + } + + ~ScopedArray() + { + if(_ptr != 0) + { + delete[] _ptr; + } + } + + void reset(T* ptr = 0) + { + assert(ptr == 0 || ptr != _ptr); + if(_ptr != 0) + { + delete[] _ptr; + } + _ptr = ptr; + } + + ScopedArray& operator=(const ScopedArray& other) + { + if(_ptr != 0) + { + delete[] _ptr; + } + _ptr = other._ptr; + const_cast(other)._ptr = 0; + return *this; + } + + T& operator[](size_t i) const + { + assert(_ptr != 0); + assert(i >= 0); + return _ptr[i]; + } + + T* get() const + { + return _ptr; + } + + void swap(ScopedArray& a) + { + T* tmp = a._ptr; + a._ptr = _ptr; + _ptr = tmp; + } + + T* release() + { + T* tmp = _ptr; + _ptr = 0; + return tmp; + } + +private: + + T* _ptr; +}; + +} // End of namespace IceUtil + +#endif +#endif diff --git a/Sources/IceCpp/include/IceUtil/Shared.h b/Sources/IceCpp/include/IceUtil/Shared.h new file mode 100644 index 0000000..67272f1 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Shared.h @@ -0,0 +1,127 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_SHARED_H +#define ICE_UTIL_SHARED_H + +#include +#include + +// +// Base classes for reference counted types. The IceUtil::Handle +// template can be used for smart pointers to types derived from these +// bases. +// +// IceUtil::SimpleShared +// ===================== +// +// A non thread-safe base class for reference-counted types. +// +// IceUtil::Shared +// =============== +// +// A thread-safe base class for reference-counted types. +// +namespace IceUtil +{ + +class ICE_API SimpleShared +{ +public: + + SimpleShared(); + SimpleShared(const SimpleShared&); + + virtual ~SimpleShared(); + + SimpleShared& operator=(const SimpleShared&) + { + return *this; + } + + void __incRef() + { + assert(_ref >= 0); + ++_ref; + } + + void __decRef() + { + assert(_ref > 0); + if(--_ref == 0) + { + if(!_noDelete) + { + delete this; + } + } + } + + int __getRef() const + { + return _ref; + } + + void __setNoDelete(bool b) + { + _noDelete = b; + } + +private: + + int _ref; + bool _noDelete; +}; + +class ICE_API Shared +{ +public: + + // + // Flag constant used by the Shared class. Derived classes + // such as GCObject define more flag constants. + // + static const unsigned char NoDelete; + + Shared(); + Shared(const Shared&); + + virtual ~Shared() + { + } + + Shared& operator=(const Shared&) + { + return *this; + } + + virtual void __incRef(); + virtual void __decRef(); + virtual int __getRef() const; + virtual void __setNoDelete(bool); + + void __setFlag(unsigned char flag) + { + _flags |= flag; + } + + void __clearFlag(unsigned char flag) + { + _flags &= ~flag; + } + + bool __hasFlag(unsigned char flag) + { + return (_flags & flag) > 0; + } + +protected: + + IceUtilInternal::Atomic _ref; + unsigned char _flags; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/StopWatch.h b/Sources/IceCpp/include/IceUtil/StopWatch.h new file mode 100644 index 0000000..f8b9aab --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/StopWatch.h @@ -0,0 +1,49 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_STOPWATCH_H +#define ICE_UTIL_STOPWATCH_H + +#include + +namespace IceUtilInternal +{ + +class StopWatch +{ +public: + + StopWatch() { } + + void start() + { + _s = IceUtil::Time::now(IceUtil::Time::Monotonic); + } + + IceUtil::Int64 stop() + { + assert(isStarted()); + IceUtil::Int64 d = (IceUtil::Time::now(IceUtil::Time::Monotonic) - _s).toMicroSeconds(); + _s = IceUtil::Time(); + return d; + } + + bool isStarted() const + { + return _s != IceUtil::Time(); + } + + IceUtil::Int64 delay() + { + return (IceUtil::Time::now(IceUtil::Time::Monotonic) - _s).toMicroSeconds(); + } + +private: + + IceUtil::Time _s; +}; + +} // End namespace IceUtilInternal + +#endif diff --git a/Sources/IceCpp/include/IceUtil/StringConverter.h b/Sources/IceCpp/include/IceUtil/StringConverter.h new file mode 100644 index 0000000..ea233ed --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/StringConverter.h @@ -0,0 +1,195 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_STRING_CONVERTER_H +#define ICE_UTIL_STRING_CONVERTER_H + +#include +#include +#include +#include + +#include + +namespace IceUtil +{ + +/** + * Provides bytes to toUTF8. Can raise std::bad_alloc or Ice::MemoryLimitException + * when too many bytes are requested. + * \headerfile Ice/Ice.h + */ +class ICE_API UTF8Buffer +{ +public: + + /** + * Obtains more bytes. + * @param howMany The number of bytes requested. + * @param firstUnused A pointer to the first unused byte. + * @return A pointer to the beginning of the buffer. + */ + virtual Byte* getMoreBytes(size_t howMany, Byte* firstUnused) = 0; + + virtual ~UTF8Buffer(); +}; + +/** + * A StringConverter converts narrow or wide-strings to and from UTF-8 byte sequences. + * It's used by the communicator during marshaling (toUTF8) and unmarshaling (fromUTF8). + * It report errors by raising IllegalConversionException or an exception raised + * by UTF8Buffer. + * \headerfile Ice/Ice.h + */ +template +class BasicStringConverter +#ifndef ICE_CPP11_MAPPING + : public IceUtil::Shared +#endif +{ +public: + + /** + * Returns a pointer to byte after the last written byte (which may be + * past the last byte returned by getMoreBytes). + */ + virtual Byte* toUTF8(const charT* sourceStart, const charT* sourceEnd, UTF8Buffer& buf) const = 0; + + /** + * Unmarshals a UTF-8 sequence into a basic_string. + */ + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, std::basic_string& target) const = 0; + + virtual ~BasicStringConverter() + { + } +}; + +#if defined(__clang__) && !defined(ICE_STATIC_LIBS) +// +// Explicit template instantiation so that dynamic_cast of derived exported +// classes works well with clang, see ICE-7473. +// +template class ICE_API BasicStringConverter; +template class ICE_API BasicStringConverter; +#endif + +/** A narrow string converter. */ +typedef BasicStringConverter StringConverter; +ICE_DEFINE_PTR(StringConverterPtr, StringConverter); + +/** A wide string converter. */ +typedef BasicStringConverter WstringConverter; +ICE_DEFINE_PTR(WstringConverterPtr, WstringConverter); + +/** + * Creates a WstringConverter that converts to and from UTF-16 or UTF-32 depending on sizeof(wchar_t). + * @return The string converter. + */ +ICE_API WstringConverterPtr createUnicodeWstringConverter(); + +/** + * Retrieves the per-process narrow string converter. + * @return The string converter. + */ +ICE_API StringConverterPtr getProcessStringConverter(); + +/** + * Sets the per-process narrow string converter. + * @param c The string converter. + */ +ICE_API void setProcessStringConverter(const StringConverterPtr& c); + +/** + * Retrieves the per-process wide string converter. + * @return The string converter. + */ +ICE_API WstringConverterPtr getProcessWstringConverter(); + +/** + * Sets the per process wide string converter. + * @param c The string converter. + */ +ICE_API void setProcessWstringConverter(const WstringConverterPtr& c); + +/** + * Converts the given wide string to a narrow string. + * @param str A wide string. + * @param nc The narrow string converter. If null, the result's narrow string encoding is UTF-8. + * @param wc The wide string converter. If null, the input's wstring encoding is UTF-16 or UTF-32 + * depending on the size of wchar_t. + * @return A narrow string. + */ +ICE_API std::string +wstringToString(const std::wstring& str, + const StringConverterPtr& nc = 0, + const WstringConverterPtr& wc = 0); + +/** + * Converts the given narrow string to a wide string. + * @param str A narrow string. + * @param nc The narrow string converter. If null, the result's narrow string encoding is UTF-8. + * @param wc The wide string converter. If null, the input's wstring encoding is UTF-16 or UTF-32 + * depending on the size of wchar_t. + * @return A wide string. + */ +ICE_API std::wstring +stringToWstring(const std::string& str, + const StringConverterPtr& nc = 0, + const WstringConverterPtr& wc = 0); + +/** + * Converts the given string from the native narrow string encoding to + * UTF-8 using the given converter. + * @param str The native narrow string. + * @param nc The narrow string converter. If null, the native string is returned. + * @return A UTF-8 string. + */ +ICE_API std::string +nativeToUTF8(const std::string& str, const StringConverterPtr& nc); + +/** + * Converts the given string from UTF-8 to the native narrow string + * encoding using the given converter. + * @param str The UTF-8 string. + * @param nc The narrow string converter. If null, the UTF-8 string is returned. + * @return A native narrow string. + */ +ICE_API std::string +UTF8ToNative(const std::string& str, const StringConverterPtr& nc); + +} + +namespace IceUtilInternal +{ + +// +// Convert from UTF-8 to UTF-16/32 +// +ICE_API std::vector toUTF16(const std::vector&); +ICE_API std::vector toUTF32(const std::vector&); + +// +// Convert from UTF-32 to UTF-8 +// +ICE_API std::vector fromUTF32(const std::vector&); + +} + +#ifdef _WIN32 +namespace IceUtil +{ + +/** + * Creates a StringConverter that converts to and from narrow chars + * in the given code page, using MultiByteToWideChar and WideCharToMultiByte. + * @param page The code page. + * @return The string converter. + */ +ICE_API StringConverterPtr createWindowsStringConverter(unsigned int page); + +} +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/StringUtil.h b/Sources/IceCpp/include/IceUtil/StringUtil.h new file mode 100644 index 0000000..0891f00 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/StringUtil.h @@ -0,0 +1,97 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_STRING_UTIL_H +#define ICE_UTIL_STRING_UTIL_H + +#include +#include + +namespace IceUtilInternal +{ + +// +// Must be kept in sync with Ice::ToStringMode +// +#ifdef ICE_CPP11_MAPPING +enum class ToStringMode : unsigned char +#else +enum ToStringMode +#endif +{ Unicode, ASCII, Compat }; + +// +// Add escape sequences (like "\n", or "\123") to the input string +// (first parameter). +// The second parameter adds characters to escape, and can be empty. +// +ICE_API std::string escapeString(const std::string&, const std::string&, ToStringMode); + +// +// Remove escape sequences added by escapeString. Throws IllegalArgumentException +// for an invalid input string. +// +ICE_API std::string unescapeString(const std::string&, std::string::size_type, std::string::size_type, const std::string&); + +// +// Split a string using the given delimiters. Considers single and double quotes; +// returns false for unbalanced quote, true otherwise. +// +ICE_API bool splitString(const std::string&, const std::string&, std::vector&); + +// +// Join a list of strings using the given delimiter. +// +ICE_API std::string joinString(const std::vector&, const std::string&); + +// +// Trim white space +// +ICE_API std::string trim(const std::string&); + +// +// If a single or double quotation mark is found at the start +// position, then the position of the matching closing quote is +// returned. If no quotation mark is found at the start position, then +// 0 is returned. If no matching closing quote is found, then +// std::string::npos is returned. +// +ICE_API std::string::size_type checkQuote(const std::string&, std::string::size_type = 0); + +// +// Match `s' against the pattern `pat'. A * in the pattern acts +// as a wildcard: it matches any non-empty sequence of characters +// other than a period (`.'). We match by hand here because +// it's portable across platforms (whereas regex() isn't). +// +ICE_API bool match(const std::string&, const std::string&, bool = false); + +// +// Get the error message for the last error code or given error code. +// +ICE_API std::string lastErrorToString(); +#ifdef _WIN32 +ICE_API std::string errorToString(int, LPCVOID = ICE_NULLPTR); +#else +ICE_API std::string errorToString(int); +#endif + +// +// Functions to convert to lower/upper case. These functions accept +// UTF8 string/characters but ignore non ASCII characters. Unlike, the +// C methods, these methods are not local dependent. +// +ICE_API std::string toLower(const std::string&); +ICE_API std::string toUpper(const std::string&); +ICE_API bool isAlpha(char); +ICE_API bool isDigit(char); + +// +// Remove all whitespace from a string +// +ICE_API std::string removeWhitespace(const std::string&); + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Thread.h b/Sources/IceCpp/include/IceUtil/Thread.h new file mode 100644 index 0000000..18a6f04 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Thread.h @@ -0,0 +1,160 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_THREAD_H +#define ICE_UTIL_THREAD_H + +#include +#include +#include +#include + +namespace IceUtil +{ + +class Time; + +class ICE_API ThreadControl +{ +public: + + // + // Constructs a ThreadControl representing the current thread. + // join and detach cannot be called on such ThreadControl object. + // + ThreadControl(); + +#if defined(_WIN32) + ThreadControl(HANDLE, DWORD); +#else + explicit ThreadControl(pthread_t); +#endif + + // + // Default copy destructor, assignment operator and destructor OK + // + + // + // == and != are meaningful only before the thread is joined/detached, + // or while the thread is still running. + // + bool operator==(const ThreadControl&) const; + bool operator!=(const ThreadControl&) const; + + // + // Wait until the controlled thread terminates. The call has POSIX + // semantics. + // + // At most one thread can wait for the termination of a given + // thread. Calling join on a thread on which another thread is + // already waiting for termination results in undefined behaviour, + // as does joining with a thread after having joined with it + // previously, or joining with a detached thread. + // + void join(); + + // + // Detach a thread. Once a thread is detached, it cannot be + // detached again, nor can it be joined with. Every thread that + // was created using the IceUtil::Thread class must either be + // joined with or detached exactly once. Detaching a thread a + // second time, or detaching a thread that was previously joined + // with results in undefined behavior. + // + void detach(); + + // + // id() returns the Thread ID on Windows and the underlying pthread_t + // on POSIX platforms. + // +#if defined(_WIN32) + typedef DWORD ID; +#else + typedef pthread_t ID; +#endif + ID id() const; + + static void sleep(const Time&); + static void yield(); + +private: + +#if defined(_WIN32) + HANDLE _handle; + DWORD _id; +#else + pthread_t _thread; + + // + // Used to prevent joining/detaching a ThreadControl constructed + // with the default constructor. Only needed to enforce our + // portable join/detach behavior. + // + bool _detachable; +#endif +}; + +class ICE_API Thread : public virtual IceUtil::Shared +{ +public: + + Thread(); + Thread(const std::string&); + virtual ~Thread(); + + virtual void run() = 0; + + ThreadControl start(size_t = 0); + ThreadControl start(size_t, int priority); + + ThreadControl getThreadControl() const; + + bool operator==(const Thread&) const; + bool operator<(const Thread&) const; + + // + // Check whether a thread is still alive. + // + bool isAlive() const; + + // + // This function is an implementation detail; + // do not call it. + // + void _done(); + + // + // Get the thread name + // + const std::string& name() const; + +protected: + const std::string _name; + Mutex _stateMutex; + bool _started; + bool _running; + +#if defined(_WIN32) + HANDLE _handle; + DWORD _id; +#else + pthread_t _thread; +#endif + +private: + +#ifdef _WIN32 +#else + ThreadControl start(size_t, bool, int); +#endif + + Thread(const Thread&); // Copying is forbidden + void operator=(const Thread&); // Assignment is forbidden +}; + +typedef Handle ThreadPtr; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/ThreadException.h b/Sources/IceCpp/include/IceUtil/ThreadException.h new file mode 100644 index 0000000..0b13fcf --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/ThreadException.h @@ -0,0 +1,94 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_THREAD_EXCEPTION_H +#define ICE_UTIL_THREAD_EXCEPTION_H + +#include +#include + +namespace IceUtil +{ + +class ICE_API ThreadSyscallException : public SyscallExceptionHelper +{ +public: + + ThreadSyscallException(const char*, int, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual ThreadSyscallException* ice_clone() const; +#endif +}; + +class ICE_API ThreadLockedException : public ExceptionHelper +{ +public: + + ThreadLockedException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual ThreadLockedException* ice_clone() const; +#endif +}; + +class ICE_API ThreadStartedException : public ExceptionHelper +{ +public: + + ThreadStartedException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual ThreadStartedException* ice_clone() const; +#endif + +}; + +class ICE_API ThreadNotStartedException : public ExceptionHelper +{ +public: + + ThreadNotStartedException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual ThreadNotStartedException* ice_clone() const; +#endif +}; + +class ICE_API BadThreadControlException : public ExceptionHelper +{ +public: + + BadThreadControlException(const char*, int); + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + virtual BadThreadControlException* ice_clone() const; +#endif +}; + +class ICE_API InvalidTimeoutException : public ExceptionHelper +{ +public: + + InvalidTimeoutException(const char*, int, const Time&); + virtual std::string ice_id() const; + virtual void ice_print(std::ostream&) const; + +#ifndef ICE_CPP11_MAPPING + virtual InvalidTimeoutException* ice_clone() const; +#endif + +private: + + Time _timeout; +}; + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Time.h b/Sources/IceCpp/include/IceUtil/Time.h new file mode 100644 index 0000000..ec7dd6a --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Time.h @@ -0,0 +1,205 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_TIME_H +#define ICE_UTIL_TIME_H + +#include + +#ifndef _WIN32 +# include +#endif + +namespace IceUtil +{ + +class ICE_API Time +{ +public: + + Time(); + + // No copy constructor and assignment operator necessary. The + // automatically generated copy constructor and assignment + // operator do the right thing. + + enum Clock { Realtime, Monotonic }; + static Time now(Clock = Realtime); + + static Time seconds(Int64); + static Time milliSeconds(Int64); + static Time microSeconds(Int64); + + static Time secondsDouble(double); + static Time milliSecondsDouble(double); + static Time microSecondsDouble(double); + +#ifndef _WIN32 + operator timeval() const; +#endif + + Int64 toSeconds() const; + Int64 toMilliSeconds() const; + Int64 toMicroSeconds() const; + + double toSecondsDouble() const; + double toMilliSecondsDouble() const; + double toMicroSecondsDouble() const; + + std::string toDateTime() const; + std::string toDuration() const; + std::string toString(const std::string&) const; + + Time operator-() const + { + return Time(-_usec); + } + + Time operator-(const Time& rhs) const + { + return Time(_usec - rhs._usec); + } + + Time operator+(const Time& rhs) const + { + return Time(_usec + rhs._usec); + } + + Time& operator+=(const Time& rhs) + { + _usec += rhs._usec; + return *this; + } + + Time& operator-=(const Time& rhs) + { + _usec -= rhs._usec; + return *this; + } + + bool operator<(const Time& rhs) const + { + return _usec < rhs._usec; + } + + bool operator<=(const Time& rhs) const + { + return _usec <= rhs._usec; + } + + bool operator>(const Time& rhs) const + { + return _usec > rhs._usec; + } + + bool operator>=(const Time& rhs) const + { + return _usec >= rhs._usec; + } + + bool operator==(const Time& rhs) const + { + return _usec == rhs._usec; + } + + bool operator!=(const Time& rhs) const + { + return _usec != rhs._usec; + } + + double operator/(const Time& rhs) const + { + return static_cast(_usec) / static_cast(rhs._usec); + } + + Time& operator*=(int rhs) + { + _usec *= rhs; + return *this; + } + + Time operator*(int rhs) const + { + Time t; + t._usec = _usec * rhs; + return t; + } + + Time& operator/=(int rhs) + { + _usec /= rhs; + return *this; + } + + Time operator/(int rhs) const + { + Time t; + t._usec = _usec / rhs; + return t; + } + + Time& operator*=(Int64 rhs) + { + _usec *= rhs; + return *this; + } + + Time operator*(Int64 rhs) const + { + Time t; + t._usec = _usec * rhs; + return t; + } + + Time& operator/=(Int64 rhs) + { + _usec /= rhs; + return *this; + } + + Time operator/(Int64 rhs) const + { + Time t; + t._usec = _usec / rhs; + return t; + } + + Time& operator*=(double rhs) + { + _usec = static_cast(static_cast(_usec) * rhs); + return *this; + } + + Time operator*(double rhs) const + { + Time t; + t._usec = static_cast(static_cast(_usec) * rhs); + return t; + } + + Time& operator/=(double rhs) + { + _usec = static_cast(static_cast(_usec) / rhs); + return *this; + } + + Time operator/(double rhs) const + { + Time t; + t._usec = static_cast(static_cast(_usec) / rhs); + return t; + } + +private: + + Time(Int64); + + Int64 _usec; +}; + +ICE_API std::ostream& operator<<(std::ostream&, const Time&); + +} // End namespace IceUtil + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Timer.h b/Sources/IceCpp/include/IceUtil/Timer.h new file mode 100644 index 0000000..d016c34 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Timer.h @@ -0,0 +1,144 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_TIMER_H +#define ICE_UTIL_TIMER_H + +#include +#include +#include +#include + +#include +#include +#include + +namespace IceUtil +{ + +class Timer; +typedef IceUtil::Handle TimerPtr; + +// +// Extend the TimerTask class and override the runTimerTask() method to execute +// code at a specific time or repeatedly. +// +class ICE_API TimerTask +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + virtual ~TimerTask(); + + virtual void runTimerTask() = 0; +}; +ICE_DEFINE_PTR(TimerTaskPtr, TimerTask); + +// +// The timer class is used to schedule tasks for one-time execution or +// repeated execution. Tasks are executed by the dedicated timer thread +// sequentially. +// +class ICE_API Timer : public virtual IceUtil::Shared, private IceUtil::Thread +{ +public: + + // + // Construct a timer and starts its execution thread. + // + Timer(); + + // + // Construct a timer and starts its execution thread with the priority. + // + Timer(int priority); + + // + // Destroy the timer and detach its execution thread if the calling thread + // is the timer thread, join the timer execution thread otherwise. + // + void destroy(); + + // + // Schedule a task for execution after a given delay. + // + void schedule(const TimerTaskPtr&, const IceUtil::Time&); + + // + // Schedule a task for repeated execution with the given delay + // between each execution. + // + void scheduleRepeated(const TimerTaskPtr&, const IceUtil::Time&); + + // + // Cancel a task. Returns true if the task has not yet run or if + // it's a task scheduled for repeated execution. Returns false if + // the task has already run, was already cancelled or was never + // schedulded. + // + bool cancel(const TimerTaskPtr&); + +protected: + + virtual void run(); + virtual void runTimerTask(const TimerTaskPtr&); + + struct Token + { + IceUtil::Time scheduledTime; + IceUtil::Time delay; + TimerTaskPtr task; + + inline Token(const IceUtil::Time&, const IceUtil::Time&, const TimerTaskPtr&); + inline bool operator<(const Token& r) const; + }; + + IceUtil::Monitor _monitor; + bool _destroyed; + std::set _tokens; + +#if (ICE_CPLUSPLUS >= 201703L) + class TimerTaskCompare +#else + class TimerTaskCompare : public std::binary_function +#endif + { + public: + + bool operator()(const TimerTaskPtr& lhs, const TimerTaskPtr& rhs) const + { + return lhs.get() < rhs.get(); + } + }; + std::map _tasks; + IceUtil::Time _wakeUpTime; +}; +typedef IceUtil::Handle TimerPtr; + +inline +Timer::Token::Token(const IceUtil::Time& st, const IceUtil::Time& d, const TimerTaskPtr& t) : + scheduledTime(st), delay(d), task(t) +{ +} + +inline bool +Timer::Token::operator<(const Timer::Token& r) const +{ + if(scheduledTime < r.scheduledTime) + { + return true; + } + else if(scheduledTime > r.scheduledTime) + { + return false; + } + + return task.get() < r.task.get(); +} + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/UUID.h b/Sources/IceCpp/include/IceUtil/UUID.h new file mode 100644 index 0000000..8e831e1 --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/UUID.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_UUID_H +#define ICE_UTIL_UUID_H + +#include + +namespace IceUtil +{ + +/** + * Generates a universally unique identifier (UUID). + * @return The UUID. + */ +ICE_API std::string generateUUID(); + +} + +#endif diff --git a/Sources/IceCpp/include/IceUtil/UndefSysMacros.h b/Sources/IceCpp/include/IceUtil/UndefSysMacros.h new file mode 100644 index 0000000..4743bfe --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/UndefSysMacros.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_UNDEF_SYS_MACROS_H +#define ICE_UTIL_UNDEF_SYS_MACROS_H + +// +// This header includes macros that can end up being dragged into +// the generated code from system headers, such as major() or NDEBUG. +// If a Slice symbol has the same name as a macro, the generated +// code most likely won't compile (but, depending how the macro is +// defined, may even compile). +// +// Here, we undefine symbols that cause such problems. +// +// The #ifdef ... #endif protection is necessary to prevent +// warnings on some platforms. +// + +#ifdef major +#undef major +#endif + +#ifdef minor +#undef minor +#endif + +#ifdef min +#undef min +#endif + +#ifdef max +#undef max +#endif + +#endif diff --git a/Sources/IceCpp/include/IceUtil/Unicode.h b/Sources/IceCpp/include/IceUtil/Unicode.h new file mode 100644 index 0000000..564644a --- /dev/null +++ b/Sources/IceCpp/include/IceUtil/Unicode.h @@ -0,0 +1,43 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_UTIL_UNICODE_H +#define ICE_UTIL_UNICODE_H + +#include +#include + +namespace IceUtilInternal +{ + +// +// Convert UTF-8 byte-sequences to and from UTF-16 or UTF-32 (with native endianness) +// +// These are wrappers for Unicode's ConvertUTF.h/cpp. + +// +// Convert wstring encoded with UTF-16 or UTF-32 to UTF-8. +// Returns false if needs for space and true upon success. +// Throws IllegalConversionException to report error +// +bool +convertUTFWstringToUTF8(const wchar_t*& sourceStart, const wchar_t* sourceEnd, + IceUtil::Byte*& targetStart, IceUtil::Byte* targetEnd); + +void +convertUTF8ToUTFWstring(const IceUtil::Byte*& sourceStart, const IceUtil::Byte* sourceEnd, + std::wstring& target); + +void +convertUTF8ToUTF16(const std::vector&, std::vector&); + +void +convertUTF8ToUTF32(const std::vector&, std::vector&); + +void +convertUTF32ToUTF8(const std::vector&, std::vector&); + +} + +#endif diff --git a/Sources/IceDiscoveryCpp/IceDiscovery.cpp b/Sources/IceDiscoveryCpp/IceDiscovery.cpp new file mode 100644 index 0000000..8953334 --- /dev/null +++ b/Sources/IceDiscoveryCpp/IceDiscovery.cpp @@ -0,0 +1,915 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `IceDiscovery.ice' +// +// Warning: do not edit this file. +// +// +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_IceDiscovery_LookupReply_ids[2] = +{ + "::Ice::Object", + "::IceDiscovery::LookupReply" +}; +const ::std::string iceC_IceDiscovery_LookupReply_ops[] = +{ + "foundAdapterById", + "foundObjectById", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_IceDiscovery_LookupReply_foundObjectById_name = "foundObjectById"; +const ::std::string iceC_IceDiscovery_LookupReply_foundAdapterById_name = "foundAdapterById"; + +const ::std::string iceC_IceDiscovery_Lookup_ids[2] = +{ + "::Ice::Object", + "::IceDiscovery::Lookup" +}; +const ::std::string iceC_IceDiscovery_Lookup_ops[] = +{ + "findAdapterById", + "findObjectById", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_IceDiscovery_Lookup_findObjectById_name = "findObjectById"; +const ::std::string iceC_IceDiscovery_Lookup_findAdapterById_name = "findAdapterById"; + +} + +bool +IceDiscovery::LookupReply::ice_isA(::std::string s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceDiscovery_LookupReply_ids, iceC_IceDiscovery_LookupReply_ids + 2, s); +} + +::std::vector<::std::string> +IceDiscovery::LookupReply::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector<::std::string>(&iceC_IceDiscovery_LookupReply_ids[0], &iceC_IceDiscovery_LookupReply_ids[2]); +} + +::std::string +IceDiscovery::LookupReply::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceDiscovery::LookupReply::ice_staticId() +{ + static const ::std::string typeId = "::IceDiscovery::LookupReply"; + return typeId; +} + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceD_foundObjectById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::Ice::Identity iceP_id; + ::std::shared_ptr<::Ice::ObjectPrx> iceP_prx; + istr->readAll(iceP_id, iceP_prx); + inS.endReadParams(); + this->foundObjectById(::std::move(iceP_id), ::std::move(iceP_prx), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceD_foundAdapterById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_id; + ::std::shared_ptr<::Ice::ObjectPrx> iceP_prx; + bool iceP_isReplicaGroup; + istr->readAll(iceP_id, iceP_prx, iceP_isReplicaGroup); + inS.endReadParams(); + this->foundAdapterById(::std::move(iceP_id), ::std::move(iceP_prx), iceP_isReplicaGroup, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceDiscovery_LookupReply_ops, iceC_IceDiscovery_LookupReply_ops + 6, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceDiscovery_LookupReply_ops) + { + case 0: + { + return _iceD_foundAdapterById(in, current); + } + case 1: + { + return _iceD_foundObjectById(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +IceDiscovery::Lookup::ice_isA(::std::string s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceDiscovery_Lookup_ids, iceC_IceDiscovery_Lookup_ids + 2, s); +} + +::std::vector<::std::string> +IceDiscovery::Lookup::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector<::std::string>(&iceC_IceDiscovery_Lookup_ids[0], &iceC_IceDiscovery_Lookup_ids[2]); +} + +::std::string +IceDiscovery::Lookup::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceDiscovery::Lookup::ice_staticId() +{ + static const ::std::string typeId = "::IceDiscovery::Lookup"; + return typeId; +} + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceD_findObjectById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_domainId; + ::Ice::Identity iceP_id; + ::std::shared_ptr iceP_reply; + istr->readAll(iceP_domainId, iceP_id, iceP_reply); + inS.endReadParams(); + this->findObjectById(::std::move(iceP_domainId), ::std::move(iceP_id), ::std::move(iceP_reply), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceD_findAdapterById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_domainId; + ::std::string iceP_id; + ::std::shared_ptr iceP_reply; + istr->readAll(iceP_domainId, iceP_id, iceP_reply); + inS.endReadParams(); + this->findAdapterById(::std::move(iceP_domainId), ::std::move(iceP_id), ::std::move(iceP_reply), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceDiscovery_Lookup_ops, iceC_IceDiscovery_Lookup_ops + 6, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceDiscovery_Lookup_ops) + { + case 0: + { + return _iceD_findAdapterById(in, current); + } + case 1: + { + return _iceD_findObjectById(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +IceDiscovery::LookupReplyPrx::_iceI_foundObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::Ice::Identity& iceP_id, const ::std::shared_ptr<::Ice::ObjectPrx>& iceP_prx, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceDiscovery_LookupReply_foundObjectById_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_id, iceP_prx); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +IceDiscovery::LookupReplyPrx::_iceI_foundAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_id, const ::std::shared_ptr<::Ice::ObjectPrx>& iceP_prx, bool iceP_isReplicaGroup, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceDiscovery_LookupReply_foundAdapterById_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_id, iceP_prx, iceP_isReplicaGroup); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +IceDiscovery::LookupReplyPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +IceDiscovery::LookupReplyPrx::ice_staticId() +{ + return LookupReply::ice_staticId(); +} + +/// \cond INTERNAL +void +IceDiscovery::LookupPrx::_iceI_findObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_domainId, const ::Ice::Identity& iceP_id, const ::std::shared_ptr& iceP_reply, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceDiscovery_Lookup_findObjectById_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_domainId, iceP_id, iceP_reply); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +void +IceDiscovery::LookupPrx::_iceI_findAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_domainId, const ::std::string& iceP_id, const ::std::shared_ptr& iceP_reply, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceDiscovery_Lookup_findAdapterById_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_domainId, iceP_id, iceP_reply); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +IceDiscovery::LookupPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +IceDiscovery::LookupPrx::ice_staticId() +{ + return Lookup::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_IceDiscovery_LookupReply_foundObjectById_name = "foundObjectById"; + +const ::std::string iceC_IceDiscovery_LookupReply_foundAdapterById_name = "foundAdapterById"; + +const ::std::string iceC_IceDiscovery_Lookup_findObjectById_name = "findObjectById"; + +const ::std::string iceC_IceDiscovery_Lookup_findAdapterById_name = "findAdapterById"; + +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* ::IceProxy::IceDiscovery::upCast(LookupReply* p) { return p; } + +void +::IceProxy::IceDiscovery::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< LookupReply>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new LookupReply; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::IceDiscovery::LookupReply::_iceI_begin_foundObjectById(const ::Ice::Identity& iceP_id, const ::Ice::ObjectPrx& iceP_prx, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceDiscovery_LookupReply_foundObjectById_name, del, cookie, sync); + try + { + result->prepare(iceC_IceDiscovery_LookupReply_foundObjectById_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + ostr->write(iceP_prx); + result->endWriteParams(); + result->invoke(iceC_IceDiscovery_LookupReply_foundObjectById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceDiscovery::LookupReply::end_foundObjectById(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceDiscovery_LookupReply_foundObjectById_name); +} + +::Ice::AsyncResultPtr +IceProxy::IceDiscovery::LookupReply::_iceI_begin_foundAdapterById(const ::std::string& iceP_id, const ::Ice::ObjectPrx& iceP_prx, bool iceP_isReplicaGroup, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceDiscovery_LookupReply_foundAdapterById_name, del, cookie, sync); + try + { + result->prepare(iceC_IceDiscovery_LookupReply_foundAdapterById_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_id); + ostr->write(iceP_prx); + ostr->write(iceP_isReplicaGroup); + result->endWriteParams(); + result->invoke(iceC_IceDiscovery_LookupReply_foundAdapterById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceDiscovery::LookupReply::end_foundAdapterById(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceDiscovery_LookupReply_foundAdapterById_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceDiscovery::LookupReply::_newInstance() const +{ + return new LookupReply; +} +/// \endcond + +const ::std::string& +IceProxy::IceDiscovery::LookupReply::ice_staticId() +{ + return ::IceDiscovery::LookupReply::ice_staticId(); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* ::IceProxy::IceDiscovery::upCast(Lookup* p) { return p; } + +void +::IceProxy::IceDiscovery::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Lookup>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Lookup; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::IceDiscovery::Lookup::_iceI_begin_findObjectById(const ::std::string& iceP_domainId, const ::Ice::Identity& iceP_id, const ::IceDiscovery::LookupReplyPrx& iceP_reply, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceDiscovery_Lookup_findObjectById_name, del, cookie, sync); + try + { + result->prepare(iceC_IceDiscovery_Lookup_findObjectById_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_domainId); + ostr->write(iceP_id); + ostr->write(iceP_reply); + result->endWriteParams(); + result->invoke(iceC_IceDiscovery_Lookup_findObjectById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceDiscovery::Lookup::end_findObjectById(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceDiscovery_Lookup_findObjectById_name); +} + +::Ice::AsyncResultPtr +IceProxy::IceDiscovery::Lookup::_iceI_begin_findAdapterById(const ::std::string& iceP_domainId, const ::std::string& iceP_id, const ::IceDiscovery::LookupReplyPrx& iceP_reply, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceDiscovery_Lookup_findAdapterById_name, del, cookie, sync); + try + { + result->prepare(iceC_IceDiscovery_Lookup_findAdapterById_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_domainId); + ostr->write(iceP_id); + ostr->write(iceP_reply); + result->endWriteParams(); + result->invoke(iceC_IceDiscovery_Lookup_findAdapterById_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceDiscovery::Lookup::end_findAdapterById(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceDiscovery_Lookup_findAdapterById_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceDiscovery::Lookup::_newInstance() const +{ + return new Lookup; +} +/// \endcond + +const ::std::string& +IceProxy::IceDiscovery::Lookup::ice_staticId() +{ + return ::IceDiscovery::Lookup::ice_staticId(); +} + +IceDiscovery::LookupReply::~LookupReply() +{ +} + +/// \cond INTERNAL +::Ice::Object* IceDiscovery::upCast(LookupReply* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_IceDiscovery_LookupReply_ids[2] = +{ + "::Ice::Object", + "::IceDiscovery::LookupReply" +}; + +} + +bool +IceDiscovery::LookupReply::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceDiscovery_LookupReply_ids, iceC_IceDiscovery_LookupReply_ids + 2, s); +} + +::std::vector< ::std::string> +IceDiscovery::LookupReply::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceDiscovery_LookupReply_ids[0], &iceC_IceDiscovery_LookupReply_ids[2]); +} + +const ::std::string& +IceDiscovery::LookupReply::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceDiscovery::LookupReply::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceDiscovery::LookupReply"; + return typeId; +#else + return iceC_IceDiscovery_LookupReply_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceD_foundObjectById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::Ice::Identity iceP_id; + ::Ice::ObjectPrx iceP_prx; + istr->read(iceP_id); + istr->read(iceP_prx); + inS.endReadParams(); + this->foundObjectById(iceP_id, iceP_prx, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceD_foundAdapterById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_id; + ::Ice::ObjectPrx iceP_prx; + bool iceP_isReplicaGroup; + istr->read(iceP_id); + istr->read(iceP_prx); + istr->read(iceP_isReplicaGroup); + inS.endReadParams(); + this->foundAdapterById(iceP_id, iceP_prx, iceP_isReplicaGroup, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_IceDiscovery_LookupReply_all[] = +{ + "foundAdapterById", + "foundObjectById", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +IceDiscovery::LookupReply::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceDiscovery_LookupReply_all, iceC_IceDiscovery_LookupReply_all + 6, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceDiscovery_LookupReply_all) + { + case 0: + { + return _iceD_foundAdapterById(in, current); + } + case 1: + { + return _iceD_foundObjectById(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +IceDiscovery::LookupReply::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< LookupReply, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceDiscovery::LookupReply::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< LookupReply, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +IceDiscovery::_icePatchObjectPtr(LookupReplyPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = LookupReplyPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(LookupReply::ice_staticId(), v); + } +} +/// \endcond + +IceDiscovery::Lookup::~Lookup() +{ +} + +/// \cond INTERNAL +::Ice::Object* IceDiscovery::upCast(Lookup* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_IceDiscovery_Lookup_ids[2] = +{ + "::Ice::Object", + "::IceDiscovery::Lookup" +}; + +} + +bool +IceDiscovery::Lookup::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceDiscovery_Lookup_ids, iceC_IceDiscovery_Lookup_ids + 2, s); +} + +::std::vector< ::std::string> +IceDiscovery::Lookup::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceDiscovery_Lookup_ids[0], &iceC_IceDiscovery_Lookup_ids[2]); +} + +const ::std::string& +IceDiscovery::Lookup::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceDiscovery::Lookup::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceDiscovery::Lookup"; + return typeId; +#else + return iceC_IceDiscovery_Lookup_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceD_findObjectById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_domainId; + ::Ice::Identity iceP_id; + LookupReplyPrx iceP_reply; + istr->read(iceP_domainId); + istr->read(iceP_id); + istr->read(iceP_reply); + inS.endReadParams(); + this->findObjectById(iceP_domainId, iceP_id, iceP_reply, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceD_findAdapterById(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_domainId; + ::std::string iceP_id; + LookupReplyPrx iceP_reply; + istr->read(iceP_domainId); + istr->read(iceP_id); + istr->read(iceP_reply); + inS.endReadParams(); + this->findAdapterById(iceP_domainId, iceP_id, iceP_reply, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_IceDiscovery_Lookup_all[] = +{ + "findAdapterById", + "findObjectById", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +IceDiscovery::Lookup::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceDiscovery_Lookup_all, iceC_IceDiscovery_Lookup_all + 6, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceDiscovery_Lookup_all) + { + case 0: + { + return _iceD_findAdapterById(in, current); + } + case 1: + { + return _iceD_findObjectById(in, current); + } + case 2: + { + return _iceD_ice_id(in, current); + } + case 3: + { + return _iceD_ice_ids(in, current); + } + case 4: + { + return _iceD_ice_isA(in, current); + } + case 5: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +IceDiscovery::Lookup::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< Lookup, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceDiscovery::Lookup::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< Lookup, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +IceDiscovery::_icePatchObjectPtr(LookupPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = LookupPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Lookup::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceDiscoveryCpp/LocatorI.cpp b/Sources/IceDiscoveryCpp/LocatorI.cpp new file mode 100644 index 0000000..9647b40 --- /dev/null +++ b/Sources/IceDiscoveryCpp/LocatorI.cpp @@ -0,0 +1,265 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceDiscovery; + +LocatorRegistryI::LocatorRegistryI(const Ice::CommunicatorPtr& com) : + _wellKnownProxy(com->stringToProxy("p")->ice_locator(0)->ice_router(0)->ice_collocationOptimized(true)) +{ +} + +#ifdef ICE_CPP11_MAPPING +void +LocatorRegistryI::setAdapterDirectProxyAsync(string adapterId, + shared_ptr proxy, + function response, + function, + const Ice::Current&) +#else +void +LocatorRegistryI::setAdapterDirectProxy_async(const AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb, + const std::string& adapterId, + const ObjectPrxPtr& proxy, + const Current&) +#endif +{ + Lock sync(*this); + if(proxy) + { + _adapters[adapterId] = proxy; + } + else + { + _adapters.erase(adapterId); + } +#ifdef ICE_CPP11_MAPPING + response(); +#else + cb->ice_response(); +#endif +} + +#ifdef ICE_CPP11_MAPPING +void +LocatorRegistryI::setReplicatedAdapterDirectProxyAsync(string adapterId, + string replicaGroupId, + shared_ptr proxy, + function response, + function, + const Ice::Current&) +#else +void +LocatorRegistryI::setReplicatedAdapterDirectProxy_async( + const AMD_LocatorRegistry_setReplicatedAdapterDirectProxyPtr& cb, + const std::string& adapterId, + const std::string& replicaGroupId, + const ObjectPrxPtr& proxy, + const Current&) +#endif +{ + Lock sync(*this); + if(proxy) + { + _adapters[adapterId] = proxy; + map >::iterator p = _replicaGroups.find(replicaGroupId); + if(p == _replicaGroups.end()) + { + p = _replicaGroups.insert(make_pair(replicaGroupId, set())).first; + } + p->second.insert(adapterId); + } + else + { + _adapters.erase(adapterId); + map >::iterator p = _replicaGroups.find(replicaGroupId); + if(p != _replicaGroups.end()) + { + p->second.erase(adapterId); + if(p->second.empty()) + { + _replicaGroups.erase(p); + } + } + } +#ifdef ICE_CPP11_MAPPING + response(); +#else + cb->ice_response(); +#endif +} + +#ifdef ICE_CPP11_MAPPING +void +LocatorRegistryI::setServerProcessProxyAsync(string, + shared_ptr, + function response, + function, + const Ice::Current&) +{ + response(); +} +#else +void +LocatorRegistryI::setServerProcessProxy_async(const AMD_LocatorRegistry_setServerProcessProxyPtr& cb, + const std::string&, + const ProcessPrxPtr&, + const Current&) +{ + cb->ice_response(); +} +#endif + +Ice::ObjectPrxPtr +LocatorRegistryI::findObject(const Ice::Identity& id) const +{ + Lock sync(*this); + if(id.name.empty()) + { + return 0; + } + + Ice::ObjectPrxPtr prx = _wellKnownProxy->ice_identity(id); + + vector adapterIds; + for(map >::const_iterator p = _replicaGroups.begin(); p != _replicaGroups.end(); ++p) + { + try + { + prx->ice_adapterId(p->first)->ice_ping(); + adapterIds.push_back(p->first); + } + catch(const Ice::Exception&) + { + // Ignore + } + } + + if(adapterIds.empty()) + { + for(map::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p) + { + try + { + prx->ice_adapterId(p->first)->ice_ping(); + adapterIds.push_back(p->first); + } + catch(const Ice::Exception&) + { + // Ignore + } + } + } + + if(adapterIds.empty()) + { + return 0; + } + + IceUtilInternal::shuffle(adapterIds.begin(), adapterIds.end()); + return prx->ice_adapterId(adapterIds[0]); +} + +Ice::ObjectPrxPtr +LocatorRegistryI::findAdapter(const string& adapterId, bool& isReplicaGroup) const +{ + Lock sync(*this); + + map::const_iterator p = _adapters.find(adapterId); + if(p != _adapters.end()) + { + isReplicaGroup = false; + return p->second; + } + + map >::const_iterator q = _replicaGroups.find(adapterId); + if(q != _replicaGroups.end()) + { + Ice::EndpointSeq endpoints; + Ice::ObjectPrxPtr prx; + for(set::const_iterator r = q->second.begin(); r != q->second.end(); ++r) + { + map::const_iterator s = _adapters.find(*r); + if(s == _adapters.end()) + { + continue; // TODO: Inconsistency + } + + if(!prx) + { + prx = s->second; + } + + Ice::EndpointSeq endpts = s->second->ice_getEndpoints(); + copy(endpts.begin(), endpts.end(), back_inserter(endpoints)); + } + + if(prx) + { + isReplicaGroup = true; + return prx->ice_endpoints(endpoints); + } + } + + isReplicaGroup = false; + return 0; +} + +LocatorI::LocatorI(const LookupIPtr& lookup, const LocatorRegistryPrxPtr& registry) : _lookup(lookup), _registry(registry) +{ +} + +#ifdef ICE_CPP11_MAPPING +void +LocatorI::findObjectByIdAsync(Ice::Identity id, + function&)> response, + function ex, + const Ice::Current&) const +{ + _lookup->findObject(make_pair(response, ex), id); +} + +void +LocatorI::findAdapterByIdAsync(string adapterId, + function&)> response, + function ex, + const Ice::Current&) const +{ + _lookup->findAdapter(make_pair(response, ex), adapterId); +} +#else +void +LocatorI::findObjectById_async(const AMD_Locator_findObjectByIdPtr& cb, + const Identity& id, + const Current&) const +{ + _lookup->findObject(cb, id); +} + +void +LocatorI::findAdapterById_async(const AMD_Locator_findAdapterByIdPtr& cb, + const std::string& adapterId, + const Current&) const +{ + _lookup->findAdapter(cb, adapterId); +} +#endif + +LocatorRegistryPrxPtr +LocatorI::getRegistry(const Current&) const +{ + return _registry; +} diff --git a/Sources/IceDiscoveryCpp/LookupI.cpp b/Sources/IceDiscoveryCpp/LookupI.cpp new file mode 100644 index 0000000..9908ff6 --- /dev/null +++ b/Sources/IceDiscoveryCpp/LookupI.cpp @@ -0,0 +1,608 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceDiscovery; + +#ifndef ICE_CPP11_MAPPING +namespace +{ + +class AdapterCallbackI : public IceUtil::Shared +{ +public: + + AdapterCallbackI(const LookupIPtr& lookup, const AdapterRequestPtr& request) : _lookup(lookup), _request(request) + { + } + + void + completed(const Ice::AsyncResultPtr& result) + { + try + { + result->throwLocalException(); + } + catch(const Ice::LocalException& ex) + { + _lookup->adapterRequestException(_request, ex); + } + } + +private: + + LookupIPtr _lookup; + AdapterRequestPtr _request; +}; + +class ObjectCallbackI : public IceUtil::Shared +{ +public: + + ObjectCallbackI(const LookupIPtr& lookup, const ObjectRequestPtr& request) : _lookup(lookup), _request(request) + { + } + + void + completed(const Ice::AsyncResultPtr& result) + { + try + { + result->throwLocalException(); + } + catch(const Ice::LocalException& ex) + { + _lookup->objectRequestException(_request, ex); + } + } + +private: + + LookupIPtr _lookup; + ObjectRequestPtr _request; +}; + +} +#endif + +IceDiscovery::Request::Request(const LookupIPtr& lookup, int retryCount) : + _lookup(lookup), _requestId(Ice::generateUUID()), _retryCount(retryCount), _lookupCount(0), _failureCount(0) +{ +} + +bool +IceDiscovery::Request::retry() +{ + return --_retryCount >= 0; +} + +void +IceDiscovery::Request::invoke(const string& domainId, const vector >& lookups) +{ + _lookupCount = lookups.size(); + _failureCount = 0; + Ice::Identity id; + id.name = _requestId; + for(vector >::const_iterator p = lookups.begin(); p != lookups.end(); ++p) + { + invokeWithLookup(domainId, p->first, ICE_UNCHECKED_CAST(LookupReplyPrx, p->second->ice_identity(id))); + } +} + +bool +IceDiscovery::Request::exception() +{ + // + // If all the invocations on all the lookup proxies failed, report it to the locator. + // + if(++_failureCount == _lookupCount) + { + finished(0); + return true; + } + return false; +} + +string +IceDiscovery::Request::getRequestId() const +{ + return _requestId; +} + +AdapterRequest::AdapterRequest(const LookupIPtr& lookup, const std::string& adapterId, int retryCount) : + RequestT(lookup, adapterId, retryCount), + _start(IceUtil::Time::now()) +{ +} + +bool +AdapterRequest::retry() +{ + return _proxies.empty() && --_retryCount >= 0; +} + +bool +AdapterRequest::response(const Ice::ObjectPrxPtr& proxy, bool isReplicaGroup) +{ + if(isReplicaGroup) + { + if(_latency == IceUtil::Time()) + { + _latency = (IceUtil::Time::now() - _start) * _lookup->latencyMultiplier(); + _lookup->timer()->cancel(ICE_SHARED_FROM_THIS); + _lookup->timer()->schedule(ICE_SHARED_FROM_THIS, _latency); + } + _proxies.insert(proxy); + return false; + } + finished(proxy); + return true; +} + +void +AdapterRequest::finished(const ObjectPrxPtr& proxy) +{ + if(proxy || _proxies.empty()) + { + RequestT::finished(proxy); + } + else if(_proxies.size() == 1) + { + RequestT::finished(*_proxies.begin()); + } + else + { + EndpointSeq endpoints; + ObjectPrxPtr prx; + for(set::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + { + if(!prx) + { + prx = *p; + } + Ice::EndpointSeq endpts = (*p)->ice_getEndpoints(); + copy(endpts.begin(), endpts.end(), back_inserter(endpoints)); + } + RequestT::finished(prx->ice_endpoints(endpoints)); + } +} + +void +AdapterRequest::invokeWithLookup(const string& domainId, const LookupPrxPtr& lookup, const LookupReplyPrxPtr& lookupReply) +{ +#ifdef ICE_CPP11_MAPPING + auto self = ICE_SHARED_FROM_THIS; + lookup->findAdapterByIdAsync(domainId, _id, lookupReply, nullptr, [self](exception_ptr ex) + { + try + { + rethrow_exception(ex); + } + catch(const Ice::LocalException& e) + { + self->_lookup->adapterRequestException(self, e); + } + }); +#else + lookup->begin_findAdapterById(domainId, _id, lookupReply, newCallback(new AdapterCallbackI(_lookup, this), + &AdapterCallbackI::completed)); +#endif +} + +void +AdapterRequest::runTimerTask() +{ + _lookup->adapterRequestTimedOut(ICE_SHARED_FROM_THIS); +} + +ObjectRequest::ObjectRequest(const LookupIPtr& lookup, const Ice::Identity& id, int retryCount) : + RequestT(lookup, id, retryCount) +{ +} + +void +ObjectRequest::response(const Ice::ObjectPrxPtr& proxy) +{ + finished(proxy); +} + +void +ObjectRequest::invokeWithLookup(const string& domainId, const LookupPrxPtr& lookup, const LookupReplyPrxPtr& lookupReply) +{ +#ifdef ICE_CPP11_MAPPING + auto self = ICE_SHARED_FROM_THIS; + lookup->findObjectByIdAsync(domainId, _id, lookupReply, nullptr, [self](exception_ptr ex) + { + try + { + rethrow_exception(ex); + } + catch(const Ice::LocalException& e) + { + self->_lookup->objectRequestException(self, e); + } + }); +#else + lookup->begin_findObjectById(domainId, _id, lookupReply, newCallback(new ObjectCallbackI(_lookup, this), + &ObjectCallbackI::completed)); + +#endif +} + +void +ObjectRequest::runTimerTask() +{ + _lookup->objectRequestTimedOut(ICE_SHARED_FROM_THIS); +} + +LookupI::LookupI(const LocatorRegistryIPtr& registry, const LookupPrxPtr& lookup, const Ice::PropertiesPtr& properties) : + _registry(registry), + _lookup(lookup), + _timeout(IceUtil::Time::milliSeconds(properties->getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300))), + _retryCount(properties->getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3)), + _latencyMultiplier(properties->getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1)), + _domainId(properties->getProperty("IceDiscovery.DomainId")), + _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())), + _warnOnce(true) +{ + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + EndpointSeq endpoints = lookup->ice_getEndpoints(); + for(vector::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + EndpointSeq single; + single.push_back(*p); + _lookups.push_back(make_pair(lookup->ice_endpoints(single), LookupReplyPrxPtr())); + } + assert(!_lookups.empty()); +} + +LookupI::~LookupI() +{ +} + +void +LookupI::destroy() +{ + Lock sync(*this); + for(map::const_iterator p = _objectRequests.begin(); p != _objectRequests.end(); ++p) + { + p->second->finished(0); + _timer->cancel(p->second); + } + _objectRequests.clear(); + + for(map::const_iterator p = _adapterRequests.begin(); p != _adapterRequests.end(); ++p) + { + p->second->finished(0); + _timer->cancel(p->second); + } + _adapterRequests.clear(); +} + +void +LookupI::setLookupReply(const LookupReplyPrxPtr& lookupReply) +{ + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + for(vector >::iterator p = _lookups.begin(); p != _lookups.end(); ++p) + { + UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo()); + if(info && !info->mcastInterface.empty()) + { + EndpointSeq endpts = lookupReply->ice_getEndpoints(); + for(EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q) + { + IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(IPEndpointInfo, (*q)->getInfo()); + if(r && r->host == info->mcastInterface) + { + EndpointSeq single; + single.push_back(*q); + p->second = lookupReply->ice_endpoints(single); + } + } + } + + if(!p->second) + { + p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found. + } + } +} + +void +LookupI::findObjectById(ICE_IN(string) domainId, ICE_IN(Ice::Identity) id, ICE_IN(LookupReplyPrxPtr) reply, + const Ice::Current&) +{ + if(domainId != _domainId) + { + return; // Ignore. + } + + Ice::ObjectPrxPtr proxy = _registry->findObject(id); + if(proxy) + { + // + // Reply to the mulicast request using the given proxy. + // + try + { +#ifdef ICE_CPP11_MAPPING + reply->foundObjectByIdAsync(id, proxy); +#else + reply->begin_foundObjectById(id, proxy); +#endif + } + catch(const Ice::LocalException&) + { + // Ignore. + } + } +} + +void +LookupI::findAdapterById(ICE_IN(string) domainId, ICE_IN(string) adapterId, ICE_IN(LookupReplyPrxPtr) reply, + const Ice::Current&) +{ + if(domainId != _domainId) + { + return; // Ignore. + } + + bool isReplicaGroup; + Ice::ObjectPrxPtr proxy = _registry->findAdapter(adapterId, isReplicaGroup); + if(proxy) + { + // + // Reply to the multicast request using the given proxy. + // + try + { +#ifdef ICE_CPP11_MAPPING + reply->foundAdapterByIdAsync(adapterId, proxy, isReplicaGroup); +#else + reply->begin_foundAdapterById(adapterId, proxy, isReplicaGroup); +#endif + } + catch(const Ice::LocalException&) + { + // Ignore. + } + } +} + +void +LookupI::findObject(const ObjectCB& cb, const Ice::Identity& id) +{ + Lock sync(*this); + map::iterator p = _objectRequests.find(id); + if(p == _objectRequests.end()) + { + p = _objectRequests.insert(make_pair(id, ICE_MAKE_SHARED(ObjectRequest, + ICE_SHARED_FROM_THIS, + id, + _retryCount))).first; + } + + if(p->second->addCallback(cb)) + { + try + { + p->second->invoke(_domainId, _lookups); + _timer->schedule(p->second, _timeout); + } + catch(const Ice::LocalException&) + { + p->second->finished(ICE_NULLPTR); + _objectRequests.erase(p); + } + } +} + +void +LookupI::findAdapter(const AdapterCB& cb, const std::string& adapterId) +{ + Lock sync(*this); + map::iterator p = _adapterRequests.find(adapterId); + if(p == _adapterRequests.end()) + { + p = _adapterRequests.insert(make_pair(adapterId, ICE_MAKE_SHARED(AdapterRequest, + ICE_SHARED_FROM_THIS, + adapterId, + _retryCount))).first; + } + + if(p->second->addCallback(cb)) + { + try + { + p->second->invoke(_domainId, _lookups); + _timer->schedule(p->second, _timeout); + } + catch(const Ice::LocalException&) + { + p->second->finished(ICE_NULLPTR); + _adapterRequests.erase(p); + } + } +} + +void +LookupI::foundObject(const Ice::Identity& id, const string& requestId, const Ice::ObjectPrxPtr& proxy) +{ + Lock sync(*this); + map::iterator p = _objectRequests.find(id); + if(p != _objectRequests.end() && p->second->getRequestId() == requestId) // Ignore responses from old requests + { + p->second->response(proxy); + _timer->cancel(p->second); + _objectRequests.erase(p); + } +} + +void +LookupI::foundAdapter(const string& adapterId, const string& requestId, const Ice::ObjectPrxPtr& proxy, + bool isReplicaGroup) +{ + Lock sync(*this); + map::iterator p = _adapterRequests.find(adapterId); + if(p != _adapterRequests.end() && p->second->getRequestId() == requestId) // Ignore responses from old requests + { + if(p->second->response(proxy, isReplicaGroup)) + { + _timer->cancel(p->second); + _adapterRequests.erase(p); + } + } +} + +void +LookupI::objectRequestTimedOut(const ObjectRequestPtr& request) +{ + Lock sync(*this); + map::iterator p = _objectRequests.find(request->getId()); + if(p == _objectRequests.end() || p->second.get() != request.get()) + { + return; + } + + if(request->retry()) + { + try + { + request->invoke(_domainId, _lookups); + _timer->schedule(request, _timeout); + return; + } + catch(const Ice::LocalException&) + { + } + } + + request->finished(0); + _objectRequests.erase(p); + _timer->cancel(request); +} + +void +LookupI::adapterRequestException(const AdapterRequestPtr& request, const LocalException& ex) +{ + Lock sync(*this); + map::iterator p = _adapterRequests.find(request->getId()); + if(p == _adapterRequests.end() || p->second.get() != request.get()) + { + return; + } + + if(request->exception()) + { + if(_warnOnce) + { + Warning warn(_lookup->ice_getCommunicator()->getLogger()); + warn << "failed to lookup adapter `" << p->first << "' with lookup proxy `" << _lookup << "':\n" << ex; + _warnOnce = false; + } + _timer->cancel(request); + _adapterRequests.erase(p); + } +} + +void +LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request) +{ + Lock sync(*this); + map::iterator p = _adapterRequests.find(request->getId()); + if(p == _adapterRequests.end() || p->second.get() != request.get()) + { + return; + } + + if(request->retry()) + { + try + { + request->invoke(_domainId, _lookups); + _timer->schedule(request, _timeout); + return; + } + catch(const Ice::LocalException&) + { + } + } + + request->finished(0); + _adapterRequests.erase(p); + _timer->cancel(request); +} + +void +LookupI::objectRequestException(const ObjectRequestPtr& request, const LocalException& ex) +{ + Lock sync(*this); + map::iterator p = _objectRequests.find(request->getId()); + if(p == _objectRequests.end() || p->second.get() != request.get()) + { + return; + } + + if(request->exception()) + { + if(_warnOnce) + { + Warning warn(_lookup->ice_getCommunicator()->getLogger()); + string id = _lookup->ice_getCommunicator()->identityToString(p->first); + warn << "failed to lookup object `" << id << "' with lookup proxy `" << _lookup << "':\n" << ex; + _warnOnce = false; + } + _timer->cancel(request); + _objectRequests.erase(p); + } +} + +LookupReplyI::LookupReplyI(const LookupIPtr& lookup) : _lookup(lookup) +{ +} + +#ifdef ICE_CPP11_MAPPING +void +LookupReplyI::foundObjectById(Identity id, shared_ptr proxy, const Current& current) +{ + _lookup->foundObject(id, current.id.name, proxy); +} + +void +LookupReplyI::foundAdapterById(string adapterId, shared_ptr proxy, bool isReplicaGroup, + const Current& current) +{ + _lookup->foundAdapter(adapterId, current.id.name, proxy, isReplicaGroup); +} +#else +void +LookupReplyI::foundObjectById(const Identity& id, const ObjectPrxPtr& proxy, const Current& current) +{ + _lookup->foundObject(id, current.id.name, proxy); +} + +void +LookupReplyI::foundAdapterById(const string& adapterId, const ObjectPrxPtr& proxy, bool isReplicaGroup, + const Current& current) +{ + _lookup->foundAdapter(adapterId, current.id.name, proxy, isReplicaGroup); +} +#endif diff --git a/Sources/IceDiscoveryCpp/PluginI.cpp b/Sources/IceDiscoveryCpp/PluginI.cpp new file mode 100644 index 0000000..e488fbb --- /dev/null +++ b/Sources/IceDiscoveryCpp/PluginI.cpp @@ -0,0 +1,176 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include // For getInterfacesForMulticast + +#include +#include +#include + +using namespace std; +using namespace IceDiscovery; + +#ifndef ICE_DISCOVERY_API +# ifdef ICE_DISCOVERY_API_EXPORTS +# define ICE_DISCOVERY_API ICE_DECLSPEC_EXPORT +# else +# define ICE_DISCOVERY_API /**/ +# endif +#endif + +// +// Plugin factory function. +// +extern "C" ICE_DISCOVERY_API Ice::Plugin* +createIceDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginI(communicator); +} + +namespace Ice +{ + +ICE_DISCOVERY_API void +registerIceDiscovery(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceDiscovery", createIceDiscovery, loadOnInitialize); + +#ifdef ICE_STATIC_LIBS + // + // Also register the UDP plugin with static builds to ensure the UDP transport is loaded. + // + registerIceUDP(true); +#endif +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_DISCOVERY_API void +ICEregisterIceDiscovery(bool loadOnInitialize) +{ + Ice::registerIceDiscovery(loadOnInitialize); +} + +PluginI::PluginI(const Ice::CommunicatorPtr& communicator) : _communicator(communicator) +{ +} + +void +PluginI::initialize() +{ + Ice::PropertiesPtr properties = _communicator->getProperties(); + + bool ipv4 = properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; + bool preferIPv6 = properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0; + string address; + if(ipv4 && !preferIPv6) + { + address = properties->getPropertyWithDefault("IceDiscovery.Address", "239.255.0.1"); + } + else + { + address = properties->getPropertyWithDefault("IceDiscovery.Address", "ff15::1"); + } + int port = properties->getPropertyAsIntWithDefault("IceDiscovery.Port", 4061); + string intf = properties->getProperty("IceDiscovery.Interface"); + + if(properties->getProperty("IceDiscovery.Multicast.Endpoints").empty()) + { + ostringstream os; + os << "udp -h \"" << address << "\" -p " << port; + if(!intf.empty()) + { + os << " --interface \"" << intf << "\""; + } + properties->setProperty("IceDiscovery.Multicast.Endpoints", os.str()); + } + + string lookupEndpoints = properties->getProperty("IceDiscovery.Lookup"); + if(lookupEndpoints.empty()) + { + // + // If no lookup endpoints are specified, we get all the network interfaces and create + // an endpoint for each of them. We'll send UDP multicast packages on each interface. + // + IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6; + vector interfaces = IceInternal::getInterfacesForMulticast(intf, protocol); + ostringstream lookup; + for(vector::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) + { + if(p != interfaces.begin()) + { + lookup << ":"; + } + lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\""; + } + lookupEndpoints = lookup.str(); + } + + if(properties->getProperty("IceDiscovery.Reply.Endpoints").empty()) + { + properties->setProperty("IceDiscovery.Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\"")); + } + + if(properties->getProperty("IceDiscovery.Locator.Endpoints").empty()) + { + properties->setProperty("IceDiscovery.Locator.AdapterId", Ice::generateUUID()); + } + + _multicastAdapter = _communicator->createObjectAdapter("IceDiscovery.Multicast"); + _replyAdapter = _communicator->createObjectAdapter("IceDiscovery.Reply"); + _locatorAdapter = _communicator->createObjectAdapter("IceDiscovery.Locator"); + + // + // Setup locatory registry. + // + LocatorRegistryIPtr locatorRegistry = ICE_MAKE_SHARED(LocatorRegistryI, _communicator); + Ice::LocatorRegistryPrxPtr locatorRegistryPrx = + ICE_UNCHECKED_CAST(Ice::LocatorRegistryPrx, _locatorAdapter->addWithUUID(locatorRegistry)); + + Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints); + // No collocation optimization for the multicast proxy! + lookupPrx = lookupPrx->ice_collocationOptimized(false)->ice_router(ICE_NULLPTR); + + // + // Add lookup and lookup reply Ice objects + // + _lookup = ICE_MAKE_SHARED(LookupI, locatorRegistry, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties); + _multicastAdapter->add(_lookup, Ice::stringToIdentity("IceDiscovery/Lookup")); + + _replyAdapter->addDefaultServant(ICE_MAKE_SHARED(LookupReplyI, _lookup), ""); + Ice::Identity id; + id.name = "dummy"; + _lookup->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, _replyAdapter->createProxy(id)->ice_datagram())); + + // + // Setup locator on the communicator. + // + Ice::ObjectPrxPtr loc = _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(LocatorI, _lookup, locatorRegistryPrx)); + _defaultLocator = _communicator->getDefaultLocator(); + _locator = ICE_UNCHECKED_CAST(Ice::LocatorPrx, loc); + _communicator->setDefaultLocator(_locator); + + _multicastAdapter->activate(); + _replyAdapter->activate(); + _locatorAdapter->activate(); +} + +void +PluginI::destroy() +{ + _multicastAdapter->destroy(); + _replyAdapter->destroy(); + _locatorAdapter->destroy(); + _lookup->destroy(); + // Restore original default locator proxy, if the user didn't change it in the meantime. + if(_communicator->getDefaultLocator() == _locator) + { + _communicator->setDefaultLocator(_defaultLocator); + } +} diff --git a/Sources/IceDiscoveryCpp/include/IceDiscovery/IceDiscovery.h b/Sources/IceDiscoveryCpp/include/IceDiscovery/IceDiscovery.h new file mode 100644 index 0000000..ce13e48 --- /dev/null +++ b/Sources/IceDiscoveryCpp/include/IceDiscovery/IceDiscovery.h @@ -0,0 +1,1889 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `IceDiscovery.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceDiscovery_IceDiscovery_h__ +#define __IceDiscovery_IceDiscovery_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceDiscovery +{ + +class LookupReply; +class LookupReplyPrx; +class Lookup; +class LookupPrx; + +} + +namespace IceDiscovery +{ + +/** + * The LookupReply interface is used by IceDiscovery clients to answer requests + * received on the Lookup interface. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class LookupReply : public virtual ::Ice::Object +{ +public: + + using ProxyType = LookupReplyPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const ::Ice::Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const ::Ice::Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param current The Current object for the invocation. + */ + virtual void foundObjectById(::Ice::Identity id, ::std::shared_ptr<::Ice::ObjectPrx> prx, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_foundObjectById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param current The Current object for the invocation. + */ + virtual void foundAdapterById(::std::string id, ::std::shared_ptr<::Ice::ObjectPrx> prx, bool isReplicaGroup, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_foundAdapterById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override; + /// \endcond +}; + +/** + * The Lookup interface is used by IceDiscovery clients to look for objects + * and adapters using UDP multicast. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class Lookup : public virtual ::Ice::Object +{ +public: + + using ProxyType = LookupPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const ::Ice::Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const ::Ice::Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param current The Current object for the invocation. + */ + virtual void findObjectById(::std::string domainId, ::Ice::Identity id, ::std::shared_ptr reply, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_findObjectById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param current The Current object for the invocation. + */ + virtual void findAdapterById(::std::string domainId, ::std::string id, ::std::shared_ptr reply, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_findAdapterById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override; + /// \endcond +}; + +} + +namespace IceDiscovery +{ + +/** + * The LookupReply interface is used by IceDiscovery clients to answer requests + * received on the Lookup interface. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class LookupReplyPrx : public virtual ::Ice::Proxy +{ +public: + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + */ + void foundObjectById(const ::Ice::Identity& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupReplyPrx::_iceI_foundObjectById, id, prx, context).get(); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto foundObjectByIdAsync(const ::Ice::Identity& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupReplyPrx::_iceI_foundObjectById, id, prx, context); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + foundObjectByIdAsync(const ::Ice::Identity& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceDiscovery::LookupReplyPrx::_iceI_foundObjectById, id, prx, context); + } + + /// \cond INTERNAL + void _iceI_foundObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::Ice::Identity&, const ::std::shared_ptr<::Ice::ObjectPrx>&, const ::Ice::Context&); + /// \endcond + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + */ + void foundAdapterById(const ::std::string& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, bool isReplicaGroup, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupReplyPrx::_iceI_foundAdapterById, id, prx, isReplicaGroup, context).get(); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto foundAdapterByIdAsync(const ::std::string& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, bool isReplicaGroup, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupReplyPrx::_iceI_foundAdapterById, id, prx, isReplicaGroup, context); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + foundAdapterByIdAsync(const ::std::string& id, const ::std::shared_ptr<::Ice::ObjectPrx>& prx, bool isReplicaGroup, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceDiscovery::LookupReplyPrx::_iceI_foundAdapterById, id, prx, isReplicaGroup, context); + } + + /// \cond INTERNAL + void _iceI_foundAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::shared_ptr<::Ice::ObjectPrx>&, bool, const ::Ice::Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LookupReplyPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override; + /// \endcond +}; + +/** + * The Lookup interface is used by IceDiscovery clients to look for objects + * and adapters using UDP multicast. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class LookupPrx : public virtual ::Ice::Proxy +{ +public: + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + */ + void findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupPrx::_iceI_findObjectById, domainId, id, reply, context).get(); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto findObjectByIdAsync(const ::std::string& domainId, const ::Ice::Identity& id, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupPrx::_iceI_findObjectById, domainId, id, reply, context); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + findObjectByIdAsync(const ::std::string& domainId, const ::Ice::Identity& id, const ::std::shared_ptr& reply, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceDiscovery::LookupPrx::_iceI_findObjectById, domainId, id, reply, context); + } + + /// \cond INTERNAL + void _iceI_findObjectById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::Ice::Identity&, const ::std::shared_ptr&, const ::Ice::Context&); + /// \endcond + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + */ + void findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupPrx::_iceI_findAdapterById, domainId, id, reply, context).get(); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto findAdapterByIdAsync(const ::std::string& domainId, const ::std::string& id, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupPrx::_iceI_findAdapterById, domainId, id, reply, context); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + findAdapterByIdAsync(const ::std::string& domainId, const ::std::string& id, const ::std::shared_ptr& reply, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceDiscovery::LookupPrx::_iceI_findAdapterById, domainId, id, reply, context); + } + + /// \cond INTERNAL + void _iceI_findAdapterById(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::string&, const ::std::shared_ptr&, const ::Ice::Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LookupPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceDiscovery +{ + +using LookupReplyPtr = ::std::shared_ptr; +using LookupReplyPrxPtr = ::std::shared_ptr; + +using LookupPtr = ::std::shared_ptr; +using LookupPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace IceDiscovery +{ + +class LookupReply; +/// \cond INTERNAL +void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LookupReply>&); +::IceProxy::Ice::Object* upCast(LookupReply*); +/// \endcond + +class Lookup; +/// \cond INTERNAL +void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Lookup>&); +::IceProxy::Ice::Object* upCast(Lookup*); +/// \endcond + +} + +} + +namespace IceDiscovery +{ + +class LookupReply; +/// \cond INTERNAL +::Ice::Object* upCast(LookupReply*); +/// \endcond +typedef ::IceInternal::Handle< LookupReply> LookupReplyPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceDiscovery::LookupReply> LookupReplyPrx; +typedef LookupReplyPrx LookupReplyPrxPtr; +/// \cond INTERNAL +void _icePatchObjectPtr(LookupReplyPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class Lookup; +/// \cond INTERNAL +::Ice::Object* upCast(Lookup*); +/// \endcond +typedef ::IceInternal::Handle< Lookup> LookupPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceDiscovery::Lookup> LookupPrx; +typedef LookupPrx LookupPrxPtr; +/// \cond INTERNAL +void _icePatchObjectPtr(LookupPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +} + +namespace IceDiscovery +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundObjectById. + */ +class Callback_LookupReply_foundObjectById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LookupReply_foundObjectById_Base> Callback_LookupReply_foundObjectByIdPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundAdapterById. + */ +class Callback_LookupReply_foundAdapterById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LookupReply_foundAdapterById_Base> Callback_LookupReply_foundAdapterByIdPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findObjectById. + */ +class Callback_Lookup_findObjectById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Lookup_findObjectById_Base> Callback_Lookup_findObjectByIdPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findAdapterById. + */ +class Callback_Lookup_findAdapterById_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Lookup_findAdapterById_Base> Callback_Lookup_findAdapterByIdPtr; + +} + +namespace IceProxy +{ + +namespace IceDiscovery +{ + +class LookupReply : public virtual ::Ice::Proxy +{ +public: + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + */ + void foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_foundObjectById(_iceI_begin_foundObjectById(id, prx, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_foundObjectById(id, prx, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundObjectById(id, prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundObjectById(id, prx, context, cb, cookie); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::IceDiscovery::Callback_LookupReply_foundObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundObjectById(id, prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::Context& context, const ::IceDiscovery::Callback_LookupReply_foundObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundObjectById(id, prx, context, cb, cookie); + } + + /** + * Completes an invocation of begin_foundObjectById. + * @param result The asynchronous result object for the invocation. + */ + void end_foundObjectById(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_foundObjectById(const ::Ice::Identity&, const ::Ice::ObjectPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + */ + void foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_foundAdapterById(_iceI_begin_foundAdapterById(id, prx, isReplicaGroup, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_foundAdapterById(id, prx, isReplicaGroup, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundAdapterById(id, prx, isReplicaGroup, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundAdapterById(id, prx, isReplicaGroup, context, cb, cookie); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::IceDiscovery::Callback_LookupReply_foundAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundAdapterById(id, prx, isReplicaGroup, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::Context& context, const ::IceDiscovery::Callback_LookupReply_foundAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundAdapterById(id, prx, isReplicaGroup, context, cb, cookie); + } + + /** + * Completes an invocation of begin_foundAdapterById. + * @param result The asynchronous result object for the invocation. + */ + void end_foundAdapterById(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_foundAdapterById(const ::std::string&, const ::Ice::ObjectPrx&, bool, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class Lookup : public virtual ::Ice::Proxy +{ +public: + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + */ + void findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_findObjectById(_iceI_begin_findObjectById(domainId, id, reply, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_findObjectById(domainId, id, reply, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(domainId, id, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(domainId, id, reply, context, cb, cookie); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::IceDiscovery::Callback_Lookup_findObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(domainId, id, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::IceDiscovery::Callback_Lookup_findObjectByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findObjectById(domainId, id, reply, context, cb, cookie); + } + + /** + * Completes an invocation of begin_findObjectById. + * @param result The asynchronous result object for the invocation. + */ + void end_findObjectById(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_findObjectById(const ::std::string&, const ::Ice::Identity&, const ::IceDiscovery::LookupReplyPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + */ + void findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_findAdapterById(_iceI_begin_findAdapterById(domainId, id, reply, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_findAdapterById(domainId, id, reply, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(domainId, id, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(domainId, id, reply, context, cb, cookie); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::IceDiscovery::Callback_Lookup_findAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(domainId, id, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findAdapterById(const ::std::string& domainId, const ::std::string& id, const ::IceDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::IceDiscovery::Callback_Lookup_findAdapterByIdPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findAdapterById(domainId, id, reply, context, cb, cookie); + } + + /** + * Completes an invocation of begin_findAdapterById. + * @param result The asynchronous result object for the invocation. + */ + void end_findAdapterById(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_findAdapterById(const ::std::string&, const ::std::string&, const ::IceDiscovery::LookupReplyPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace IceDiscovery +{ + +/** + * The LookupReply interface is used by IceDiscovery clients to answer requests + * received on the Lookup interface. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class LookupReply : public virtual ::Ice::Object +{ +public: + + typedef LookupReplyPrx ProxyType; + typedef LookupReplyPtr PointerType; + + virtual ~LookupReply(); + +#ifdef ICE_CPP11_COMPILER + LookupReply() = default; + LookupReply(const LookupReply&) = default; + LookupReply& operator=(const LookupReply&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Reply to the findObjectById request. + * @param id The identity of the object. + * @param prx The proxy of the object. + * @param current The Current object for the invocation. + */ + virtual void foundObjectById(const ::Ice::Identity& id, const ::Ice::ObjectPrx& prx, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_foundObjectById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Reply to the findAdpaterById request. + * @param id The adapter ID. + * @param prx The adapter proxy (a dummy proxy created by the adapter). + * The proxy provides the adapter endpoints. + * @param isReplicaGroup True if the adapter is also a member of a + * replica group. + * @param current The Current object for the invocation. + */ + virtual void foundAdapterById(const ::std::string& id, const ::Ice::ObjectPrx& prx, bool isReplicaGroup, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_foundAdapterById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const LookupReply& lhs, const LookupReply& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const LookupReply& lhs, const LookupReply& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The Lookup interface is used by IceDiscovery clients to look for objects + * and adapters using UDP multicast. + * \headerfile IceDiscovery/IceDiscovery.h + */ +class Lookup : public virtual ::Ice::Object +{ +public: + + typedef LookupPrx ProxyType; + typedef LookupPtr PointerType; + + virtual ~Lookup(); + +#ifdef ICE_CPP11_COMPILER + Lookup() = default; + Lookup(const Lookup&) = default; + Lookup& operator=(const Lookup&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Request to find an Ice object + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The object identity. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching object is found. + * @param current The Current object for the invocation. + */ + virtual void findObjectById(const ::std::string& domainId, const ::Ice::Identity& id, const LookupReplyPrx& reply, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_findObjectById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /** + * Request to find an object adapter + * @param domainId The IceDiscovery domain identifier. An IceDiscovery client only + * replies to requests with a matching domain identifier. + * @param id The adapter ID. + * @param reply The proxy of the LookupReply interface that should be used to send + * the reply if a matching adapter is found. + * @param current The Current object for the invocation. + */ + virtual void findAdapterById(const ::std::string& domainId, const ::std::string& id, const LookupReplyPrx& reply, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_findAdapterById(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const Lookup& lhs, const Lookup& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Lookup& lhs, const Lookup& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +namespace IceDiscovery +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundObjectById. + */ +template +class CallbackNC_LookupReply_foundObjectById : public Callback_LookupReply_foundObjectById_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LookupReply_foundObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundObjectById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundObjectById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundObjectById. + */ +template +class Callback_LookupReply_foundObjectById : public Callback_LookupReply_foundObjectById_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LookupReply_foundObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundObjectById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundObjectById. + */ +template Callback_LookupReply_foundObjectByIdPtr +newCallback_LookupReply_foundObjectById(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundObjectById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundAdapterById. + */ +template +class CallbackNC_LookupReply_foundAdapterById : public Callback_LookupReply_foundAdapterById_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LookupReply_foundAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundAdapterById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundAdapterById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_LookupReply_foundAdapterById. + */ +template +class Callback_LookupReply_foundAdapterById : public Callback_LookupReply_foundAdapterById_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LookupReply_foundAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundAdapterById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::LookupReply::begin_foundAdapterById. + */ +template Callback_LookupReply_foundAdapterByIdPtr +newCallback_LookupReply_foundAdapterById(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundAdapterById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findObjectById. + */ +template +class CallbackNC_Lookup_findObjectById : public Callback_Lookup_findObjectById_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Lookup_findObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findObjectById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findObjectById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findObjectById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findObjectById. + */ +template +class Callback_Lookup_findObjectById : public Callback_Lookup_findObjectById_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Lookup_findObjectById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findObjectById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findObjectById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findObjectById. + */ +template Callback_Lookup_findObjectByIdPtr +newCallback_Lookup_findObjectById(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findObjectById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findAdapterById. + */ +template +class CallbackNC_Lookup_findAdapterById : public Callback_Lookup_findAdapterById_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Lookup_findAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findAdapterById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findAdapterById(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + * Create a wrapper instance by calling ::IceDiscovery::newCallback_Lookup_findAdapterById. + */ +template +class Callback_Lookup_findAdapterById : public Callback_Lookup_findAdapterById_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Lookup_findAdapterById(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findAdapterById(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findAdapterById(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceDiscovery::Lookup::begin_findAdapterById. + */ +template Callback_Lookup_findAdapterByIdPtr +newCallback_Lookup_findAdapterById(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findAdapterById(instance, 0, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceDiscoveryCpp/include/IceDiscovery/LocatorI.h b/Sources/IceDiscoveryCpp/include/IceDiscovery/LocatorI.h new file mode 100644 index 0000000..34b8921 --- /dev/null +++ b/Sources/IceDiscoveryCpp/include/IceDiscovery/LocatorI.h @@ -0,0 +1,109 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef LOCATORI_H +#define LOCATORI_H + +#include +#include + +#include + +namespace IceDiscovery +{ + +class LocatorRegistryI : public Ice::LocatorRegistry, private IceUtil::Mutex +{ +public: + + LocatorRegistryI(const Ice::CommunicatorPtr&); + +#ifdef ICE_CPP11_MAPPING + virtual void + setAdapterDirectProxyAsync(std::string, + std::shared_ptr, + std::function, + std::function, + const Ice::Current&); + + virtual void + setReplicatedAdapterDirectProxyAsync(std::string, + std::string, + std::shared_ptr, + std::function, + std::function, + const Ice::Current&); + + virtual void + setServerProcessProxyAsync(std::string, + std::shared_ptr, + std::function, + std::function, + const Ice::Current&); +#else + virtual void + setAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr&, const std::string&, + const Ice::ObjectPrx&, const Ice::Current&); + + virtual void + setReplicatedAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setReplicatedAdapterDirectProxyPtr&, + const std::string&, const std::string&, const Ice::ObjectPrx&, + const Ice::Current&); + + virtual void + setServerProcessProxy_async(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr&, const std::string&, + const Ice::ProcessPrx&, const Ice::Current&); +#endif + Ice::ObjectPrxPtr findObject(const Ice::Identity&) const; + Ice::ObjectPrxPtr findAdapter(const std::string&, bool&) const; + +private: + + const Ice::ObjectPrxPtr _wellKnownProxy; + std::map _adapters; + std::map > _replicaGroups; +}; +ICE_DEFINE_PTR(LocatorRegistryIPtr, LocatorRegistryI); + +class LookupI; +ICE_DEFINE_PTR(LookupIPtr, LookupI); + +class LocatorI : public Ice::Locator +{ +public: + + LocatorI(const LookupIPtr&, const Ice::LocatorRegistryPrxPtr&); + +#ifdef ICE_CPP11_MAPPING + virtual void + findObjectByIdAsync(Ice::Identity, + std::function&)>, + std::function, + const Ice::Current&) const; + + virtual void + findAdapterByIdAsync(std::string, + std::function&)>, + std::function, + const Ice::Current&) const; +#else + virtual void + findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr&, const Ice::Identity&, + const Ice::Current&) const; + + virtual void + findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr&, const std::string&, + const Ice::Current&) const; +#endif + virtual Ice::LocatorRegistryPrxPtr getRegistry(const Ice::Current&) const; + +private: + + LookupIPtr _lookup; + Ice::LocatorRegistryPrxPtr _registry; +}; + +}; + +#endif diff --git a/Sources/IceDiscoveryCpp/include/IceDiscovery/LookupI.h b/Sources/IceDiscoveryCpp/include/IceDiscovery/LookupI.h new file mode 100644 index 0000000..348d698 --- /dev/null +++ b/Sources/IceDiscoveryCpp/include/IceDiscovery/LookupI.h @@ -0,0 +1,228 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef LOOKUPI_H +#define LOOKUPI_H + +#include +#include + +#include +#include +#include + +#include + +namespace IceDiscovery +{ + +class LookupI; + +class Request : public IceUtil::TimerTask +{ +public: + + Request(const LookupIPtr&, int); + + virtual bool retry(); + void invoke(const std::string&, const std::vector >&); + bool exception(); + std::string getRequestId() const; + + virtual void finished(const Ice::ObjectPrxPtr&) = 0; + +protected: + + virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&) = 0; + + LookupIPtr _lookup; + const std::string _requestId; + int _retryCount; + size_t _lookupCount; + size_t _failureCount; +}; +ICE_DEFINE_PTR(RequestPtr, Request); + +template class RequestT : public Request +{ +public: + + RequestT(const LookupIPtr& lookup, T id, int retryCount) : Request(lookup, retryCount), _id(id) + { + } + + T getId() const + { + return _id; + } + + bool addCallback(const CB& cb) + { + _callbacks.push_back(cb); + return _callbacks.size() == 1; + } + + virtual void finished(const Ice::ObjectPrxPtr& proxy) + { + for(typename std::vector::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) + { +#ifdef ICE_CPP11_MAPPING + p->first(proxy); +#else + (*p)->ice_response(proxy); +#endif + } + _callbacks.clear(); + } + +protected: + + const T _id; + std::vector _callbacks; +}; + +#ifdef ICE_CPP11_MAPPING +typedef std::pair&)>, + std::function> ObjectCB; +typedef std::pair&)>, + std::function> AdapterCB; +#else +typedef Ice::AMD_Locator_findObjectByIdPtr ObjectCB; +typedef Ice::AMD_Locator_findAdapterByIdPtr AdapterCB; +#endif + +class ObjectRequest : public RequestT +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + ObjectRequest(const LookupIPtr&, const Ice::Identity&, int); + + void response(const Ice::ObjectPrxPtr&); + +private: + + virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&); + virtual void runTimerTask(); +}; +ICE_DEFINE_PTR(ObjectRequestPtr, ObjectRequest); + +class AdapterRequest : public RequestT +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + AdapterRequest(const LookupIPtr&, const std::string&, int); + + bool response(const Ice::ObjectPrxPtr&, bool); + + virtual bool retry(); + virtual void finished(const Ice::ObjectPrxPtr&); + +private: + + virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&); + virtual void runTimerTask(); + + // + // We use a set because the same IceDiscovery plugin might return multiple times + // the same proxy if it's accessible through multiple network interfaces and if we + // also sent the request to multiple interfaces. + // +#ifdef ICE_CPP11_MAPPING + std::set, Ice::TargetCompare, std::less>> _proxies; +#else + std::set _proxies; +#endif + IceUtil::Time _start; + IceUtil::Time _latency; +}; +ICE_DEFINE_PTR(AdapterRequestPtr, AdapterRequest); + +class LookupI : public Lookup, + private IceUtil::Mutex +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + LookupI(const LocatorRegistryIPtr&, const LookupPrxPtr&, const Ice::PropertiesPtr&); + virtual ~LookupI(); + + void destroy(); + + void setLookupReply(const LookupReplyPrxPtr&); + + virtual void findObjectById(ICE_IN(std::string), ICE_IN(Ice::Identity), ICE_IN(IceDiscovery::LookupReplyPrxPtr), + const Ice::Current&); + virtual void findAdapterById(ICE_IN(std::string), ICE_IN(std::string), ICE_IN(IceDiscovery::LookupReplyPrxPtr), + const Ice::Current&); + void findObject(const ObjectCB&, const Ice::Identity&); + void findAdapter(const AdapterCB&, const std::string&); + + void foundObject(const Ice::Identity&, const std::string&, const Ice::ObjectPrxPtr&); + void foundAdapter(const std::string&, const std::string&, const Ice::ObjectPrxPtr&, bool); + + void adapterRequestTimedOut(const AdapterRequestPtr&); + void adapterRequestException(const AdapterRequestPtr&, const Ice::LocalException&); + void objectRequestTimedOut(const ObjectRequestPtr&); + void objectRequestException(const ObjectRequestPtr&, const Ice::LocalException&); + + const IceUtil::TimerPtr& + timer() + { + return _timer; + } + + int + latencyMultiplier() + { + return _latencyMultiplier; + } + +private: + + LocatorRegistryIPtr _registry; + LookupPrxPtr _lookup; + std::vector > _lookups; + const IceUtil::Time _timeout; + const int _retryCount; + const int _latencyMultiplier; + const std::string _domainId; + + IceUtil::TimerPtr _timer; + Ice::ObjectPrxPtr _wellKnownProxy; + bool _warnOnce; + + std::map _objectRequests; + std::map _adapterRequests; +}; + +class LookupReplyI : public LookupReply +{ +public: + + LookupReplyI(const LookupIPtr&); + +#ifdef ICE_CPP11_MAPPING + virtual void foundObjectById(Ice::Identity, std::shared_ptr, const Ice::Current&); + virtual void foundAdapterById(std::string, std::shared_ptr, bool, const Ice::Current&); +#else + virtual void foundObjectById(const Ice::Identity&, const Ice::ObjectPrx&, const Ice::Current&); + virtual void foundAdapterById(const std::string&, const Ice::ObjectPrx&, bool, const Ice::Current&); +#endif + +private: + + const LookupIPtr _lookup; +}; + +}; + +#endif diff --git a/Sources/IceDiscoveryCpp/include/IceDiscovery/PluginI.h b/Sources/IceDiscoveryCpp/include/IceDiscovery/PluginI.h new file mode 100644 index 0000000..0a0e610 --- /dev/null +++ b/Sources/IceDiscoveryCpp/include/IceDiscovery/PluginI.h @@ -0,0 +1,36 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef PLUGIN_I_H +#define PLUGIN_I_H + +#include +#include + +namespace IceDiscovery +{ + +class PluginI : public Ice::Plugin +{ +public: + + PluginI(const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual void destroy(); + +private: + + const Ice::CommunicatorPtr _communicator; + Ice::ObjectAdapterPtr _multicastAdapter; + Ice::ObjectAdapterPtr _replyAdapter; + Ice::ObjectAdapterPtr _locatorAdapter; + LookupIPtr _lookup; + Ice::LocatorPrxPtr _locator; + Ice::LocatorPrxPtr _defaultLocator; +}; + +}; + +#endif diff --git a/Sources/IceGrid/Admin.swift b/Sources/IceGrid/Admin.swift new file mode 100644 index 0000000..af0e147 --- /dev/null +++ b/Sources/IceGrid/Admin.swift @@ -0,0 +1,11290 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Admin.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit +import Glacier2 + +/// An enumeration representing the state of the server. +public enum ServerState: Swift.UInt8 { + /// Inactive The server is not running. + case Inactive = 0 + /// Activating The server is being activated and will change to the active + /// state when the registered server object adapters are activated + /// or to the activation timed out state if the activation timeout + /// expires. + case Activating = 1 + /// ActivationTimedOut The activation timed out state indicates that the server + /// activation timed out. + case ActivationTimedOut = 2 + /// Active The server is running. + case Active = 3 + /// Deactivating The server is being deactivated. + case Deactivating = 4 + /// Destroying The server is being destroyed. + case Destroying = 5 + /// Destroyed The server is destroyed. + case Destroyed = 6 + public init() { + self = .Inactive + } +} + +/// An `Ice.InputStream` extension to read `ServerState` enumerated values from the stream. +public extension Ice.InputStream { + /// Read an enumerated value. + /// + /// - returns: `ServerState` - The enumarated value. + func read() throws -> ServerState { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 6) + guard let val = ServerState(rawValue: rawValue) else { + throw Ice.MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerState` - The enumerated value. + func read(tag: Swift.Int32) throws -> ServerState? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as ServerState + } +} + +/// An `Ice.OutputStream` extension to write `ServerState` enumerated values to the stream. +public extension Ice.OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `ServerState` - The enumerator to write. + func write(_ v: ServerState) { + write(enum: v.rawValue, maxValue: 6) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `ServerState` - The enumerator to write. + func write(tag: Swift.Int32, value: ServerState?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 6) + } +} + +/// A dictionary of proxies. +public typealias StringObjectProxyDict = [Swift.String: Ice.ObjectPrx?] + +/// Helper class to read and write `StringObjectProxyDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct StringObjectProxyDictHelper { + /// Read a `StringObjectProxyDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `StringObjectProxyDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> StringObjectProxyDict { + let sz = try Swift.Int(istr.readSize()) + var v = StringObjectProxyDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + v[key] = value + } + return v + } + /// Read an optional `StringObjectProxyDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `StringObjectProxyDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> StringObjectProxyDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `StringObjectProxyDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `StringObjectProxyDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: StringObjectProxyDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `StringObjectProxyDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `StringObjectProxyDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: StringObjectProxyDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Information about an Ice object. +public struct ObjectInfo { + /// The proxy of the object. + public var proxy: Ice.ObjectPrx? = nil + /// The type of the object. + public var `type`: Swift.String = "" + + public init() {} + + public init(proxy: Ice.ObjectPrx?, `type`: Swift.String) { + self.proxy = proxy + self.`type` = `type` + } +} + +/// An `Ice.InputStream` extension to read `ObjectInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ObjectInfo` structured value from the stream. + /// + /// - returns: `ObjectInfo` - The structured value read from the stream. + func read() throws -> ObjectInfo { + var v = ObjectInfo() + v.proxy = try self.read(Ice.ObjectPrx.self) + v.`type` = try self.read() + return v + } + + /// Read an optional `ObjectInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ObjectInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ObjectInfo + } +} + +/// An `Ice.OutputStream` extension to write `ObjectInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ObjectInfo` structured value to the stream. + /// + /// - parameter _: `ObjectInfo` - The value to write to the stream. + func write(_ v: ObjectInfo) { + self.write(v.proxy) + self.write(v.`type`) + } + + /// Write an optional `ObjectInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ObjectInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of object information structures. +public typealias ObjectInfoSeq = [ObjectInfo] + +/// Helper class to read and write `ObjectInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ObjectInfoSeqHelper { + /// Read a `ObjectInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ObjectInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ObjectInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 3) + var v = ObjectInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ObjectInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ObjectInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ObjectInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ObjectInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ObjectInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ObjectInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ObjectInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ObjectInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Information about an adapter registered with the IceGrid registry. +public struct AdapterInfo { + /// The id of the adapter. + public var id: Swift.String = "" + /// A dummy direct proxy that contains the adapter endpoints. + public var proxy: Ice.ObjectPrx? = nil + /// The replica group id of the object adapter, or empty if the + /// adapter doesn't belong to a replica group. + public var replicaGroupId: Swift.String = "" + + public init() {} + + public init(id: Swift.String, proxy: Ice.ObjectPrx?, replicaGroupId: Swift.String) { + self.id = id + self.proxy = proxy + self.replicaGroupId = replicaGroupId + } +} + +/// An `Ice.InputStream` extension to read `AdapterInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `AdapterInfo` structured value from the stream. + /// + /// - returns: `AdapterInfo` - The structured value read from the stream. + func read() throws -> AdapterInfo { + var v = AdapterInfo() + v.id = try self.read() + v.proxy = try self.read(Ice.ObjectPrx.self) + v.replicaGroupId = try self.read() + return v + } + + /// Read an optional `AdapterInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> AdapterInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as AdapterInfo + } +} + +/// An `Ice.OutputStream` extension to write `AdapterInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `AdapterInfo` structured value to the stream. + /// + /// - parameter _: `AdapterInfo` - The value to write to the stream. + func write(_ v: AdapterInfo) { + self.write(v.id) + self.write(v.proxy) + self.write(v.replicaGroupId) + } + + /// Write an optional `AdapterInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: AdapterInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of adapter information structures. +public typealias AdapterInfoSeq = [AdapterInfo] + +/// Helper class to read and write `AdapterInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct AdapterInfoSeqHelper { + /// Read a `AdapterInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `AdapterInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> AdapterInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 4) + var v = AdapterInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: AdapterInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `AdapterInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> AdapterInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `AdapterInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `AdapterInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: AdapterInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `AdapterInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: AdapterInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Information about a server managed by an IceGrid node. +public class ServerInfo { + /// The server application. + public var application: Swift.String = "" + /// The application uuid. + public var uuid: Swift.String = "" + /// The application revision. + public var revision: Swift.Int32 = 0 + /// The server node. + public var node: Swift.String = "" + /// The server descriptor. + public var descriptor: ServerDescriptor? = nil + /// The id of the session which allocated the server. + public var sessionId: Swift.String = "" + + public init() {} + + public init(application: Swift.String, uuid: Swift.String, revision: Swift.Int32, node: Swift.String, descriptor: ServerDescriptor?, sessionId: Swift.String) { + self.application = application + self.uuid = uuid + self.revision = revision + self.node = node + self.descriptor = descriptor + self.sessionId = sessionId + } +} + +/// An `Ice.InputStream` extension to read `ServerInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ServerInfo` structured value from the stream. + /// + /// - returns: `ServerInfo` - The structured value read from the stream. + func read() throws -> ServerInfo { + let v = ServerInfo() + v.application = try self.read() + v.uuid = try self.read() + v.revision = try self.read() + v.node = try self.read() + try self.read(ServerDescriptor.self) { v.descriptor = $0 } + v.sessionId = try self.read() + return v + } + + /// Read an optional `ServerInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ServerInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ServerInfo + } +} + +/// An `Ice.OutputStream` extension to write `ServerInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ServerInfo` structured value to the stream. + /// + /// - parameter _: `ServerInfo` - The value to write to the stream. + func write(_ v: ServerInfo) { + self.write(v.application) + self.write(v.uuid) + self.write(v.revision) + self.write(v.node) + self.write(v.descriptor) + self.write(v.sessionId) + } + + /// Write an optional `ServerInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ServerInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Information about an IceGrid node. +public struct NodeInfo: Swift.Hashable { + /// The name of the node. + public var name: Swift.String = "" + /// The operating system name. + public var os: Swift.String = "" + /// The network name of the host running this node (as defined in + /// uname()). + public var hostname: Swift.String = "" + /// The operation system release level (as defined in uname()). + public var release: Swift.String = "" + /// The operation system version (as defined in uname()). + public var version: Swift.String = "" + /// The machine hardware type (as defined in uname()). + public var machine: Swift.String = "" + /// The number of processor threads on the node. + /// For example, nProcessors is 8 on a computer with a single quad-core + /// processor and two HT threads per core. + public var nProcessors: Swift.Int32 = 0 + /// The path to the node data directory. + public var dataDir: Swift.String = "" + + public init() {} + + public init(name: Swift.String, os: Swift.String, hostname: Swift.String, release: Swift.String, version: Swift.String, machine: Swift.String, nProcessors: Swift.Int32, dataDir: Swift.String) { + self.name = name + self.os = os + self.hostname = hostname + self.release = release + self.version = version + self.machine = machine + self.nProcessors = nProcessors + self.dataDir = dataDir + } +} + +/// An `Ice.InputStream` extension to read `NodeInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `NodeInfo` structured value from the stream. + /// + /// - returns: `NodeInfo` - The structured value read from the stream. + func read() throws -> NodeInfo { + var v = NodeInfo() + v.name = try self.read() + v.os = try self.read() + v.hostname = try self.read() + v.release = try self.read() + v.version = try self.read() + v.machine = try self.read() + v.nProcessors = try self.read() + v.dataDir = try self.read() + return v + } + + /// Read an optional `NodeInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> NodeInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as NodeInfo + } +} + +/// An `Ice.OutputStream` extension to write `NodeInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `NodeInfo` structured value to the stream. + /// + /// - parameter _: `NodeInfo` - The value to write to the stream. + func write(_ v: NodeInfo) { + self.write(v.name) + self.write(v.os) + self.write(v.hostname) + self.write(v.release) + self.write(v.version) + self.write(v.machine) + self.write(v.nProcessors) + self.write(v.dataDir) + } + + /// Write an optional `NodeInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: NodeInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Information about an IceGrid registry replica. +public struct RegistryInfo: Swift.Hashable { + /// The name of the registry. + public var name: Swift.String = "" + /// The network name of the host running this registry (as defined in + /// uname()). + public var hostname: Swift.String = "" + + public init() {} + + public init(name: Swift.String, hostname: Swift.String) { + self.name = name + self.hostname = hostname + } +} + +/// An `Ice.InputStream` extension to read `RegistryInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `RegistryInfo` structured value from the stream. + /// + /// - returns: `RegistryInfo` - The structured value read from the stream. + func read() throws -> RegistryInfo { + var v = RegistryInfo() + v.name = try self.read() + v.hostname = try self.read() + return v + } + + /// Read an optional `RegistryInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `RegistryInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> RegistryInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as RegistryInfo + } +} + +/// An `Ice.OutputStream` extension to write `RegistryInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `RegistryInfo` structured value to the stream. + /// + /// - parameter _: `RegistryInfo` - The value to write to the stream. + func write(_ v: RegistryInfo) { + self.write(v.name) + self.write(v.hostname) + } + + /// Write an optional `RegistryInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `RegistryInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: RegistryInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of RegistryInfo structures. +public typealias RegistryInfoSeq = [RegistryInfo] + +/// Helper class to read and write `RegistryInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct RegistryInfoSeqHelper { + /// Read a `RegistryInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `RegistryInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> RegistryInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 2) + var v = RegistryInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: RegistryInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `RegistryInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `RegistryInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> RegistryInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `RegistryInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `RegistryInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: RegistryInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `RegistryInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `RegistryInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: RegistryInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Information about the load of a node. +public struct LoadInfo { + /// The load average over the past minute. + public var avg1: Swift.Float = 0.0 + /// The load average over the past 5 minutes. + public var avg5: Swift.Float = 0.0 + /// The load average over the past 15 minutes. + public var avg15: Swift.Float = 0.0 + + public init() {} + + public init(avg1: Swift.Float, avg5: Swift.Float, avg15: Swift.Float) { + self.avg1 = avg1 + self.avg5 = avg5 + self.avg15 = avg15 + } +} + +/// An `Ice.InputStream` extension to read `LoadInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `LoadInfo` structured value from the stream. + /// + /// - returns: `LoadInfo` - The structured value read from the stream. + func read() throws -> LoadInfo { + var v = LoadInfo() + v.avg1 = try self.read() + v.avg5 = try self.read() + v.avg15 = try self.read() + return v + } + + /// Read an optional `LoadInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LoadInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> LoadInfo? { + guard try readOptional(tag: tag, expectedFormat: .VSize) else { + return nil + } + try skipSize() + return try read() as LoadInfo + } +} + +/// An `Ice.OutputStream` extension to write `LoadInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `LoadInfo` structured value to the stream. + /// + /// - parameter _: `LoadInfo` - The value to write to the stream. + func write(_ v: LoadInfo) { + self.write(v.avg1) + self.write(v.avg5) + self.write(v.avg15) + } + + /// Write an optional `LoadInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LoadInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: LoadInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .VSize) { + write(size: 12) + write(v) + } + } + } +} + +/// Information about an IceGrid application. +public class ApplicationInfo { + /// Unique application identifier. + public var uuid: Swift.String = "" + /// The creation time. + public var createTime: Swift.Int64 = 0 + /// The user who created the application. + public var createUser: Swift.String = "" + /// The update time. + public var updateTime: Swift.Int64 = 0 + /// The user who updated the application. + public var updateUser: Swift.String = "" + /// The application revision number. + public var revision: Swift.Int32 = 0 + /// The application descriptor + public var descriptor: ApplicationDescriptor = ApplicationDescriptor() + + public init() {} + + public init(uuid: Swift.String, createTime: Swift.Int64, createUser: Swift.String, updateTime: Swift.Int64, updateUser: Swift.String, revision: Swift.Int32, descriptor: ApplicationDescriptor) { + self.uuid = uuid + self.createTime = createTime + self.createUser = createUser + self.updateTime = updateTime + self.updateUser = updateUser + self.revision = revision + self.descriptor = descriptor + } +} + +/// An `Ice.InputStream` extension to read `ApplicationInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ApplicationInfo` structured value from the stream. + /// + /// - returns: `ApplicationInfo` - The structured value read from the stream. + func read() throws -> ApplicationInfo { + let v = ApplicationInfo() + v.uuid = try self.read() + v.createTime = try self.read() + v.createUser = try self.read() + v.updateTime = try self.read() + v.updateUser = try self.read() + v.revision = try self.read() + v.descriptor = try self.read() + return v + } + + /// Read an optional `ApplicationInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ApplicationInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ApplicationInfo + } +} + +/// An `Ice.OutputStream` extension to write `ApplicationInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ApplicationInfo` structured value to the stream. + /// + /// - parameter _: `ApplicationInfo` - The value to write to the stream. + func write(_ v: ApplicationInfo) { + self.write(v.uuid) + self.write(v.createTime) + self.write(v.createUser) + self.write(v.updateTime) + self.write(v.updateUser) + self.write(v.revision) + self.write(v.descriptor) + } + + /// Write an optional `ApplicationInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ApplicationInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of ApplicationInfo structures. +public typealias ApplicationInfoSeq = [ApplicationInfo] + +/// Helper class to read and write `ApplicationInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ApplicationInfoSeqHelper { + /// Read a `ApplicationInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ApplicationInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ApplicationInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 33) + var v = ApplicationInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ApplicationInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ApplicationInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ApplicationInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ApplicationInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ApplicationInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ApplicationInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ApplicationInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ApplicationInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Information about updates to an IceGrid application. +public class ApplicationUpdateInfo { + /// The update time. + public var updateTime: Swift.Int64 = 0 + /// The user who updated the application. + public var updateUser: Swift.String = "" + /// The application revision number. + public var revision: Swift.Int32 = 0 + /// The update descriptor. + public var descriptor: ApplicationUpdateDescriptor = ApplicationUpdateDescriptor() + + public init() {} + + public init(updateTime: Swift.Int64, updateUser: Swift.String, revision: Swift.Int32, descriptor: ApplicationUpdateDescriptor) { + self.updateTime = updateTime + self.updateUser = updateUser + self.revision = revision + self.descriptor = descriptor + } +} + +/// An `Ice.InputStream` extension to read `ApplicationUpdateInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ApplicationUpdateInfo` structured value from the stream. + /// + /// - returns: `ApplicationUpdateInfo` - The structured value read from the stream. + func read() throws -> ApplicationUpdateInfo { + let v = ApplicationUpdateInfo() + v.updateTime = try self.read() + v.updateUser = try self.read() + v.revision = try self.read() + v.descriptor = try self.read() + return v + } + + /// Read an optional `ApplicationUpdateInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationUpdateInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ApplicationUpdateInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ApplicationUpdateInfo + } +} + +/// An `Ice.OutputStream` extension to write `ApplicationUpdateInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ApplicationUpdateInfo` structured value to the stream. + /// + /// - parameter _: `ApplicationUpdateInfo` - The value to write to the stream. + func write(_ v: ApplicationUpdateInfo) { + self.write(v.updateTime) + self.write(v.updateUser) + self.write(v.revision) + self.write(v.descriptor) + } + + /// Write an optional `ApplicationUpdateInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationUpdateInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ApplicationUpdateInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Traits for Slice interface `Admin`. +public struct AdminTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::Admin"] + public static let staticId = "::IceGrid::Admin" +} + +/// Traits for Slice interface `FileIterator`. +public struct FileIteratorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::FileIterator"] + public static let staticId = "::IceGrid::FileIterator" +} + +/// Dynamic information about the state of a server. +public struct ServerDynamicInfo: Swift.Hashable { + /// The id of the server. + public var id: Swift.String = "" + /// The state of the server. + public var state: ServerState = .Inactive + /// The process id of the server. + public var pid: Swift.Int32 = 0 + /// Indicates whether the server is enabled. + public var enabled: Swift.Bool = false + + public init() {} + + public init(id: Swift.String, state: ServerState, pid: Swift.Int32, enabled: Swift.Bool) { + self.id = id + self.state = state + self.pid = pid + self.enabled = enabled + } +} + +/// An `Ice.InputStream` extension to read `ServerDynamicInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ServerDynamicInfo` structured value from the stream. + /// + /// - returns: `ServerDynamicInfo` - The structured value read from the stream. + func read() throws -> ServerDynamicInfo { + var v = ServerDynamicInfo() + v.id = try self.read() + v.state = try self.read() + v.pid = try self.read() + v.enabled = try self.read() + return v + } + + /// Read an optional `ServerDynamicInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerDynamicInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ServerDynamicInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ServerDynamicInfo + } +} + +/// An `Ice.OutputStream` extension to write `ServerDynamicInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ServerDynamicInfo` structured value to the stream. + /// + /// - parameter _: `ServerDynamicInfo` - The value to write to the stream. + func write(_ v: ServerDynamicInfo) { + self.write(v.id) + self.write(v.state) + self.write(v.pid) + self.write(v.enabled) + } + + /// Write an optional `ServerDynamicInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerDynamicInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ServerDynamicInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of server dynamic information structures. +public typealias ServerDynamicInfoSeq = [ServerDynamicInfo] + +/// Helper class to read and write `ServerDynamicInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ServerDynamicInfoSeqHelper { + /// Read a `ServerDynamicInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ServerDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ServerDynamicInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 7) + var v = ServerDynamicInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ServerDynamicInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ServerDynamicInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ServerDynamicInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ServerDynamicInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ServerDynamicInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ServerDynamicInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ServerDynamicInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerDynamicInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ServerDynamicInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Dynamic information about the state of an adapter. +public struct AdapterDynamicInfo { + /// The id of the adapter. + public var id: Swift.String = "" + /// The direct proxy containing the adapter endpoints. + public var proxy: Ice.ObjectPrx? = nil + + public init() {} + + public init(id: Swift.String, proxy: Ice.ObjectPrx?) { + self.id = id + self.proxy = proxy + } +} + +/// An `Ice.InputStream` extension to read `AdapterDynamicInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `AdapterDynamicInfo` structured value from the stream. + /// + /// - returns: `AdapterDynamicInfo` - The structured value read from the stream. + func read() throws -> AdapterDynamicInfo { + var v = AdapterDynamicInfo() + v.id = try self.read() + v.proxy = try self.read(Ice.ObjectPrx.self) + return v + } + + /// Read an optional `AdapterDynamicInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterDynamicInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> AdapterDynamicInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as AdapterDynamicInfo + } +} + +/// An `Ice.OutputStream` extension to write `AdapterDynamicInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `AdapterDynamicInfo` structured value to the stream. + /// + /// - parameter _: `AdapterDynamicInfo` - The value to write to the stream. + func write(_ v: AdapterDynamicInfo) { + self.write(v.id) + self.write(v.proxy) + } + + /// Write an optional `AdapterDynamicInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterDynamicInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: AdapterDynamicInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of adapter dynamic information structures. +public typealias AdapterDynamicInfoSeq = [AdapterDynamicInfo] + +/// Helper class to read and write `AdapterDynamicInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct AdapterDynamicInfoSeqHelper { + /// Read a `AdapterDynamicInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `AdapterDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> AdapterDynamicInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 3) + var v = AdapterDynamicInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: AdapterDynamicInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `AdapterDynamicInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> AdapterDynamicInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `AdapterDynamicInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `AdapterDynamicInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: AdapterDynamicInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `AdapterDynamicInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterDynamicInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: AdapterDynamicInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Dynamic information about the state of a node. +public struct NodeDynamicInfo { + /// Some static information about the node. + public var info: NodeInfo = NodeInfo() + /// The dynamic information of the servers deployed on this node. + public var servers: ServerDynamicInfoSeq = ServerDynamicInfoSeq() + /// The dynamic information of the adapters deployed on this node. + public var adapters: AdapterDynamicInfoSeq = AdapterDynamicInfoSeq() + + public init() {} + + public init(info: NodeInfo, servers: ServerDynamicInfoSeq, adapters: AdapterDynamicInfoSeq) { + self.info = info + self.servers = servers + self.adapters = adapters + } +} + +/// An `Ice.InputStream` extension to read `NodeDynamicInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `NodeDynamicInfo` structured value from the stream. + /// + /// - returns: `NodeDynamicInfo` - The structured value read from the stream. + func read() throws -> NodeDynamicInfo { + var v = NodeDynamicInfo() + v.info = try self.read() + v.servers = try ServerDynamicInfoSeqHelper.read(from: self) + v.adapters = try AdapterDynamicInfoSeqHelper.read(from: self) + return v + } + + /// Read an optional `NodeDynamicInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeDynamicInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> NodeDynamicInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as NodeDynamicInfo + } +} + +/// An `Ice.OutputStream` extension to write `NodeDynamicInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `NodeDynamicInfo` structured value to the stream. + /// + /// - parameter _: `NodeDynamicInfo` - The value to write to the stream. + func write(_ v: NodeDynamicInfo) { + self.write(v.info) + ServerDynamicInfoSeqHelper.write(to: self, value: v.servers) + AdapterDynamicInfoSeqHelper.write(to: self, value: v.adapters) + } + + /// Write an optional `NodeDynamicInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeDynamicInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: NodeDynamicInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Traits for Slice interface `RegistryObserver`. +public struct RegistryObserverTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::RegistryObserver"] + public static let staticId = "::IceGrid::RegistryObserver" +} + +/// A sequence of node dynamic information structures. +public typealias NodeDynamicInfoSeq = [NodeDynamicInfo] + +/// Helper class to read and write `NodeDynamicInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct NodeDynamicInfoSeqHelper { + /// Read a `NodeDynamicInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `NodeDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> NodeDynamicInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 13) + var v = NodeDynamicInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: NodeDynamicInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `NodeDynamicInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeDynamicInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> NodeDynamicInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `NodeDynamicInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `NodeDynamicInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: NodeDynamicInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `NodeDynamicInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeDynamicInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: NodeDynamicInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice interface `NodeObserver`. +public struct NodeObserverTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::NodeObserver"] + public static let staticId = "::IceGrid::NodeObserver" +} + +/// Traits for Slice interface `ApplicationObserver`. +public struct ApplicationObserverTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::ApplicationObserver"] + public static let staticId = "::IceGrid::ApplicationObserver" +} + +/// Traits for Slice interface `AdapterObserver`. +public struct AdapterObserverTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::AdapterObserver"] + public static let staticId = "::IceGrid::AdapterObserver" +} + +/// Traits for Slice interface `ObjectObserver`. +public struct ObjectObserverTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::ObjectObserver"] + public static let staticId = "::IceGrid::ObjectObserver" +} + +/// Traits for Slice interface `AdminSession`. +public struct AdminSessionTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::Session", "::Ice::Object", "::IceGrid::AdminSession"] + public static let staticId = "::IceGrid::AdminSession" +} + +/// The IceGrid administrative interface. +/// Allowing access to this interface +/// is a security risk! Please see the IceGrid documentation +/// for further information. +/// +/// AdminPrx Methods: +/// +/// - addApplication: Add an application to IceGrid. +/// +/// - addApplicationAsync: Add an application to IceGrid. +/// +/// - syncApplication: Synchronize a deployed application with the given application descriptor. +/// +/// - syncApplicationAsync: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplication: Update a deployed application with the given update application descriptor. +/// +/// - updateApplicationAsync: Update a deployed application with the given update application descriptor. +/// +/// - syncApplicationWithoutRestart: Synchronize a deployed application with the given application descriptor. +/// +/// - syncApplicationWithoutRestartAsync: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplicationWithoutRestart: Update a deployed application with the given update application descriptor only if no server restarts are necessary for the update of the application. +/// +/// - updateApplicationWithoutRestartAsync: Update a deployed application with the given update application descriptor only if no server restarts are necessary for the update of the application. +/// +/// - removeApplication: Remove an application from IceGrid. +/// +/// - removeApplicationAsync: Remove an application from IceGrid. +/// +/// - instantiateServer: Instantiate a server template from an application on the given node. +/// +/// - instantiateServerAsync: Instantiate a server template from an application on the given node. +/// +/// - patchApplication: Patch the given application data. +/// +/// - patchApplicationAsync: Patch the given application data. +/// +/// - getApplicationInfo: Get an application descriptor. +/// +/// - getApplicationInfoAsync: Get an application descriptor. +/// +/// - getDefaultApplicationDescriptor: Get the default application descriptor. +/// +/// - getDefaultApplicationDescriptorAsync: Get the default application descriptor. +/// +/// - getAllApplicationNames: Get all the IceGrid applications currently registered. +/// +/// - getAllApplicationNamesAsync: Get all the IceGrid applications currently registered. +/// +/// - getServerInfo: Get the server information for the server with the given id. +/// +/// - getServerInfoAsync: Get the server information for the server with the given id. +/// +/// - getServerState: Get a server's state. +/// +/// - getServerStateAsync: Get a server's state. +/// +/// - getServerPid: Get a server's system process id. +/// +/// - getServerPidAsync: Get a server's system process id. +/// +/// - getServerAdminCategory: Get the category for server admin objects. +/// +/// - getServerAdminCategoryAsync: Get the category for server admin objects. +/// +/// - getServerAdmin: Get a proxy to the server's admin object. +/// +/// - getServerAdminAsync: Get a proxy to the server's admin object. +/// +/// - enableServer: Enable or disable a server. +/// +/// - enableServerAsync: Enable or disable a server. +/// +/// - isServerEnabled: Check if the server is enabled or disabled. +/// +/// - isServerEnabledAsync: Check if the server is enabled or disabled. +/// +/// - startServer: Start a server and wait for its activation. +/// +/// - startServerAsync: Start a server and wait for its activation. +/// +/// - stopServer: Stop a server. +/// +/// - stopServerAsync: Stop a server. +/// +/// - patchServer: Patch a server. +/// +/// - patchServerAsync: Patch a server. +/// +/// - sendSignal: Send signal to a server. +/// +/// - sendSignalAsync: Send signal to a server. +/// +/// - getAllServerIds: Get all the server ids registered with IceGrid. +/// +/// - getAllServerIdsAsync: Get all the server ids registered with IceGrid. +/// +/// - getAdapterInfo: Get the adapter information for the replica group or adapter with the given id. +/// +/// - getAdapterInfoAsync: Get the adapter information for the replica group or adapter with the given id. +/// +/// - removeAdapter: Remove the adapter with the given id. +/// +/// - removeAdapterAsync: Remove the adapter with the given id. +/// +/// - getAllAdapterIds: Get all the adapter ids registered with IceGrid. +/// +/// - getAllAdapterIdsAsync: Get all the adapter ids registered with IceGrid. +/// +/// - addObject: Add an object to the object registry. +/// +/// - addObjectAsync: Add an object to the object registry. +/// +/// - updateObject: Update an object in the object registry. +/// +/// - updateObjectAsync: Update an object in the object registry. +/// +/// - addObjectWithType: Add an object to the object registry and explicitly specify its type. +/// +/// - addObjectWithTypeAsync: Add an object to the object registry and explicitly specify its type. +/// +/// - removeObject: Remove an object from the object registry. +/// +/// - removeObjectAsync: Remove an object from the object registry. +/// +/// - getObjectInfo: Get the object info for the object with the given identity. +/// +/// - getObjectInfoAsync: Get the object info for the object with the given identity. +/// +/// - getObjectInfosByType: Get the object info of all the registered objects with the given type. +/// +/// - getObjectInfosByTypeAsync: Get the object info of all the registered objects with the given type. +/// +/// - getAllObjectInfos: Get the object info of all the registered objects whose stringified identities match the given expression. +/// +/// - getAllObjectInfosAsync: Get the object info of all the registered objects whose stringified identities match the given expression. +/// +/// - pingNode: Ping an IceGrid node to see if it is active. +/// +/// - pingNodeAsync: Ping an IceGrid node to see if it is active. +/// +/// - getNodeLoad: Get the load averages of the node. +/// +/// - getNodeLoadAsync: Get the load averages of the node. +/// +/// - getNodeInfo: Get the node information for the node with the given name. +/// +/// - getNodeInfoAsync: Get the node information for the node with the given name. +/// +/// - getNodeAdmin: Get a proxy to the IceGrid node's admin object. +/// +/// - getNodeAdminAsync: Get a proxy to the IceGrid node's admin object. +/// +/// - getNodeProcessorSocketCount: Get the number of physical processor sockets for the machine running the node with the given name. +/// +/// - getNodeProcessorSocketCountAsync: Get the number of physical processor sockets for the machine running the node with the given name. +/// +/// - shutdownNode: Shutdown an IceGrid node. +/// +/// - shutdownNodeAsync: Shutdown an IceGrid node. +/// +/// - getNodeHostname: Get the hostname of this node. +/// +/// - getNodeHostnameAsync: Get the hostname of this node. +/// +/// - getAllNodeNames: Get all the IceGrid nodes currently registered. +/// +/// - getAllNodeNamesAsync: Get all the IceGrid nodes currently registered. +/// +/// - pingRegistry: Ping an IceGrid registry to see if it is active. +/// +/// - pingRegistryAsync: Ping an IceGrid registry to see if it is active. +/// +/// - getRegistryInfo: Get the registry information for the registry with the given name. +/// +/// - getRegistryInfoAsync: Get the registry information for the registry with the given name. +/// +/// - getRegistryAdmin: Get a proxy to the IceGrid registry's admin object. +/// +/// - getRegistryAdminAsync: Get a proxy to the IceGrid registry's admin object. +/// +/// - shutdownRegistry: Shutdown an IceGrid registry. +/// +/// - shutdownRegistryAsync: Shutdown an IceGrid registry. +/// +/// - getAllRegistryNames: Get all the IceGrid registries currently registered. +/// +/// - getAllRegistryNamesAsync: Get all the IceGrid registries currently registered. +/// +/// - shutdown: Shut down the IceGrid registry. +/// +/// - shutdownAsync: Shut down the IceGrid registry. +/// +/// - getSliceChecksums: Returns the checksums for the IceGrid Slice definitions. +/// +/// - getSliceChecksumsAsync: Returns the checksums for the IceGrid Slice definitions. +public protocol AdminPrx: Ice.ObjectPrx {} + +private final class AdminPrxI: Ice.ObjectPrxI, AdminPrx { + public override class func ice_staticId() -> Swift.String { + return AdminTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `AdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `AdminPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: AdminPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> AdminPrx? { + return try AdminPrxI.checkedCast(prx: prx, facet: facet, context: context) as AdminPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `AdminPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `AdminPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: AdminPrx.Protocol, facet: Swift.String? = nil) -> AdminPrx { + return AdminPrxI.uncheckedCast(prx: prx, facet: facet) as AdminPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `AdminPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: AdminPrx.Protocol) -> Swift.String { + return AdminTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `AdminPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `AdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdminPrx?` - The extracted proxy + func read(_ type: AdminPrx.Protocol) throws -> AdminPrx? { + return try read() as AdminPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `AdminPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdminPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: AdminPrx.Protocol) throws -> AdminPrx? { + return try read(tag: tag) as AdminPrxI? + } +} + +/// The IceGrid administrative interface. +/// Allowing access to this interface +/// is a security risk! Please see the IceGrid documentation +/// for further information. +/// +/// AdminPrx Methods: +/// +/// - addApplication: Add an application to IceGrid. +/// +/// - addApplicationAsync: Add an application to IceGrid. +/// +/// - syncApplication: Synchronize a deployed application with the given application descriptor. +/// +/// - syncApplicationAsync: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplication: Update a deployed application with the given update application descriptor. +/// +/// - updateApplicationAsync: Update a deployed application with the given update application descriptor. +/// +/// - syncApplicationWithoutRestart: Synchronize a deployed application with the given application descriptor. +/// +/// - syncApplicationWithoutRestartAsync: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplicationWithoutRestart: Update a deployed application with the given update application descriptor only if no server restarts are necessary for the update of the application. +/// +/// - updateApplicationWithoutRestartAsync: Update a deployed application with the given update application descriptor only if no server restarts are necessary for the update of the application. +/// +/// - removeApplication: Remove an application from IceGrid. +/// +/// - removeApplicationAsync: Remove an application from IceGrid. +/// +/// - instantiateServer: Instantiate a server template from an application on the given node. +/// +/// - instantiateServerAsync: Instantiate a server template from an application on the given node. +/// +/// - patchApplication: Patch the given application data. +/// +/// - patchApplicationAsync: Patch the given application data. +/// +/// - getApplicationInfo: Get an application descriptor. +/// +/// - getApplicationInfoAsync: Get an application descriptor. +/// +/// - getDefaultApplicationDescriptor: Get the default application descriptor. +/// +/// - getDefaultApplicationDescriptorAsync: Get the default application descriptor. +/// +/// - getAllApplicationNames: Get all the IceGrid applications currently registered. +/// +/// - getAllApplicationNamesAsync: Get all the IceGrid applications currently registered. +/// +/// - getServerInfo: Get the server information for the server with the given id. +/// +/// - getServerInfoAsync: Get the server information for the server with the given id. +/// +/// - getServerState: Get a server's state. +/// +/// - getServerStateAsync: Get a server's state. +/// +/// - getServerPid: Get a server's system process id. +/// +/// - getServerPidAsync: Get a server's system process id. +/// +/// - getServerAdminCategory: Get the category for server admin objects. +/// +/// - getServerAdminCategoryAsync: Get the category for server admin objects. +/// +/// - getServerAdmin: Get a proxy to the server's admin object. +/// +/// - getServerAdminAsync: Get a proxy to the server's admin object. +/// +/// - enableServer: Enable or disable a server. +/// +/// - enableServerAsync: Enable or disable a server. +/// +/// - isServerEnabled: Check if the server is enabled or disabled. +/// +/// - isServerEnabledAsync: Check if the server is enabled or disabled. +/// +/// - startServer: Start a server and wait for its activation. +/// +/// - startServerAsync: Start a server and wait for its activation. +/// +/// - stopServer: Stop a server. +/// +/// - stopServerAsync: Stop a server. +/// +/// - patchServer: Patch a server. +/// +/// - patchServerAsync: Patch a server. +/// +/// - sendSignal: Send signal to a server. +/// +/// - sendSignalAsync: Send signal to a server. +/// +/// - getAllServerIds: Get all the server ids registered with IceGrid. +/// +/// - getAllServerIdsAsync: Get all the server ids registered with IceGrid. +/// +/// - getAdapterInfo: Get the adapter information for the replica group or adapter with the given id. +/// +/// - getAdapterInfoAsync: Get the adapter information for the replica group or adapter with the given id. +/// +/// - removeAdapter: Remove the adapter with the given id. +/// +/// - removeAdapterAsync: Remove the adapter with the given id. +/// +/// - getAllAdapterIds: Get all the adapter ids registered with IceGrid. +/// +/// - getAllAdapterIdsAsync: Get all the adapter ids registered with IceGrid. +/// +/// - addObject: Add an object to the object registry. +/// +/// - addObjectAsync: Add an object to the object registry. +/// +/// - updateObject: Update an object in the object registry. +/// +/// - updateObjectAsync: Update an object in the object registry. +/// +/// - addObjectWithType: Add an object to the object registry and explicitly specify its type. +/// +/// - addObjectWithTypeAsync: Add an object to the object registry and explicitly specify its type. +/// +/// - removeObject: Remove an object from the object registry. +/// +/// - removeObjectAsync: Remove an object from the object registry. +/// +/// - getObjectInfo: Get the object info for the object with the given identity. +/// +/// - getObjectInfoAsync: Get the object info for the object with the given identity. +/// +/// - getObjectInfosByType: Get the object info of all the registered objects with the given type. +/// +/// - getObjectInfosByTypeAsync: Get the object info of all the registered objects with the given type. +/// +/// - getAllObjectInfos: Get the object info of all the registered objects whose stringified identities match the given expression. +/// +/// - getAllObjectInfosAsync: Get the object info of all the registered objects whose stringified identities match the given expression. +/// +/// - pingNode: Ping an IceGrid node to see if it is active. +/// +/// - pingNodeAsync: Ping an IceGrid node to see if it is active. +/// +/// - getNodeLoad: Get the load averages of the node. +/// +/// - getNodeLoadAsync: Get the load averages of the node. +/// +/// - getNodeInfo: Get the node information for the node with the given name. +/// +/// - getNodeInfoAsync: Get the node information for the node with the given name. +/// +/// - getNodeAdmin: Get a proxy to the IceGrid node's admin object. +/// +/// - getNodeAdminAsync: Get a proxy to the IceGrid node's admin object. +/// +/// - getNodeProcessorSocketCount: Get the number of physical processor sockets for the machine running the node with the given name. +/// +/// - getNodeProcessorSocketCountAsync: Get the number of physical processor sockets for the machine running the node with the given name. +/// +/// - shutdownNode: Shutdown an IceGrid node. +/// +/// - shutdownNodeAsync: Shutdown an IceGrid node. +/// +/// - getNodeHostname: Get the hostname of this node. +/// +/// - getNodeHostnameAsync: Get the hostname of this node. +/// +/// - getAllNodeNames: Get all the IceGrid nodes currently registered. +/// +/// - getAllNodeNamesAsync: Get all the IceGrid nodes currently registered. +/// +/// - pingRegistry: Ping an IceGrid registry to see if it is active. +/// +/// - pingRegistryAsync: Ping an IceGrid registry to see if it is active. +/// +/// - getRegistryInfo: Get the registry information for the registry with the given name. +/// +/// - getRegistryInfoAsync: Get the registry information for the registry with the given name. +/// +/// - getRegistryAdmin: Get a proxy to the IceGrid registry's admin object. +/// +/// - getRegistryAdminAsync: Get a proxy to the IceGrid registry's admin object. +/// +/// - shutdownRegistry: Shutdown an IceGrid registry. +/// +/// - shutdownRegistryAsync: Shutdown an IceGrid registry. +/// +/// - getAllRegistryNames: Get all the IceGrid registries currently registered. +/// +/// - getAllRegistryNamesAsync: Get all the IceGrid registries currently registered. +/// +/// - shutdown: Shut down the IceGrid registry. +/// +/// - shutdownAsync: Shut down the IceGrid registry. +/// +/// - getSliceChecksums: Returns the checksums for the IceGrid Slice definitions. +/// +/// - getSliceChecksumsAsync: Returns the checksums for the IceGrid Slice definitions. +public extension AdminPrx { + /// Add an application to IceGrid. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func addApplication(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "addApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Add an application to IceGrid. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func addApplicationAsync(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "addApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func syncApplication(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "syncApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func syncApplicationAsync(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "syncApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Update a deployed application with the given update application + /// descriptor. + /// + /// - parameter _: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func updateApplication(_ iceP_descriptor: ApplicationUpdateDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "updateApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Update a deployed application with the given update application + /// descriptor. + /// + /// - parameter _: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func updateApplicationAsync(_ iceP_descriptor: ApplicationUpdateDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "updateApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor only if no server restarts are + /// necessary for the update of the application. If some servers + /// need to be restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func syncApplicationWithoutRestart(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "syncApplicationWithoutRestart", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor only if no server restarts are + /// necessary for the update of the application. If some servers + /// need to be restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter _: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func syncApplicationWithoutRestartAsync(_ iceP_descriptor: ApplicationDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "syncApplicationWithoutRestart", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Update a deployed application with the given update application + /// descriptor only if no server restarts are necessary for the + /// update of the application. If some servers need to be + /// restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter _: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func updateApplicationWithoutRestart(_ iceP_descriptor: ApplicationUpdateDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "updateApplicationWithoutRestart", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Update a deployed application with the given update application + /// descriptor only if no server restarts are necessary for the + /// update of the application. If some servers need to be + /// restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter _: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func updateApplicationWithoutRestartAsync(_ iceP_descriptor: ApplicationUpdateDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "updateApplicationWithoutRestart", + mode: .Normal, + write: { ostr in + ostr.write(iceP_descriptor) + ostr.writePendingValues() + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Remove an application from IceGrid. + /// + /// - parameter _: `Swift.String` The application name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment failed. + func removeApplication(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "removeApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Remove an application from IceGrid. + /// + /// - parameter _: `Swift.String` The application name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func removeApplicationAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "removeApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Instantiate a server template from an application on the given + /// node. + /// + /// - parameter application: `Swift.String` The application name. + /// + /// - parameter node: `Swift.String` The name of the node where the server will be + /// deployed. + /// + /// - parameter desc: `ServerInstanceDescriptor` The descriptor of the server instance to deploy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if server instantiation + /// failed. + func instantiateServer(application iceP_application: Swift.String, node iceP_node: Swift.String, desc iceP_desc: ServerInstanceDescriptor, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "instantiateServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_application) + ostr.write(iceP_node) + ostr.write(iceP_desc) + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Instantiate a server template from an application on the given + /// node. + /// + /// - parameter application: `Swift.String` The application name. + /// + /// - parameter node: `Swift.String` The name of the node where the server will be + /// deployed. + /// + /// - parameter desc: `ServerInstanceDescriptor` The descriptor of the server instance to deploy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func instantiateServerAsync(application iceP_application: Swift.String, node iceP_node: Swift.String, desc iceP_desc: ServerInstanceDescriptor, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "instantiateServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_application) + ostr.write(iceP_node) + ostr.write(iceP_desc) + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch let error as ApplicationNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Patch the given application data. + /// + /// - parameter name: `Swift.String` The application name. + /// + /// - parameter shutdown: `Swift.Bool` If true, the servers depending on the data to + /// patch will be shut down if necessary. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - PatchException - Raised if the patch failed. + func patchApplication(name iceP_name: Swift.String, shutdown iceP_shutdown: Swift.Bool, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "patchApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_shutdown) + }, + userException:{ ex in + do { + throw ex + } catch let error as ApplicationNotExistException { + throw error + } catch let error as PatchException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Patch the given application data. + /// + /// - parameter name: `Swift.String` The application name. + /// + /// - parameter shutdown: `Swift.Bool` If true, the servers depending on the data to + /// patch will be shut down if necessary. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func patchApplicationAsync(name iceP_name: Swift.String, shutdown iceP_shutdown: Swift.Bool, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "patchApplication", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_shutdown) + }, + userException:{ ex in + do { + throw ex + } catch let error as ApplicationNotExistException { + throw error + } catch let error as PatchException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get an application descriptor. + /// + /// - parameter _: `Swift.String` The application name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ApplicationInfo` - The application descriptor. + /// + /// - throws: + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + func getApplicationInfo(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> ApplicationInfo { + return try _impl._invoke(operation: "getApplicationInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: ApplicationInfo = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ApplicationNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get an application descriptor. + /// + /// - parameter _: `Swift.String` The application name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getApplicationInfoAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getApplicationInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: ApplicationInfo = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ApplicationNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the default application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ApplicationDescriptor` - The default application descriptor. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the default application + /// descriptor can't be accessed or is invalid. + func getDefaultApplicationDescriptor(context: Ice.Context? = nil) throws -> ApplicationDescriptor { + return try _impl._invoke(operation: "getDefaultApplicationDescriptor", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the default application descriptor. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getDefaultApplicationDescriptorAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getDefaultApplicationDescriptor", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all the IceGrid applications currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The application names. + func getAllApplicationNames(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "getAllApplicationNames", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get all the IceGrid applications currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllApplicationNamesAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllApplicationNames", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the server information for the server with the given id. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ServerInfo` - The server information. + /// + /// - throws: + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerInfo(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> ServerInfo { + return try _impl._invoke(operation: "getServerInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ServerInfo = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the server information for the server with the given id. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerInfoAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ServerInfo = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a server's state. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ServerState` - The server state. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerState(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> ServerState { + return try _impl._invoke(operation: "getServerState", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ServerState = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get a server's state. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerStateAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerState", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ServerState = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a server's system process id. The process id is operating + /// system dependent. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The server's process id. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerPid(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getServerPid", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get a server's system process id. The process id is operating + /// system dependent. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerPidAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerPid", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the category for server admin objects. You can manufacture a server admin + /// proxy from the admin proxy by changing its identity: use the server ID as name + /// and the returned category as category. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The category for server admin objects. + func getServerAdminCategory(context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getServerAdminCategory", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the category for server admin objects. You can manufacture a server admin + /// proxy from the admin proxy by changing its identity: use the server ID as name + /// and the returned category as category. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerAdminCategoryAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerAdminCategory", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a proxy to the server's admin object. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the server's admin object + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerAdmin(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getServerAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get a proxy to the server's admin object. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getServerAdminAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getServerAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Enable or disable a server. A disabled server can't be started + /// on demand or administratively. The enable state of the server + /// is not persistent: if the node is shut down and restarted, the + /// server will be enabled by default. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter enabled: `Swift.Bool` True to enable the server, false to disable it. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func enableServer(id iceP_id: Swift.String, enabled iceP_enabled: Swift.Bool, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "enableServer", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_enabled) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Enable or disable a server. A disabled server can't be started + /// on demand or administratively. The enable state of the server + /// is not persistent: if the node is shut down and restarted, the + /// server will be enabled by default. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter enabled: `Swift.Bool` True to enable the server, false to disable it. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func enableServerAsync(id iceP_id: Swift.String, enabled iceP_enabled: Swift.Bool, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "enableServer", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_enabled) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Check if the server is enabled or disabled. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Bool` - True if the server is enabled. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func isServerEnabled(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> Swift.Bool { + return try _impl._invoke(operation: "isServerEnabled", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Check if the server is enabled or disabled. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func isServerEnabledAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "isServerEnabled", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Start a server and wait for its activation. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + /// + /// - ServerStartException - Raised if the server couldn't be + /// started. + func startServer(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "startServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch let error as ServerStartException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Start a server and wait for its activation. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func startServerAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "startServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch let error as ServerStartException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Stop a server. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + /// + /// - ServerStopException - Raised if the server couldn't be + /// stopped. + func stopServer(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "stopServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch let error as ServerStopException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Stop a server. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func stopServerAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "stopServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch let error as ServerStopException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Patch a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter shutdown: `Swift.Bool` If true, servers depending on the data to patch + /// will be shut down if necessary. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - PatchException - Raised if the patch failed. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func patchServer(id iceP_id: Swift.String, shutdown iceP_shutdown: Swift.Bool, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "patchServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_shutdown) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as PatchException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Patch a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter shutdown: `Swift.Bool` If true, servers depending on the data to patch + /// will be shut down if necessary. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func patchServerAsync(id iceP_id: Swift.String, shutdown iceP_shutdown: Swift.Bool, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "patchServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_shutdown) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as PatchException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Send signal to a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter signal: `Swift.String` The signal, for example SIGTERM or 15. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - BadSignalException - Raised if the signal is not recognized + /// by the target server. + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func sendSignal(id iceP_id: Swift.String, signal iceP_signal: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "sendSignal", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_signal) + }, + userException:{ ex in + do { + throw ex + } catch let error as BadSignalException { + throw error + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Send signal to a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter signal: `Swift.String` The signal, for example SIGTERM or 15. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func sendSignalAsync(id iceP_id: Swift.String, signal iceP_signal: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "sendSignal", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_signal) + }, + userException:{ ex in + do { + throw ex + } catch let error as BadSignalException { + throw error + } catch let error as DeploymentException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all the server ids registered with IceGrid. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The server ids. + func getAllServerIds(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "getAllServerIds", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get all the server ids registered with IceGrid. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllServerIdsAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllServerIds", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the adapter information for the replica group or adapter + /// with the given id. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `AdapterInfoSeq` - A sequence of adapter information structures. If the + /// given id refers to an adapter, this sequence will contain only + /// one element. If the given id refers to a replica group, the + /// sequence will contain the adapter information of each member of + /// the replica group. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter or + /// replica group doesn't exist. + func getAdapterInfo(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws -> AdapterInfoSeq { + return try _impl._invoke(operation: "getAdapterInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: AdapterInfoSeq = try AdapterInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the adapter information for the replica group or adapter + /// with the given id. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAdapterInfoAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAdapterInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: AdapterInfoSeq = try AdapterInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Remove the adapter with the given id. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't + /// exist. + /// + /// - DeploymentException - Raised if application deployment failed. + func removeAdapter(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "removeAdapter", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Remove the adapter with the given id. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func removeAdapterAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "removeAdapter", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as AdapterNotExistException { + throw error + } catch let error as DeploymentException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all the adapter ids registered with IceGrid. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The adapter ids. + func getAllAdapterIds(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "getAllAdapterIds", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get all the adapter ids registered with IceGrid. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllAdapterIdsAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllAdapterIds", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Add an object to the object registry. IceGrid will get the + /// object type by calling ice_id on the given proxy. The object + /// must be reachable. + /// + /// - parameter _: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// added. This might be raised if the invocation on the proxy to + /// get the object type failed. + /// + /// - ObjectExistsException - Raised if the object is already + /// registered. + func addObject(_ iceP_obj: Ice.ObjectPrx?, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "addObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectExistsException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Add an object to the object registry. IceGrid will get the + /// object type by calling ice_id on the given proxy. The object + /// must be reachable. + /// + /// - parameter _: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func addObjectAsync(_ iceP_obj: Ice.ObjectPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "addObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectExistsException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Update an object in the object registry. Only objects added + /// with this interface can be updated with this operation. Objects + /// added with deployment descriptors should be updated with the + /// deployment mechanism. + /// + /// - parameter _: `Ice.ObjectPrx?` The object to be updated to the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// updated. This might happen if the object was added with a + /// deployment descriptor. + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func updateObject(_ iceP_obj: Ice.ObjectPrx?, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "updateObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Update an object in the object registry. Only objects added + /// with this interface can be updated with this operation. Objects + /// added with deployment descriptors should be updated with the + /// deployment mechanism. + /// + /// - parameter _: `Ice.ObjectPrx?` The object to be updated to the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func updateObjectAsync(_ iceP_obj: Ice.ObjectPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "updateObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Add an object to the object registry and explicitly specify + /// its type. + /// + /// - parameter obj: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if application deployment failed. + /// + /// - ObjectExistsException - Raised if the object is already + /// registered. + func addObjectWithType(obj iceP_obj: Ice.ObjectPrx?, type iceP_type: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "addObjectWithType", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + ostr.write(iceP_type) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectExistsException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Add an object to the object registry and explicitly specify + /// its type. + /// + /// - parameter obj: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func addObjectWithTypeAsync(obj iceP_obj: Ice.ObjectPrx?, type iceP_type: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "addObjectWithType", + mode: .Normal, + write: { ostr in + ostr.write(iceP_obj) + ostr.write(iceP_type) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectExistsException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Remove an object from the object registry. Only objects added + /// with this interface can be removed with this operation. Objects + /// added with deployment descriptors should be removed with the + /// deployment mechanism. + /// + /// - parameter _: `Ice.Identity` The identity of the object to be removed from the + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// removed. This might happen if the object was added with a + /// deployment descriptor. + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func removeObject(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "removeObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Remove an object from the object registry. Only objects added + /// with this interface can be removed with this operation. Objects + /// added with deployment descriptors should be removed with the + /// deployment mechanism. + /// + /// - parameter _: `Ice.Identity` The identity of the object to be removed from the + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func removeObjectAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "removeObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the object info for the object with the given identity. + /// + /// - parameter _: `Ice.Identity` The identity of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectInfo` - The object info. + /// + /// - throws: + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func getObjectInfo(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws -> ObjectInfo { + return try _impl._invoke(operation: "getObjectInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the object info for the object with the given identity. + /// + /// - parameter _: `Ice.Identity` The identity of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getObjectInfoAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getObjectInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: ObjectInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the object info of all the registered objects with the + /// given type. + /// + /// - parameter _: `Swift.String` The type of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectInfoSeq` - The object infos. + func getObjectInfosByType(_ iceP_type: Swift.String, context: Ice.Context? = nil) throws -> ObjectInfoSeq { + return try _impl._invoke(operation: "getObjectInfosByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: ObjectInfoSeq = try ObjectInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Get the object info of all the registered objects with the + /// given type. + /// + /// - parameter _: `Swift.String` The type of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getObjectInfosByTypeAsync(_ iceP_type: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getObjectInfosByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: ObjectInfoSeq = try ObjectInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the object info of all the registered objects whose stringified + /// identities match the given expression. + /// + /// - parameter _: `Swift.String` The expression to match against the stringified + /// identities of registered objects. The expression may contain + /// a trailing wildcard (*) character. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ObjectInfoSeq` - All the object infos with a stringified identity + /// matching the given expression. + func getAllObjectInfos(_ iceP_expr: Swift.String, context: Ice.Context? = nil) throws -> ObjectInfoSeq { + return try _impl._invoke(operation: "getAllObjectInfos", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_expr) + }, + read: { istr in + let iceP_returnValue: ObjectInfoSeq = try ObjectInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Get the object info of all the registered objects whose stringified + /// identities match the given expression. + /// + /// - parameter _: `Swift.String` The expression to match against the stringified + /// identities of registered objects. The expression may contain + /// a trailing wildcard (*) character. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllObjectInfosAsync(_ iceP_expr: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllObjectInfos", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_expr) + }, + read: { istr in + let iceP_returnValue: ObjectInfoSeq = try ObjectInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Ping an IceGrid node to see if it is active. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Bool` - true if the node ping succeeded, false otherwise. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + func pingNode(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Swift.Bool { + return try _impl._invoke(operation: "pingNode", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Ping an IceGrid node to see if it is active. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func pingNodeAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "pingNode", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the load averages of the node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `LoadInfo` - The node load information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeLoad(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> LoadInfo { + return try _impl._invoke(operation: "getNodeLoad", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: LoadInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the load averages of the node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNodeLoadAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNodeLoad", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: LoadInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the node information for the node with the given name. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `NodeInfo` - The node information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeInfo(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> NodeInfo { + return try _impl._invoke(operation: "getNodeInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: NodeInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the node information for the node with the given name. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNodeInfoAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNodeInfo", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: NodeInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a proxy to the IceGrid node's admin object. + /// + /// - parameter _: `Swift.String` The IceGrid node name + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the IceGrid node's admin object + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeAdmin(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getNodeAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get a proxy to the IceGrid node's admin object. + /// + /// - parameter _: `Swift.String` The IceGrid node name + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNodeAdminAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNodeAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the number of physical processor sockets for the machine + /// running the node with the given name. + /// + /// Note that this method will return 1 on operating systems where + /// this can't be automatically determined and where the + /// IceGrid.Node.ProcessorSocketCount property for the node is not + /// set. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The number of processor sockets or 1 if the number of + /// sockets can't determined. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeProcessorSocketCount(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getNodeProcessorSocketCount", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the number of physical processor sockets for the machine + /// running the node with the given name. + /// + /// Note that this method will return 1 on operating systems where + /// this can't be automatically determined and where the + /// IceGrid.Node.ProcessorSocketCount property for the node is not + /// set. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNodeProcessorSocketCountAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNodeProcessorSocketCount", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Shutdown an IceGrid node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func shutdownNode(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "shutdownNode", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Shutdown an IceGrid node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func shutdownNodeAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "shutdownNode", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the hostname of this node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The node hostname. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeHostname(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getNodeHostname", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the hostname of this node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNodeHostnameAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNodeHostname", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all the IceGrid nodes currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The node names. + func getAllNodeNames(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "getAllNodeNames", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get all the IceGrid nodes currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllNodeNamesAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllNodeNames", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Ping an IceGrid registry to see if it is active. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Bool` - true if the registry ping succeeded, false otherwise. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + func pingRegistry(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Swift.Bool { + return try _impl._invoke(operation: "pingRegistry", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Ping an IceGrid registry to see if it is active. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func pingRegistryAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "pingRegistry", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Swift.Bool = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the registry information for the registry with the given name. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `RegistryInfo` - The registry information. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry could not be + /// reached. + func getRegistryInfo(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> RegistryInfo { + return try _impl._invoke(operation: "getRegistryInfo", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: RegistryInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the registry information for the registry with the given name. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getRegistryInfoAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getRegistryInfo", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: RegistryInfo = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a proxy to the IceGrid registry's admin object. + /// + /// - parameter _: `Swift.String` The registry name + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the IceGrid registry's admin object + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + func getRegistryAdmin(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getRegistryAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get a proxy to the IceGrid registry's admin object. + /// + /// - parameter _: `Swift.String` The registry name + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getRegistryAdminAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getRegistryAdmin", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Shutdown an IceGrid registry. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry could not be + /// reached. + func shutdownRegistry(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "shutdownRegistry", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Shutdown an IceGrid registry. + /// + /// - parameter _: `Swift.String` The registry name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func shutdownRegistryAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "shutdownRegistry", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_name) + }, + userException:{ ex in + do { + throw ex + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get all the IceGrid registries currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.StringSeq` - The registry names. + func getAllRegistryNames(context: Ice.Context? = nil) throws -> Ice.StringSeq { + return try _impl._invoke(operation: "getAllRegistryNames", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get all the IceGrid registries currently registered. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAllRegistryNamesAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAllRegistryNames", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.StringSeq = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Shut down the IceGrid registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func shutdown(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "shutdown", + mode: .Normal, + context: context) + } + + /// Shut down the IceGrid registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func shutdownAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "shutdown", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns the checksums for the IceGrid Slice definitions. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.SliceChecksumDict` - A dictionary mapping Slice type ids to their checksums. + func getSliceChecksums(context: Ice.Context? = nil) throws -> Ice.SliceChecksumDict { + return try _impl._invoke(operation: "getSliceChecksums", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.SliceChecksumDict = try Ice.SliceChecksumDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Returns the checksums for the IceGrid Slice definitions. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSliceChecksumsAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSliceChecksums", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.SliceChecksumDict = try Ice.SliceChecksumDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This interface provides access to IceGrid log file contents. +/// +/// FileIteratorPrx Methods: +/// +/// - read: Read lines from the log file. +/// +/// - readAsync: Read lines from the log file. +/// +/// - destroy: Destroy the iterator. +/// +/// - destroyAsync: Destroy the iterator. +public protocol FileIteratorPrx: Ice.ObjectPrx {} + +private final class FileIteratorPrxI: Ice.ObjectPrxI, FileIteratorPrx { + public override class func ice_staticId() -> Swift.String { + return FileIteratorTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `FileIteratorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `FileIteratorPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: FileIteratorPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try FileIteratorPrxI.checkedCast(prx: prx, facet: facet, context: context) as FileIteratorPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `FileIteratorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `FileIteratorPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: FileIteratorPrx.Protocol, facet: Swift.String? = nil) -> FileIteratorPrx { + return FileIteratorPrxI.uncheckedCast(prx: prx, facet: facet) as FileIteratorPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `FileIteratorPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: FileIteratorPrx.Protocol) -> Swift.String { + return FileIteratorTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `FileIteratorPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `FileIteratorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FileIteratorPrx?` - The extracted proxy + func read(_ type: FileIteratorPrx.Protocol) throws -> FileIteratorPrx? { + return try read() as FileIteratorPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `FileIteratorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FileIteratorPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: FileIteratorPrx.Protocol) throws -> FileIteratorPrx? { + return try read(tag: tag) as FileIteratorPrxI? + } +} + +/// This interface provides access to IceGrid log file contents. +/// +/// FileIteratorPrx Methods: +/// +/// - read: Read lines from the log file. +/// +/// - readAsync: Read lines from the log file. +/// +/// - destroy: Destroy the iterator. +/// +/// - destroyAsync: Destroy the iterator. +public extension FileIteratorPrx { + /// Read lines from the log file. + /// + /// - parameter _: `Swift.Int32` Specifies the maximum number of bytes to be + /// received. The server will ensure that the returned message + /// doesn't exceed the given size. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `(returnValue: Swift.Bool, lines: Ice.StringSeq)`: + /// + /// - returnValue: `Swift.Bool` - True if EOF is encountered. + /// + /// - lines: `Ice.StringSeq` - The lines read from the file. If there was nothing to + /// read from the file since the last call to read, an empty + /// sequence is returned. The last line of the sequence is always + /// incomplete (and therefore no '\n' should be added when writing + /// the last line to the to the output device). + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if there was a problem + /// to read lines from the file. + func read(_ iceP_size: Swift.Int32, context: Ice.Context? = nil) throws -> (returnValue: Swift.Bool, lines: Ice.StringSeq) { + return try _impl._invoke(operation: "read", + mode: .Normal, + write: { ostr in + ostr.write(iceP_size) + }, + read: { istr in + let iceP_lines: Ice.StringSeq = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_lines) + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Read lines from the log file. + /// + /// - parameter _: `Swift.Int32` Specifies the maximum number of bytes to be + /// received. The server will ensure that the returned message + /// doesn't exceed the given size. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<(returnValue: Swift.Bool, lines: Ice.StringSeq)>` - The result of the operation + func readAsync(_ iceP_size: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise<(returnValue: Swift.Bool, lines: Ice.StringSeq)> { + return _impl._invokeAsync(operation: "read", + mode: .Normal, + write: { ostr in + ostr.write(iceP_size) + }, + read: { istr in + let iceP_lines: Ice.StringSeq = try istr.read() + let iceP_returnValue: Swift.Bool = try istr.read() + return (iceP_returnValue, iceP_lines) + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Destroy the iterator. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func destroy(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "destroy", + mode: .Normal, + context: context) + } + + /// Destroy the iterator. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func destroyAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "destroy", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This interface allows applications to monitor changes the state +/// of the registry. +/// +/// RegistryObserverPrx Methods: +/// +/// - registryInit: The registryInit operation is called after registration of an observer to indicate the state of the registries. +/// +/// - registryInitAsync: The registryInit operation is called after registration of an observer to indicate the state of the registries. +/// +/// - registryUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - registryUpAsync: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - registryDown: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - registryDownAsync: The nodeDown operation is called to notify an observer that a node went down. +public protocol RegistryObserverPrx: Ice.ObjectPrx {} + +private final class RegistryObserverPrxI: Ice.ObjectPrxI, RegistryObserverPrx { + public override class func ice_staticId() -> Swift.String { + return RegistryObserverTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RegistryObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RegistryObserverPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: RegistryObserverPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> RegistryObserverPrx? { + return try RegistryObserverPrxI.checkedCast(prx: prx, facet: facet, context: context) as RegistryObserverPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RegistryObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RegistryObserverPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: RegistryObserverPrx.Protocol, facet: Swift.String? = nil) -> RegistryObserverPrx { + return RegistryObserverPrxI.uncheckedCast(prx: prx, facet: facet) as RegistryObserverPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RegistryObserverPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RegistryObserverPrx.Protocol) -> Swift.String { + return RegistryObserverTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RegistryObserverPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RegistryObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RegistryObserverPrx?` - The extracted proxy + func read(_ type: RegistryObserverPrx.Protocol) throws -> RegistryObserverPrx? { + return try read() as RegistryObserverPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RegistryObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RegistryObserverPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RegistryObserverPrx.Protocol) throws -> RegistryObserverPrx? { + return try read(tag: tag) as RegistryObserverPrxI? + } +} + +/// This interface allows applications to monitor changes the state +/// of the registry. +/// +/// RegistryObserverPrx Methods: +/// +/// - registryInit: The registryInit operation is called after registration of an observer to indicate the state of the registries. +/// +/// - registryInitAsync: The registryInit operation is called after registration of an observer to indicate the state of the registries. +/// +/// - registryUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - registryUpAsync: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - registryDown: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - registryDownAsync: The nodeDown operation is called to notify an observer that a node went down. +public extension RegistryObserverPrx { + /// The registryInit operation is called after registration of + /// an observer to indicate the state of the registries. + /// + /// - parameter _: `RegistryInfoSeq` The current state of the registries. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func registryInit(_ iceP_registries: RegistryInfoSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "registryInit", + mode: .Normal, + write: { ostr in + RegistryInfoSeqHelper.write(to: ostr, value: iceP_registries) + }, + context: context) + } + + /// The registryInit operation is called after registration of + /// an observer to indicate the state of the registries. + /// + /// - parameter _: `RegistryInfoSeq` The current state of the registries. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func registryInitAsync(_ iceP_registries: RegistryInfoSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "registryInit", + mode: .Normal, + write: { ostr in + RegistryInfoSeqHelper.write(to: ostr, value: iceP_registries) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter _: `RegistryInfo` The node state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func registryUp(_ iceP_node: RegistryInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "registryUp", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + }, + context: context) + } + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter _: `RegistryInfo` The node state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func registryUpAsync(_ iceP_node: RegistryInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "registryUp", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func registryDown(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "registryDown", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + context: context) + } + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func registryDownAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "registryDown", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The node observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// nodes. +/// +/// NodeObserverPrx Methods: +/// +/// - nodeInit: The nodeInit operation indicates the current state of nodes. +/// +/// - nodeInitAsync: The nodeInit operation indicates the current state of nodes. +/// +/// - nodeUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - nodeUpAsync: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - nodeDown: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - nodeDownAsync: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - updateServer: The updateServer operation is called to notify an observer that the state of a server changed. +/// +/// - updateServerAsync: The updateServer operation is called to notify an observer that the state of a server changed. +/// +/// - updateAdapter: The updateAdapter operation is called to notify an observer that the state of an adapter changed. +/// +/// - updateAdapterAsync: The updateAdapter operation is called to notify an observer that the state of an adapter changed. +public protocol NodeObserverPrx: Ice.ObjectPrx {} + +private final class NodeObserverPrxI: Ice.ObjectPrxI, NodeObserverPrx { + public override class func ice_staticId() -> Swift.String { + return NodeObserverTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `NodeObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `NodeObserverPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: NodeObserverPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> NodeObserverPrx? { + return try NodeObserverPrxI.checkedCast(prx: prx, facet: facet, context: context) as NodeObserverPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `NodeObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `NodeObserverPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: NodeObserverPrx.Protocol, facet: Swift.String? = nil) -> NodeObserverPrx { + return NodeObserverPrxI.uncheckedCast(prx: prx, facet: facet) as NodeObserverPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `NodeObserverPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: NodeObserverPrx.Protocol) -> Swift.String { + return NodeObserverTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `NodeObserverPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `NodeObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `NodeObserverPrx?` - The extracted proxy + func read(_ type: NodeObserverPrx.Protocol) throws -> NodeObserverPrx? { + return try read() as NodeObserverPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `NodeObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `NodeObserverPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: NodeObserverPrx.Protocol) throws -> NodeObserverPrx? { + return try read(tag: tag) as NodeObserverPrxI? + } +} + +/// The node observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// nodes. +/// +/// NodeObserverPrx Methods: +/// +/// - nodeInit: The nodeInit operation indicates the current state of nodes. +/// +/// - nodeInitAsync: The nodeInit operation indicates the current state of nodes. +/// +/// - nodeUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - nodeUpAsync: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - nodeDown: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - nodeDownAsync: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - updateServer: The updateServer operation is called to notify an observer that the state of a server changed. +/// +/// - updateServerAsync: The updateServer operation is called to notify an observer that the state of a server changed. +/// +/// - updateAdapter: The updateAdapter operation is called to notify an observer that the state of an adapter changed. +/// +/// - updateAdapterAsync: The updateAdapter operation is called to notify an observer that the state of an adapter changed. +public extension NodeObserverPrx { + /// The nodeInit operation indicates the current state + /// of nodes. It is called after the registration of an observer. + /// + /// - parameter _: `NodeDynamicInfoSeq` The current state of the nodes. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func nodeInit(_ iceP_nodes: NodeDynamicInfoSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "nodeInit", + mode: .Normal, + write: { ostr in + NodeDynamicInfoSeqHelper.write(to: ostr, value: iceP_nodes) + }, + context: context) + } + + /// The nodeInit operation indicates the current state + /// of nodes. It is called after the registration of an observer. + /// + /// - parameter _: `NodeDynamicInfoSeq` The current state of the nodes. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func nodeInitAsync(_ iceP_nodes: NodeDynamicInfoSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "nodeInit", + mode: .Normal, + write: { ostr in + NodeDynamicInfoSeqHelper.write(to: ostr, value: iceP_nodes) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter _: `NodeDynamicInfo` The node state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func nodeUp(_ iceP_node: NodeDynamicInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "nodeUp", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + }, + context: context) + } + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter _: `NodeDynamicInfo` The node state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func nodeUpAsync(_ iceP_node: NodeDynamicInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "nodeUp", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func nodeDown(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "nodeDown", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + context: context) + } + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func nodeDownAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "nodeDown", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The updateServer operation is called to notify an observer that + /// the state of a server changed. + /// + /// - parameter node: `Swift.String` The node hosting the server. + /// + /// - parameter updatedInfo: `ServerDynamicInfo` The new server state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func updateServer(node iceP_node: Swift.String, updatedInfo iceP_updatedInfo: ServerDynamicInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "updateServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + ostr.write(iceP_updatedInfo) + }, + context: context) + } + + /// The updateServer operation is called to notify an observer that + /// the state of a server changed. + /// + /// - parameter node: `Swift.String` The node hosting the server. + /// + /// - parameter updatedInfo: `ServerDynamicInfo` The new server state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func updateServerAsync(node iceP_node: Swift.String, updatedInfo iceP_updatedInfo: ServerDynamicInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "updateServer", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + ostr.write(iceP_updatedInfo) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The updateAdapter operation is called to notify an observer that + /// the state of an adapter changed. + /// + /// - parameter node: `Swift.String` The node hosting the adapter. + /// + /// - parameter updatedInfo: `AdapterDynamicInfo` The new adapter state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func updateAdapter(node iceP_node: Swift.String, updatedInfo iceP_updatedInfo: AdapterDynamicInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "updateAdapter", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + ostr.write(iceP_updatedInfo) + }, + context: context) + } + + /// The updateAdapter operation is called to notify an observer that + /// the state of an adapter changed. + /// + /// - parameter node: `Swift.String` The node hosting the adapter. + /// + /// - parameter updatedInfo: `AdapterDynamicInfo` The new adapter state. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func updateAdapterAsync(node iceP_node: Swift.String, updatedInfo iceP_updatedInfo: AdapterDynamicInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "updateAdapter", + mode: .Normal, + write: { ostr in + ostr.write(iceP_node) + ostr.write(iceP_updatedInfo) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The database observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// registry database. +/// +/// ApplicationObserverPrx Methods: +/// +/// - applicationInit: applicationInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - applicationInitAsync: applicationInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - applicationAdded: The applicationAdded operation is called to notify an observer that an application was added. +/// +/// - applicationAddedAsync: The applicationAdded operation is called to notify an observer that an application was added. +/// +/// - applicationRemoved: The applicationRemoved operation is called to notify an observer that an application was removed. +/// +/// - applicationRemovedAsync: The applicationRemoved operation is called to notify an observer that an application was removed. +/// +/// - applicationUpdated: The applicationUpdated operation is called to notify an observer that an application was updated. +/// +/// - applicationUpdatedAsync: The applicationUpdated operation is called to notify an observer that an application was updated. +public protocol ApplicationObserverPrx: Ice.ObjectPrx {} + +private final class ApplicationObserverPrxI: Ice.ObjectPrxI, ApplicationObserverPrx { + public override class func ice_staticId() -> Swift.String { + return ApplicationObserverTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `ApplicationObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `ApplicationObserverPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: ApplicationObserverPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> ApplicationObserverPrx? { + return try ApplicationObserverPrxI.checkedCast(prx: prx, facet: facet, context: context) as ApplicationObserverPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `ApplicationObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `ApplicationObserverPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: ApplicationObserverPrx.Protocol, facet: Swift.String? = nil) -> ApplicationObserverPrx { + return ApplicationObserverPrxI.uncheckedCast(prx: prx, facet: facet) as ApplicationObserverPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `ApplicationObserverPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: ApplicationObserverPrx.Protocol) -> Swift.String { + return ApplicationObserverTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `ApplicationObserverPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `ApplicationObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ApplicationObserverPrx?` - The extracted proxy + func read(_ type: ApplicationObserverPrx.Protocol) throws -> ApplicationObserverPrx? { + return try read() as ApplicationObserverPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `ApplicationObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ApplicationObserverPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: ApplicationObserverPrx.Protocol) throws -> ApplicationObserverPrx? { + return try read(tag: tag) as ApplicationObserverPrxI? + } +} + +/// The database observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// registry database. +/// +/// ApplicationObserverPrx Methods: +/// +/// - applicationInit: applicationInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - applicationInitAsync: applicationInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - applicationAdded: The applicationAdded operation is called to notify an observer that an application was added. +/// +/// - applicationAddedAsync: The applicationAdded operation is called to notify an observer that an application was added. +/// +/// - applicationRemoved: The applicationRemoved operation is called to notify an observer that an application was removed. +/// +/// - applicationRemovedAsync: The applicationRemoved operation is called to notify an observer that an application was removed. +/// +/// - applicationUpdated: The applicationUpdated operation is called to notify an observer that an application was updated. +/// +/// - applicationUpdatedAsync: The applicationUpdated operation is called to notify an observer that an application was updated. +public extension ApplicationObserverPrx { + /// applicationInit is called after the registration + /// of an observer to indicate the state of the registry. + /// + /// - parameter serial: `Swift.Int32` The current serial number of the registry + /// database. This serial number allows observers to make sure that + /// their internal state is synchronized with the registry. + /// + /// - parameter applications: `ApplicationInfoSeq` The applications currently registered with + /// the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func applicationInit(serial iceP_serial: Swift.Int32, applications iceP_applications: ApplicationInfoSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "applicationInit", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ApplicationInfoSeqHelper.write(to: ostr, value: iceP_applications) + ostr.writePendingValues() + }, + context: context) + } + + /// applicationInit is called after the registration + /// of an observer to indicate the state of the registry. + /// + /// - parameter serial: `Swift.Int32` The current serial number of the registry + /// database. This serial number allows observers to make sure that + /// their internal state is synchronized with the registry. + /// + /// - parameter applications: `ApplicationInfoSeq` The applications currently registered with + /// the registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func applicationInitAsync(serial iceP_serial: Swift.Int32, applications iceP_applications: ApplicationInfoSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "applicationInit", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ApplicationInfoSeqHelper.write(to: ostr, value: iceP_applications) + ostr.writePendingValues() + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The applicationAdded operation is called to notify an observer + /// that an application was added. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationInfo` The descriptor of the new application. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func applicationAdded(serial iceP_serial: Swift.Int32, desc iceP_desc: ApplicationInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "applicationAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_desc) + ostr.writePendingValues() + }, + context: context) + } + + /// The applicationAdded operation is called to notify an observer + /// that an application was added. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationInfo` The descriptor of the new application. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func applicationAddedAsync(serial iceP_serial: Swift.Int32, desc iceP_desc: ApplicationInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "applicationAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_desc) + ostr.writePendingValues() + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The applicationRemoved operation is called to notify an observer + /// that an application was removed. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter name: `Swift.String` The name of the application that was removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func applicationRemoved(serial iceP_serial: Swift.Int32, name iceP_name: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "applicationRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_name) + }, + context: context) + } + + /// The applicationRemoved operation is called to notify an observer + /// that an application was removed. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter name: `Swift.String` The name of the application that was removed. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func applicationRemovedAsync(serial iceP_serial: Swift.Int32, name iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "applicationRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_name) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The applicationUpdated operation is called to notify an observer + /// that an application was updated. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationUpdateInfo` The descriptor of the update. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func applicationUpdated(serial iceP_serial: Swift.Int32, desc iceP_desc: ApplicationUpdateInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "applicationUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_desc) + ostr.writePendingValues() + }, + context: context) + } + + /// The applicationUpdated operation is called to notify an observer + /// that an application was updated. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationUpdateInfo` The descriptor of the update. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func applicationUpdatedAsync(serial iceP_serial: Swift.Int32, desc iceP_desc: ApplicationUpdateInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "applicationUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_serial) + ostr.write(iceP_desc) + ostr.writePendingValues() + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This interface allows applications to monitor the state of object +/// adapters that are registered with IceGrid. +/// +/// AdapterObserverPrx Methods: +/// +/// - adapterInit: adapterInit is called after registration of an observer to indicate the state of the registry. +/// +/// - adapterInitAsync: adapterInit is called after registration of an observer to indicate the state of the registry. +/// +/// - adapterAdded: The adapterAdded operation is called to notify an observer when a dynamically-registered adapter was added. +/// +/// - adapterAddedAsync: The adapterAdded operation is called to notify an observer when a dynamically-registered adapter was added. +/// +/// - adapterUpdated: The adapterUpdated operation is called to notify an observer when a dynamically-registered adapter was updated. +/// +/// - adapterUpdatedAsync: The adapterUpdated operation is called to notify an observer when a dynamically-registered adapter was updated. +/// +/// - adapterRemoved: The adapterRemoved operation is called to notify an observer when a dynamically-registered adapter was removed. +/// +/// - adapterRemovedAsync: The adapterRemoved operation is called to notify an observer when a dynamically-registered adapter was removed. +public protocol AdapterObserverPrx: Ice.ObjectPrx {} + +private final class AdapterObserverPrxI: Ice.ObjectPrxI, AdapterObserverPrx { + public override class func ice_staticId() -> Swift.String { + return AdapterObserverTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `AdapterObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `AdapterObserverPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: AdapterObserverPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> AdapterObserverPrx? { + return try AdapterObserverPrxI.checkedCast(prx: prx, facet: facet, context: context) as AdapterObserverPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `AdapterObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `AdapterObserverPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: AdapterObserverPrx.Protocol, facet: Swift.String? = nil) -> AdapterObserverPrx { + return AdapterObserverPrxI.uncheckedCast(prx: prx, facet: facet) as AdapterObserverPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `AdapterObserverPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: AdapterObserverPrx.Protocol) -> Swift.String { + return AdapterObserverTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `AdapterObserverPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `AdapterObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdapterObserverPrx?` - The extracted proxy + func read(_ type: AdapterObserverPrx.Protocol) throws -> AdapterObserverPrx? { + return try read() as AdapterObserverPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `AdapterObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdapterObserverPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: AdapterObserverPrx.Protocol) throws -> AdapterObserverPrx? { + return try read(tag: tag) as AdapterObserverPrxI? + } +} + +/// This interface allows applications to monitor the state of object +/// adapters that are registered with IceGrid. +/// +/// AdapterObserverPrx Methods: +/// +/// - adapterInit: adapterInit is called after registration of an observer to indicate the state of the registry. +/// +/// - adapterInitAsync: adapterInit is called after registration of an observer to indicate the state of the registry. +/// +/// - adapterAdded: The adapterAdded operation is called to notify an observer when a dynamically-registered adapter was added. +/// +/// - adapterAddedAsync: The adapterAdded operation is called to notify an observer when a dynamically-registered adapter was added. +/// +/// - adapterUpdated: The adapterUpdated operation is called to notify an observer when a dynamically-registered adapter was updated. +/// +/// - adapterUpdatedAsync: The adapterUpdated operation is called to notify an observer when a dynamically-registered adapter was updated. +/// +/// - adapterRemoved: The adapterRemoved operation is called to notify an observer when a dynamically-registered adapter was removed. +/// +/// - adapterRemovedAsync: The adapterRemoved operation is called to notify an observer when a dynamically-registered adapter was removed. +public extension AdapterObserverPrx { + /// adapterInit is called after registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter _: `AdapterInfoSeq` The adapters that were dynamically registered + /// with the registry (not through the deployment mechanism). + /// + /// - parameter context: `Ice.Context` - Optional request context. + func adapterInit(_ iceP_adpts: AdapterInfoSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "adapterInit", + mode: .Normal, + write: { ostr in + AdapterInfoSeqHelper.write(to: ostr, value: iceP_adpts) + }, + context: context) + } + + /// adapterInit is called after registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter _: `AdapterInfoSeq` The adapters that were dynamically registered + /// with the registry (not through the deployment mechanism). + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func adapterInitAsync(_ iceP_adpts: AdapterInfoSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "adapterInit", + mode: .Normal, + write: { ostr in + AdapterInfoSeqHelper.write(to: ostr, value: iceP_adpts) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The adapterAdded operation is called to notify an observer when + /// a dynamically-registered adapter was added. + /// + /// - parameter _: `AdapterInfo` The details of the new adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func adapterAdded(_ iceP_info: AdapterInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "adapterAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context) + } + + /// The adapterAdded operation is called to notify an observer when + /// a dynamically-registered adapter was added. + /// + /// - parameter _: `AdapterInfo` The details of the new adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func adapterAddedAsync(_ iceP_info: AdapterInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "adapterAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The adapterUpdated operation is called to notify an observer when + /// a dynamically-registered adapter was updated. + /// + /// - parameter _: `AdapterInfo` The details of the updated adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func adapterUpdated(_ iceP_info: AdapterInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "adapterUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context) + } + + /// The adapterUpdated operation is called to notify an observer when + /// a dynamically-registered adapter was updated. + /// + /// - parameter _: `AdapterInfo` The details of the updated adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func adapterUpdatedAsync(_ iceP_info: AdapterInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "adapterUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The adapterRemoved operation is called to notify an observer when + /// a dynamically-registered adapter was removed. + /// + /// - parameter _: `Swift.String` The ID of the removed adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func adapterRemoved(_ iceP_id: Swift.String, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "adapterRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + context: context) + } + + /// The adapterRemoved operation is called to notify an observer when + /// a dynamically-registered adapter was removed. + /// + /// - parameter _: `Swift.String` The ID of the removed adapter. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func adapterRemovedAsync(_ iceP_id: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "adapterRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This interface allows applications to monitor IceGrid well-known objects. +/// +/// ObjectObserverPrx Methods: +/// +/// - objectInit: objectInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - objectInitAsync: objectInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - objectAdded: The objectAdded operation is called to notify an observer when an object was added to the Admin interface. +/// +/// - objectAddedAsync: The objectAdded operation is called to notify an observer when an object was added to the Admin interface. +/// +/// - objectUpdated: objectUpdated is called to notify an observer when an object registered with the Admin interface was updated. +/// +/// - objectUpdatedAsync: objectUpdated is called to notify an observer when an object registered with the Admin interface was updated. +/// +/// - objectRemoved: objectRemoved is called to notify an observer when an object registered with the Admin interface was removed. +/// +/// - objectRemovedAsync: objectRemoved is called to notify an observer when an object registered with the Admin interface was removed. +public protocol ObjectObserverPrx: Ice.ObjectPrx {} + +private final class ObjectObserverPrxI: Ice.ObjectPrxI, ObjectObserverPrx { + public override class func ice_staticId() -> Swift.String { + return ObjectObserverTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `ObjectObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `ObjectObserverPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: ObjectObserverPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> ObjectObserverPrx? { + return try ObjectObserverPrxI.checkedCast(prx: prx, facet: facet, context: context) as ObjectObserverPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `ObjectObserverPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `ObjectObserverPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: ObjectObserverPrx.Protocol, facet: Swift.String? = nil) -> ObjectObserverPrx { + return ObjectObserverPrxI.uncheckedCast(prx: prx, facet: facet) as ObjectObserverPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `ObjectObserverPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: ObjectObserverPrx.Protocol) -> Swift.String { + return ObjectObserverTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `ObjectObserverPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `ObjectObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ObjectObserverPrx?` - The extracted proxy + func read(_ type: ObjectObserverPrx.Protocol) throws -> ObjectObserverPrx? { + return try read() as ObjectObserverPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `ObjectObserverPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `ObjectObserverPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: ObjectObserverPrx.Protocol) throws -> ObjectObserverPrx? { + return try read(tag: tag) as ObjectObserverPrxI? + } +} + +/// This interface allows applications to monitor IceGrid well-known objects. +/// +/// ObjectObserverPrx Methods: +/// +/// - objectInit: objectInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - objectInitAsync: objectInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - objectAdded: The objectAdded operation is called to notify an observer when an object was added to the Admin interface. +/// +/// - objectAddedAsync: The objectAdded operation is called to notify an observer when an object was added to the Admin interface. +/// +/// - objectUpdated: objectUpdated is called to notify an observer when an object registered with the Admin interface was updated. +/// +/// - objectUpdatedAsync: objectUpdated is called to notify an observer when an object registered with the Admin interface was updated. +/// +/// - objectRemoved: objectRemoved is called to notify an observer when an object registered with the Admin interface was removed. +/// +/// - objectRemovedAsync: objectRemoved is called to notify an observer when an object registered with the Admin interface was removed. +public extension ObjectObserverPrx { + /// objectInit is called after the registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter _: `ObjectInfoSeq` The objects registered with the Admin + /// interface (not through the deployment mechanism). + /// + /// - parameter context: `Ice.Context` - Optional request context. + func objectInit(_ iceP_objects: ObjectInfoSeq, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "objectInit", + mode: .Normal, + write: { ostr in + ObjectInfoSeqHelper.write(to: ostr, value: iceP_objects) + }, + context: context) + } + + /// objectInit is called after the registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter _: `ObjectInfoSeq` The objects registered with the Admin + /// interface (not through the deployment mechanism). + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func objectInitAsync(_ iceP_objects: ObjectInfoSeq, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "objectInit", + mode: .Normal, + write: { ostr in + ObjectInfoSeqHelper.write(to: ostr, value: iceP_objects) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// The objectAdded operation is called to notify an observer when an + /// object was added to the Admin interface. + /// + /// - parameter _: `ObjectInfo` The details of the added object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func objectAdded(_ iceP_info: ObjectInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "objectAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context) + } + + /// The objectAdded operation is called to notify an observer when an + /// object was added to the Admin interface. + /// + /// - parameter _: `ObjectInfo` The details of the added object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func objectAddedAsync(_ iceP_info: ObjectInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "objectAdded", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// objectUpdated is called to notify an observer when + /// an object registered with the Admin interface was updated. + /// + /// - parameter _: `ObjectInfo` The details of the updated object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func objectUpdated(_ iceP_info: ObjectInfo, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "objectUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context) + } + + /// objectUpdated is called to notify an observer when + /// an object registered with the Admin interface was updated. + /// + /// - parameter _: `ObjectInfo` The details of the updated object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func objectUpdatedAsync(_ iceP_info: ObjectInfo, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "objectUpdated", + mode: .Normal, + write: { ostr in + ostr.write(iceP_info) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// objectRemoved is called to notify an observer when + /// an object registered with the Admin interface was removed. + /// + /// - parameter _: `Ice.Identity` The identity of the removed object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func objectRemoved(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "objectRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + context: context) + } + + /// objectRemoved is called to notify an observer when + /// an object registered with the Admin interface was removed. + /// + /// - parameter _: `Ice.Identity` The identity of the removed object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func objectRemovedAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "objectRemoved", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// Used by administrative clients to view, +/// update, and receive observer updates from the IceGrid +/// registry. Admin sessions are created either via the Registry +/// object or via the registry admin SessionManager object. +/// +/// AdminSessionPrx Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - keepAliveAsync: Keep the session alive. +/// +/// - getAdmin: Get the admin interface. +/// +/// - getAdminAsync: Get the admin interface. +/// +/// - getAdminCallbackTemplate: Get a "template" proxy for admin callback objects. +/// +/// - getAdminCallbackTemplateAsync: Get a "template" proxy for admin callback objects. +/// +/// - setObservers: Set the observer proxies that receive notifications when the state of the registry or nodes changes. +/// +/// - setObserversAsync: Set the observer proxies that receive notifications when the state of the registry or nodes changes. +/// +/// - setObserversByIdentity: Set the observer identities that receive notifications the state of the registry or nodes changes. +/// +/// - setObserversByIdentityAsync: Set the observer identities that receive notifications the state of the registry or nodes changes. +/// +/// - startUpdate: Acquires an exclusive lock to start updating the registry applications. +/// +/// - startUpdateAsync: Acquires an exclusive lock to start updating the registry applications. +/// +/// - finishUpdate: Finish updating the registry and release the exclusive lock. +/// +/// - finishUpdateAsync: Finish updating the registry and release the exclusive lock. +/// +/// - getReplicaName: Get the name of the registry replica hosting this session. +/// +/// - getReplicaNameAsync: Get the name of the registry replica hosting this session. +/// +/// - openServerLog: Open the given server log file for reading. +/// +/// - openServerLogAsync: Open the given server log file for reading. +/// +/// - openServerStdErr: Open the given server stderr file for reading. +/// +/// - openServerStdErrAsync: Open the given server stderr file for reading. +/// +/// - openServerStdOut: Open the given server stdout file for reading. +/// +/// - openServerStdOutAsync: Open the given server stdout file for reading. +/// +/// - openNodeStdErr: Open the given node stderr file for reading. +/// +/// - openNodeStdErrAsync: Open the given node stderr file for reading. +/// +/// - openNodeStdOut: Open the given node stdout file for reading. +/// +/// - openNodeStdOutAsync: Open the given node stdout file for reading. +/// +/// - openRegistryStdErr: Open the given registry stderr file for reading. +/// +/// - openRegistryStdErrAsync: Open the given registry stderr file for reading. +/// +/// - openRegistryStdOut: Open the given registry stdout file for reading. +/// +/// - openRegistryStdOutAsync: Open the given registry stdout file for reading. +public protocol AdminSessionPrx: Glacier2.SessionPrx {} + +private final class AdminSessionPrxI: Ice.ObjectPrxI, AdminSessionPrx { + public override class func ice_staticId() -> Swift.String { + return AdminSessionTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `AdminSessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `AdminSessionPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: AdminSessionPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> AdminSessionPrx? { + return try AdminSessionPrxI.checkedCast(prx: prx, facet: facet, context: context) as AdminSessionPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `AdminSessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `AdminSessionPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: AdminSessionPrx.Protocol, facet: Swift.String? = nil) -> AdminSessionPrx { + return AdminSessionPrxI.uncheckedCast(prx: prx, facet: facet) as AdminSessionPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `AdminSessionPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: AdminSessionPrx.Protocol) -> Swift.String { + return AdminSessionTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `AdminSessionPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `AdminSessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdminSessionPrx?` - The extracted proxy + func read(_ type: AdminSessionPrx.Protocol) throws -> AdminSessionPrx? { + return try read() as AdminSessionPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `AdminSessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `AdminSessionPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: AdminSessionPrx.Protocol) throws -> AdminSessionPrx? { + return try read(tag: tag) as AdminSessionPrxI? + } +} + +/// Used by administrative clients to view, +/// update, and receive observer updates from the IceGrid +/// registry. Admin sessions are created either via the Registry +/// object or via the registry admin SessionManager object. +/// +/// AdminSessionPrx Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - keepAliveAsync: Keep the session alive. +/// +/// - getAdmin: Get the admin interface. +/// +/// - getAdminAsync: Get the admin interface. +/// +/// - getAdminCallbackTemplate: Get a "template" proxy for admin callback objects. +/// +/// - getAdminCallbackTemplateAsync: Get a "template" proxy for admin callback objects. +/// +/// - setObservers: Set the observer proxies that receive notifications when the state of the registry or nodes changes. +/// +/// - setObserversAsync: Set the observer proxies that receive notifications when the state of the registry or nodes changes. +/// +/// - setObserversByIdentity: Set the observer identities that receive notifications the state of the registry or nodes changes. +/// +/// - setObserversByIdentityAsync: Set the observer identities that receive notifications the state of the registry or nodes changes. +/// +/// - startUpdate: Acquires an exclusive lock to start updating the registry applications. +/// +/// - startUpdateAsync: Acquires an exclusive lock to start updating the registry applications. +/// +/// - finishUpdate: Finish updating the registry and release the exclusive lock. +/// +/// - finishUpdateAsync: Finish updating the registry and release the exclusive lock. +/// +/// - getReplicaName: Get the name of the registry replica hosting this session. +/// +/// - getReplicaNameAsync: Get the name of the registry replica hosting this session. +/// +/// - openServerLog: Open the given server log file for reading. +/// +/// - openServerLogAsync: Open the given server log file for reading. +/// +/// - openServerStdErr: Open the given server stderr file for reading. +/// +/// - openServerStdErrAsync: Open the given server stderr file for reading. +/// +/// - openServerStdOut: Open the given server stdout file for reading. +/// +/// - openServerStdOutAsync: Open the given server stdout file for reading. +/// +/// - openNodeStdErr: Open the given node stderr file for reading. +/// +/// - openNodeStdErrAsync: Open the given node stderr file for reading. +/// +/// - openNodeStdOut: Open the given node stdout file for reading. +/// +/// - openNodeStdOutAsync: Open the given node stdout file for reading. +/// +/// - openRegistryStdErr: Open the given registry stderr file for reading. +/// +/// - openRegistryStdErrAsync: Open the given registry stderr file for reading. +/// +/// - openRegistryStdOut: Open the given registry stdout file for reading. +/// +/// - openRegistryStdOutAsync: Open the given registry stdout file for reading. +public extension AdminSessionPrx { + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func keepAlive(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "keepAlive", + mode: .Idempotent, + context: context) + } + + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func keepAliveAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "keepAlive", + mode: .Idempotent, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the admin interface. The admin object returned by this + /// operation can only be accessed by the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `AdminPrx?` - The admin interface proxy. + func getAdmin(context: Ice.Context? = nil) throws -> AdminPrx? { + return try _impl._invoke(operation: "getAdmin", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: AdminPrx? = try istr.read(AdminPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the admin interface. The admin object returned by this + /// operation can only be accessed by the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAdminAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAdmin", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: AdminPrx? = try istr.read(AdminPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a "template" proxy for admin callback objects. + /// An Admin client uses this proxy to set the category of its callback + /// objects, and the published endpoints of the object adapter hosting + /// the admin callback objects. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A template proxy. The returned proxy is null when the Admin + /// session was established using Glacier2. + func getAdminCallbackTemplate(context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getAdminCallbackTemplate", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get a "template" proxy for admin callback objects. + /// An Admin client uses this proxy to set the category of its callback + /// objects, and the published endpoints of the object adapter hosting + /// the admin callback objects. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getAdminCallbackTemplateAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getAdminCallbackTemplate", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Set the observer proxies that receive + /// notifications when the state of the registry + /// or nodes changes. + /// + /// - parameter registryObs: `RegistryObserverPrx?` The registry observer. + /// + /// - parameter nodeObs: `NodeObserverPrx?` The node observer. + /// + /// - parameter appObs: `ApplicationObserverPrx?` The application observer. + /// + /// - parameter adptObs: `AdapterObserverPrx?` The adapter observer. + /// + /// - parameter objObs: `ObjectObserverPrx?` The object observer. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - ObserverAlreadyRegisteredException - Raised if an + /// observer is already registered with this registry. + func setObservers(registryObs iceP_registryObs: RegistryObserverPrx?, nodeObs iceP_nodeObs: NodeObserverPrx?, appObs iceP_appObs: ApplicationObserverPrx?, adptObs iceP_adptObs: AdapterObserverPrx?, objObs iceP_objObs: ObjectObserverPrx?, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "setObservers", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_registryObs) + ostr.write(iceP_nodeObs) + ostr.write(iceP_appObs) + ostr.write(iceP_adptObs) + ostr.write(iceP_objObs) + }, + userException:{ ex in + do { + throw ex + } catch let error as ObserverAlreadyRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Set the observer proxies that receive + /// notifications when the state of the registry + /// or nodes changes. + /// + /// - parameter registryObs: `RegistryObserverPrx?` The registry observer. + /// + /// - parameter nodeObs: `NodeObserverPrx?` The node observer. + /// + /// - parameter appObs: `ApplicationObserverPrx?` The application observer. + /// + /// - parameter adptObs: `AdapterObserverPrx?` The adapter observer. + /// + /// - parameter objObs: `ObjectObserverPrx?` The object observer. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setObserversAsync(registryObs iceP_registryObs: RegistryObserverPrx?, nodeObs iceP_nodeObs: NodeObserverPrx?, appObs iceP_appObs: ApplicationObserverPrx?, adptObs iceP_adptObs: AdapterObserverPrx?, objObs iceP_objObs: ObjectObserverPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setObservers", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_registryObs) + ostr.write(iceP_nodeObs) + ostr.write(iceP_appObs) + ostr.write(iceP_adptObs) + ostr.write(iceP_objObs) + }, + userException:{ ex in + do { + throw ex + } catch let error as ObserverAlreadyRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Set the observer identities that receive + /// notifications the state of the registry + /// or nodes changes. This operation should be used by clients that + /// are using a bidirectional connection to communicate with the + /// session. + /// + /// - parameter registryObs: `Ice.Identity` The registry observer identity. + /// + /// - parameter nodeObs: `Ice.Identity` The node observer identity. + /// + /// - parameter appObs: `Ice.Identity` The application observer. + /// + /// - parameter adptObs: `Ice.Identity` The adapter observer. + /// + /// - parameter objObs: `Ice.Identity` The object observer. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - ObserverAlreadyRegisteredException - Raised if an + /// observer is already registered with this registry. + func setObserversByIdentity(registryObs iceP_registryObs: Ice.Identity, nodeObs iceP_nodeObs: Ice.Identity, appObs iceP_appObs: Ice.Identity, adptObs iceP_adptObs: Ice.Identity, objObs iceP_objObs: Ice.Identity, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "setObserversByIdentity", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_registryObs) + ostr.write(iceP_nodeObs) + ostr.write(iceP_appObs) + ostr.write(iceP_adptObs) + ostr.write(iceP_objObs) + }, + userException:{ ex in + do { + throw ex + } catch let error as ObserverAlreadyRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Set the observer identities that receive + /// notifications the state of the registry + /// or nodes changes. This operation should be used by clients that + /// are using a bidirectional connection to communicate with the + /// session. + /// + /// - parameter registryObs: `Ice.Identity` The registry observer identity. + /// + /// - parameter nodeObs: `Ice.Identity` The node observer identity. + /// + /// - parameter appObs: `Ice.Identity` The application observer. + /// + /// - parameter adptObs: `Ice.Identity` The adapter observer. + /// + /// - parameter objObs: `Ice.Identity` The object observer. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setObserversByIdentityAsync(registryObs iceP_registryObs: Ice.Identity, nodeObs iceP_nodeObs: Ice.Identity, appObs iceP_appObs: Ice.Identity, adptObs iceP_adptObs: Ice.Identity, objObs iceP_objObs: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setObserversByIdentity", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_registryObs) + ostr.write(iceP_nodeObs) + ostr.write(iceP_appObs) + ostr.write(iceP_adptObs) + ostr.write(iceP_objObs) + }, + userException:{ ex in + do { + throw ex + } catch let error as ObserverAlreadyRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Acquires an exclusive lock to start updating the registry applications. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The current serial. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the exclusive lock can't be + /// acquired. This might happen if the lock is currently acquired by + /// another session. + func startUpdate(context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "startUpdate", + mode: .Normal, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Acquires an exclusive lock to start updating the registry applications. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func startUpdateAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "startUpdate", + mode: .Normal, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Finish updating the registry and release the exclusive lock. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't hold the + /// exclusive lock. + func finishUpdate(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "finishUpdate", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Finish updating the registry and release the exclusive lock. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func finishUpdateAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "finishUpdate", + mode: .Normal, + userException:{ ex in + do { + throw ex + } catch let error as AccessDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the name of the registry replica hosting this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The replica name of the registry. + func getReplicaName(context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getReplicaName", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the name of the registry replica hosting this session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getReplicaNameAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getReplicaName", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given server log file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter path: `Swift.String` The path of the log file. A log file can be opened + /// only if it's declared in the server or service deployment + /// descriptor. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerLog(id iceP_id: Swift.String, path iceP_path: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openServerLog", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_path) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given server log file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter path: `Swift.String` The path of the log file. A log file can be opened + /// only if it's declared in the server or service deployment + /// descriptor. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openServerLogAsync(id iceP_id: Swift.String, path iceP_path: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openServerLog", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_path) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given server stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerStdErr(id iceP_id: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openServerStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given server stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openServerStdErrAsync(id iceP_id: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openServerStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given server stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerStdOut(id iceP_id: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openServerStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given server stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openServerStdOutAsync(id iceP_id: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openServerStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as DeploymentException { + throw error + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch let error as ServerNotExistException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given node stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + func openNodeStdErr(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openNodeStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given node stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openNodeStdErrAsync(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openNodeStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given node stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + func openNodeStdOut(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openNodeStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given node stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openNodeStdOutAsync(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openNodeStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as NodeNotExistException { + throw error + } catch let error as NodeUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given registry stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - RegistryNotExistException - Raised if the registry + /// doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry + /// could not be reached. + func openRegistryStdErr(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openRegistryStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given registry stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openRegistryStdErrAsync(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openRegistryStdErr", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Open the given registry stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - RegistryNotExistException - Raised if the registry + /// doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry + /// could not be reached. + func openRegistryStdOut(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil) throws -> FileIteratorPrx? { + return try _impl._invoke(operation: "openRegistryStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Open the given registry stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func openRegistryStdOutAsync(name iceP_name: Swift.String, count iceP_count: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "openRegistryStdOut", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + ostr.write(iceP_count) + }, + read: { istr in + let iceP_returnValue: FileIteratorPrx? = try istr.read(FileIteratorPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as FileNotAvailableException { + throw error + } catch let error as RegistryNotExistException { + throw error + } catch let error as RegistryUnreachableException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Admin` servants. +public struct AdminDisp: Ice.Disp { + public let servant: Admin + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Admin) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "addApplication": + return try servant._iceD_addApplication(incoming: request, current: current) + case "addObject": + return try servant._iceD_addObject(incoming: request, current: current) + case "addObjectWithType": + return try servant._iceD_addObjectWithType(incoming: request, current: current) + case "enableServer": + return try servant._iceD_enableServer(incoming: request, current: current) + case "getAdapterInfo": + return try servant._iceD_getAdapterInfo(incoming: request, current: current) + case "getAllAdapterIds": + return try servant._iceD_getAllAdapterIds(incoming: request, current: current) + case "getAllApplicationNames": + return try servant._iceD_getAllApplicationNames(incoming: request, current: current) + case "getAllNodeNames": + return try servant._iceD_getAllNodeNames(incoming: request, current: current) + case "getAllObjectInfos": + return try servant._iceD_getAllObjectInfos(incoming: request, current: current) + case "getAllRegistryNames": + return try servant._iceD_getAllRegistryNames(incoming: request, current: current) + case "getAllServerIds": + return try servant._iceD_getAllServerIds(incoming: request, current: current) + case "getApplicationInfo": + return try servant._iceD_getApplicationInfo(incoming: request, current: current) + case "getDefaultApplicationDescriptor": + return try servant._iceD_getDefaultApplicationDescriptor(incoming: request, current: current) + case "getNodeAdmin": + return try servant._iceD_getNodeAdmin(incoming: request, current: current) + case "getNodeHostname": + return try servant._iceD_getNodeHostname(incoming: request, current: current) + case "getNodeInfo": + return try servant._iceD_getNodeInfo(incoming: request, current: current) + case "getNodeLoad": + return try servant._iceD_getNodeLoad(incoming: request, current: current) + case "getNodeProcessorSocketCount": + return try servant._iceD_getNodeProcessorSocketCount(incoming: request, current: current) + case "getObjectInfo": + return try servant._iceD_getObjectInfo(incoming: request, current: current) + case "getObjectInfosByType": + return try servant._iceD_getObjectInfosByType(incoming: request, current: current) + case "getRegistryAdmin": + return try servant._iceD_getRegistryAdmin(incoming: request, current: current) + case "getRegistryInfo": + return try servant._iceD_getRegistryInfo(incoming: request, current: current) + case "getServerAdmin": + return try servant._iceD_getServerAdmin(incoming: request, current: current) + case "getServerAdminCategory": + return try servant._iceD_getServerAdminCategory(incoming: request, current: current) + case "getServerInfo": + return try servant._iceD_getServerInfo(incoming: request, current: current) + case "getServerPid": + return try servant._iceD_getServerPid(incoming: request, current: current) + case "getServerState": + return try servant._iceD_getServerState(incoming: request, current: current) + case "getSliceChecksums": + return try servant._iceD_getSliceChecksums(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? AdminDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? AdminDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? AdminDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? AdminDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "instantiateServer": + return try servant._iceD_instantiateServer(incoming: request, current: current) + case "isServerEnabled": + return try servant._iceD_isServerEnabled(incoming: request, current: current) + case "patchApplication": + return try servant._iceD_patchApplication(incoming: request, current: current) + case "patchServer": + return try servant._iceD_patchServer(incoming: request, current: current) + case "pingNode": + return try servant._iceD_pingNode(incoming: request, current: current) + case "pingRegistry": + return try servant._iceD_pingRegistry(incoming: request, current: current) + case "removeAdapter": + return try servant._iceD_removeAdapter(incoming: request, current: current) + case "removeApplication": + return try servant._iceD_removeApplication(incoming: request, current: current) + case "removeObject": + return try servant._iceD_removeObject(incoming: request, current: current) + case "sendSignal": + return try servant._iceD_sendSignal(incoming: request, current: current) + case "shutdown": + return try servant._iceD_shutdown(incoming: request, current: current) + case "shutdownNode": + return try servant._iceD_shutdownNode(incoming: request, current: current) + case "shutdownRegistry": + return try servant._iceD_shutdownRegistry(incoming: request, current: current) + case "startServer": + return try servant._iceD_startServer(incoming: request, current: current) + case "stopServer": + return try servant._iceD_stopServer(incoming: request, current: current) + case "syncApplication": + return try servant._iceD_syncApplication(incoming: request, current: current) + case "syncApplicationWithoutRestart": + return try servant._iceD_syncApplicationWithoutRestart(incoming: request, current: current) + case "updateApplication": + return try servant._iceD_updateApplication(incoming: request, current: current) + case "updateApplicationWithoutRestart": + return try servant._iceD_updateApplicationWithoutRestart(incoming: request, current: current) + case "updateObject": + return try servant._iceD_updateObject(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The IceGrid administrative interface. +/// Allowing access to this interface +/// is a security risk! Please see the IceGrid documentation +/// for further information. +public protocol Admin { + /// Add an application to IceGrid. + /// + /// - parameter descriptor: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func addApplication(descriptor: ApplicationDescriptor, current: Ice.Current) throws + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor. + /// + /// - parameter descriptor: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func syncApplication(descriptor: ApplicationDescriptor, current: Ice.Current) throws + + /// Update a deployed application with the given update application + /// descriptor. + /// + /// - parameter descriptor: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func updateApplication(descriptor: ApplicationUpdateDescriptor, current: Ice.Current) throws + + /// Synchronize a deployed application with the given application + /// descriptor. This operation will replace the current descriptor + /// with this new descriptor only if no server restarts are + /// necessary for the update of the application. If some servers + /// need to be restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter descriptor: `ApplicationDescriptor` The application descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func syncApplicationWithoutRestart(descriptor: ApplicationDescriptor, current: Ice.Current) throws + + /// Update a deployed application with the given update application + /// descriptor only if no server restarts are necessary for the + /// update of the application. If some servers need to be + /// restarted, the synchronization is rejected with a + /// DeploymentException. + /// + /// - parameter descriptor: `ApplicationUpdateDescriptor` The update descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment + /// failed. + func updateApplicationWithoutRestart(descriptor: ApplicationUpdateDescriptor, current: Ice.Current) throws + + /// Remove an application from IceGrid. + /// + /// - parameter name: `Swift.String` The application name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if application deployment failed. + func removeApplication(name: Swift.String, current: Ice.Current) throws + + /// Instantiate a server template from an application on the given + /// node. + /// + /// - parameter application: `Swift.String` The application name. + /// + /// - parameter node: `Swift.String` The name of the node where the server will be + /// deployed. + /// + /// - parameter desc: `ServerInstanceDescriptor` The descriptor of the server instance to deploy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't + /// hold the exclusive lock or if another session is holding the + /// lock. + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + /// + /// - DeploymentException - Raised if server instantiation + /// failed. + func instantiateServer(application: Swift.String, node: Swift.String, desc: ServerInstanceDescriptor, current: Ice.Current) throws + + /// Patch the given application data. + /// + /// - parameter name: `Swift.String` The application name. + /// + /// - parameter shutdown: `Swift.Bool` If true, the servers depending on the data to + /// patch will be shut down if necessary. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func patchApplicationAsync(name: Swift.String, shutdown: Swift.Bool, current: Ice.Current) -> PromiseKit.Promise + + /// Get an application descriptor. + /// + /// - parameter name: `Swift.String` The application name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ApplicationInfo` - The application descriptor. + /// + /// - throws: + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + func getApplicationInfo(name: Swift.String, current: Ice.Current) throws -> ApplicationInfo + + /// Get the default application descriptor. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ApplicationDescriptor` - The default application descriptor. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the default application + /// descriptor can't be accessed or is invalid. + func getDefaultApplicationDescriptor(current: Ice.Current) throws -> ApplicationDescriptor + + /// Get all the IceGrid applications currently registered. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The application names. + func getAllApplicationNames(current: Ice.Current) throws -> Ice.StringSeq + + /// Get the server information for the server with the given id. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ServerInfo` - The server information. + /// + /// - throws: + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerInfo(id: Swift.String, current: Ice.Current) throws -> ServerInfo + + /// Get a server's state. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ServerState` - The server state. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerState(id: Swift.String, current: Ice.Current) throws -> ServerState + + /// Get a server's system process id. The process id is operating + /// system dependent. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The server's process id. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerPid(id: Swift.String, current: Ice.Current) throws -> Swift.Int32 + + /// Get the category for server admin objects. You can manufacture a server admin + /// proxy from the admin proxy by changing its identity: use the server ID as name + /// and the returned category as category. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The category for server admin objects. + func getServerAdminCategory(current: Ice.Current) throws -> Swift.String + + /// Get a proxy to the server's admin object. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the server's admin object + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerAdmin(id: Swift.String, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Enable or disable a server. A disabled server can't be started + /// on demand or administratively. The enable state of the server + /// is not persistent: if the node is shut down and restarted, the + /// server will be enabled by default. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter enabled: `Swift.Bool` True to enable the server, false to disable it. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func enableServer(id: Swift.String, enabled: Swift.Bool, current: Ice.Current) throws + + /// Check if the server is enabled or disabled. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Bool` - True if the server is enabled. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func isServerEnabled(id: Swift.String, current: Ice.Current) throws -> Swift.Bool + + /// Start a server and wait for its activation. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func startServerAsync(id: Swift.String, current: Ice.Current) -> PromiseKit.Promise + + /// Stop a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func stopServerAsync(id: Swift.String, current: Ice.Current) -> PromiseKit.Promise + + /// Patch a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter shutdown: `Swift.Bool` If true, servers depending on the data to patch + /// will be shut down if necessary. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func patchServerAsync(id: Swift.String, shutdown: Swift.Bool, current: Ice.Current) -> PromiseKit.Promise + + /// Send signal to a server. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter signal: `Swift.String` The signal, for example SIGTERM or 15. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - BadSignalException - Raised if the signal is not recognized + /// by the target server. + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func sendSignal(id: Swift.String, signal: Swift.String, current: Ice.Current) throws + + /// Get all the server ids registered with IceGrid. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The server ids. + func getAllServerIds(current: Ice.Current) throws -> Ice.StringSeq + + /// Get the adapter information for the replica group or adapter + /// with the given id. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `AdapterInfoSeq` - A sequence of adapter information structures. If the + /// given id refers to an adapter, this sequence will contain only + /// one element. If the given id refers to a replica group, the + /// sequence will contain the adapter information of each member of + /// the replica group. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter or + /// replica group doesn't exist. + func getAdapterInfo(id: Swift.String, current: Ice.Current) throws -> AdapterInfoSeq + + /// Remove the adapter with the given id. + /// + /// - parameter id: `Swift.String` The adapter id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't + /// exist. + /// + /// - DeploymentException - Raised if application deployment failed. + func removeAdapter(id: Swift.String, current: Ice.Current) throws + + /// Get all the adapter ids registered with IceGrid. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The adapter ids. + func getAllAdapterIds(current: Ice.Current) throws -> Ice.StringSeq + + /// Add an object to the object registry. IceGrid will get the + /// object type by calling ice_id on the given proxy. The object + /// must be reachable. + /// + /// - parameter obj: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// added. This might be raised if the invocation on the proxy to + /// get the object type failed. + /// + /// - ObjectExistsException - Raised if the object is already + /// registered. + func addObject(obj: Ice.ObjectPrx?, current: Ice.Current) throws + + /// Update an object in the object registry. Only objects added + /// with this interface can be updated with this operation. Objects + /// added with deployment descriptors should be updated with the + /// deployment mechanism. + /// + /// - parameter obj: `Ice.ObjectPrx?` The object to be updated to the registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// updated. This might happen if the object was added with a + /// deployment descriptor. + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func updateObject(obj: Ice.ObjectPrx?, current: Ice.Current) throws + + /// Add an object to the object registry and explicitly specify + /// its type. + /// + /// - parameter obj: `Ice.ObjectPrx?` The object to be added to the registry. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - DeploymentException - Raised if application deployment failed. + /// + /// - ObjectExistsException - Raised if the object is already + /// registered. + func addObjectWithType(obj: Ice.ObjectPrx?, type: Swift.String, current: Ice.Current) throws + + /// Remove an object from the object registry. Only objects added + /// with this interface can be removed with this operation. Objects + /// added with deployment descriptors should be removed with the + /// deployment mechanism. + /// + /// - parameter id: `Ice.Identity` The identity of the object to be removed from the + /// registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the object can't be + /// removed. This might happen if the object was added with a + /// deployment descriptor. + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func removeObject(id: Ice.Identity, current: Ice.Current) throws + + /// Get the object info for the object with the given identity. + /// + /// - parameter id: `Ice.Identity` The identity of the object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ObjectInfo` - The object info. + /// + /// - throws: + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func getObjectInfo(id: Ice.Identity, current: Ice.Current) throws -> ObjectInfo + + /// Get the object info of all the registered objects with the + /// given type. + /// + /// - parameter type: `Swift.String` The type of the object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ObjectInfoSeq` - The object infos. + func getObjectInfosByType(type: Swift.String, current: Ice.Current) throws -> ObjectInfoSeq + + /// Get the object info of all the registered objects whose stringified + /// identities match the given expression. + /// + /// - parameter expr: `Swift.String` The expression to match against the stringified + /// identities of registered objects. The expression may contain + /// a trailing wildcard (*) character. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ObjectInfoSeq` - All the object infos with a stringified identity + /// matching the given expression. + func getAllObjectInfos(expr: Swift.String, current: Ice.Current) throws -> ObjectInfoSeq + + /// Ping an IceGrid node to see if it is active. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Bool` - true if the node ping succeeded, false otherwise. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + func pingNode(name: Swift.String, current: Ice.Current) throws -> Swift.Bool + + /// Get the load averages of the node. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `LoadInfo` - The node load information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeLoad(name: Swift.String, current: Ice.Current) throws -> LoadInfo + + /// Get the node information for the node with the given name. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `NodeInfo` - The node information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeInfo(name: Swift.String, current: Ice.Current) throws -> NodeInfo + + /// Get a proxy to the IceGrid node's admin object. + /// + /// - parameter name: `Swift.String` The IceGrid node name + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the IceGrid node's admin object + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeAdmin(name: Swift.String, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Get the number of physical processor sockets for the machine + /// running the node with the given name. + /// + /// Note that this method will return 1 on operating systems where + /// this can't be automatically determined and where the + /// IceGrid.Node.ProcessorSocketCount property for the node is not + /// set. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The number of processor sockets or 1 if the number of + /// sockets can't determined. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeProcessorSocketCount(name: Swift.String, current: Ice.Current) throws -> Swift.Int32 + + /// Shutdown an IceGrid node. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func shutdownNode(name: Swift.String, current: Ice.Current) throws + + /// Get the hostname of this node. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The node hostname. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeHostname(name: Swift.String, current: Ice.Current) throws -> Swift.String + + /// Get all the IceGrid nodes currently registered. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The node names. + func getAllNodeNames(current: Ice.Current) throws -> Ice.StringSeq + + /// Ping an IceGrid registry to see if it is active. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Bool` - true if the registry ping succeeded, false otherwise. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + func pingRegistry(name: Swift.String, current: Ice.Current) throws -> Swift.Bool + + /// Get the registry information for the registry with the given name. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `RegistryInfo` - The registry information. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry could not be + /// reached. + func getRegistryInfo(name: Swift.String, current: Ice.Current) throws -> RegistryInfo + + /// Get a proxy to the IceGrid registry's admin object. + /// + /// - parameter name: `Swift.String` The registry name + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to the IceGrid registry's admin object + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + func getRegistryAdmin(name: Swift.String, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Shutdown an IceGrid registry. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - RegistryNotExistException - Raised if the registry doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry could not be + /// reached. + func shutdownRegistry(name: Swift.String, current: Ice.Current) throws + + /// Get all the IceGrid registries currently registered. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.StringSeq` - The registry names. + func getAllRegistryNames(current: Ice.Current) throws -> Ice.StringSeq + + /// Shut down the IceGrid registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func shutdown(current: Ice.Current) throws + + /// Returns the checksums for the IceGrid Slice definitions. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.SliceChecksumDict` - A dictionary mapping Slice type ids to their checksums. + func getSliceChecksums(current: Ice.Current) throws -> Ice.SliceChecksumDict +} + + +/// Dispatcher for `FileIterator` servants. +public struct FileIteratorDisp: Ice.Disp { + public let servant: FileIterator + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: FileIterator) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? FileIteratorDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? FileIteratorDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? FileIteratorDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? FileIteratorDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "read": + return try servant._iceD_read(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This interface provides access to IceGrid log file contents. +public protocol FileIterator { + /// Read lines from the log file. + /// + /// - parameter size: `Swift.Int32` Specifies the maximum number of bytes to be + /// received. The server will ensure that the returned message + /// doesn't exceed the given size. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `(returnValue: Swift.Bool, lines: Ice.StringSeq)`: + /// + /// - returnValue: `Swift.Bool` - True if EOF is encountered. + /// + /// - lines: `Ice.StringSeq` - The lines read from the file. If there was nothing to + /// read from the file since the last call to read, an empty + /// sequence is returned. The last line of the sequence is always + /// incomplete (and therefore no '\n' should be added when writing + /// the last line to the to the output device). + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if there was a problem + /// to read lines from the file. + func read(size: Swift.Int32, current: Ice.Current) throws -> (returnValue: Swift.Bool, lines: Ice.StringSeq) + + /// Destroy the iterator. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func destroy(current: Ice.Current) throws +} + + +/// Dispatcher for `RegistryObserver` servants. +public struct RegistryObserverDisp: Ice.Disp { + public let servant: RegistryObserver + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: RegistryObserver) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? RegistryObserverDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RegistryObserverDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RegistryObserverDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RegistryObserverDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "registryDown": + return try servant._iceD_registryDown(incoming: request, current: current) + case "registryInit": + return try servant._iceD_registryInit(incoming: request, current: current) + case "registryUp": + return try servant._iceD_registryUp(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This interface allows applications to monitor changes the state +/// of the registry. +public protocol RegistryObserver { + /// The registryInit operation is called after registration of + /// an observer to indicate the state of the registries. + /// + /// - parameter registries: `RegistryInfoSeq` The current state of the registries. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func registryInit(registries: RegistryInfoSeq, current: Ice.Current) throws + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter node: `RegistryInfo` The node state. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func registryUp(node: RegistryInfo, current: Ice.Current) throws + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func registryDown(name: Swift.String, current: Ice.Current) throws +} + + +/// Dispatcher for `NodeObserver` servants. +public struct NodeObserverDisp: Ice.Disp { + public let servant: NodeObserver + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: NodeObserver) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? NodeObserverDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? NodeObserverDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? NodeObserverDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? NodeObserverDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "nodeDown": + return try servant._iceD_nodeDown(incoming: request, current: current) + case "nodeInit": + return try servant._iceD_nodeInit(incoming: request, current: current) + case "nodeUp": + return try servant._iceD_nodeUp(incoming: request, current: current) + case "updateAdapter": + return try servant._iceD_updateAdapter(incoming: request, current: current) + case "updateServer": + return try servant._iceD_updateServer(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The node observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// nodes. +public protocol NodeObserver { + /// The nodeInit operation indicates the current state + /// of nodes. It is called after the registration of an observer. + /// + /// - parameter nodes: `NodeDynamicInfoSeq` The current state of the nodes. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func nodeInit(nodes: NodeDynamicInfoSeq, current: Ice.Current) throws + + /// The nodeUp operation is called to notify an observer that a node + /// came up. + /// + /// - parameter node: `NodeDynamicInfo` The node state. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func nodeUp(node: NodeDynamicInfo, current: Ice.Current) throws + + /// The nodeDown operation is called to notify an observer that a node + /// went down. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func nodeDown(name: Swift.String, current: Ice.Current) throws + + /// The updateServer operation is called to notify an observer that + /// the state of a server changed. + /// + /// - parameter node: `Swift.String` The node hosting the server. + /// + /// - parameter updatedInfo: `ServerDynamicInfo` The new server state. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func updateServer(node: Swift.String, updatedInfo: ServerDynamicInfo, current: Ice.Current) throws + + /// The updateAdapter operation is called to notify an observer that + /// the state of an adapter changed. + /// + /// - parameter node: `Swift.String` The node hosting the adapter. + /// + /// - parameter updatedInfo: `AdapterDynamicInfo` The new adapter state. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func updateAdapter(node: Swift.String, updatedInfo: AdapterDynamicInfo, current: Ice.Current) throws +} + + +/// Dispatcher for `ApplicationObserver` servants. +public struct ApplicationObserverDisp: Ice.Disp { + public let servant: ApplicationObserver + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: ApplicationObserver) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "applicationAdded": + return try servant._iceD_applicationAdded(incoming: request, current: current) + case "applicationInit": + return try servant._iceD_applicationInit(incoming: request, current: current) + case "applicationRemoved": + return try servant._iceD_applicationRemoved(incoming: request, current: current) + case "applicationUpdated": + return try servant._iceD_applicationUpdated(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? ApplicationObserverDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? ApplicationObserverDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? ApplicationObserverDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? ApplicationObserverDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The database observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// registry database. +public protocol ApplicationObserver { + /// applicationInit is called after the registration + /// of an observer to indicate the state of the registry. + /// + /// - parameter serial: `Swift.Int32` The current serial number of the registry + /// database. This serial number allows observers to make sure that + /// their internal state is synchronized with the registry. + /// + /// - parameter applications: `ApplicationInfoSeq` The applications currently registered with + /// the registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func applicationInit(serial: Swift.Int32, applications: ApplicationInfoSeq, current: Ice.Current) throws + + /// The applicationAdded operation is called to notify an observer + /// that an application was added. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationInfo` The descriptor of the new application. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func applicationAdded(serial: Swift.Int32, desc: ApplicationInfo, current: Ice.Current) throws + + /// The applicationRemoved operation is called to notify an observer + /// that an application was removed. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter name: `Swift.String` The name of the application that was removed. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func applicationRemoved(serial: Swift.Int32, name: Swift.String, current: Ice.Current) throws + + /// The applicationUpdated operation is called to notify an observer + /// that an application was updated. + /// + /// - parameter serial: `Swift.Int32` The new serial number of the registry database. + /// + /// - parameter desc: `ApplicationUpdateInfo` The descriptor of the update. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func applicationUpdated(serial: Swift.Int32, desc: ApplicationUpdateInfo, current: Ice.Current) throws +} + + +/// Dispatcher for `AdapterObserver` servants. +public struct AdapterObserverDisp: Ice.Disp { + public let servant: AdapterObserver + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: AdapterObserver) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "adapterAdded": + return try servant._iceD_adapterAdded(incoming: request, current: current) + case "adapterInit": + return try servant._iceD_adapterInit(incoming: request, current: current) + case "adapterRemoved": + return try servant._iceD_adapterRemoved(incoming: request, current: current) + case "adapterUpdated": + return try servant._iceD_adapterUpdated(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? AdapterObserverDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? AdapterObserverDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? AdapterObserverDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? AdapterObserverDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This interface allows applications to monitor the state of object +/// adapters that are registered with IceGrid. +public protocol AdapterObserver { + /// adapterInit is called after registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter adpts: `AdapterInfoSeq` The adapters that were dynamically registered + /// with the registry (not through the deployment mechanism). + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func adapterInit(adpts: AdapterInfoSeq, current: Ice.Current) throws + + /// The adapterAdded operation is called to notify an observer when + /// a dynamically-registered adapter was added. + /// + /// - parameter info: `AdapterInfo` The details of the new adapter. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func adapterAdded(info: AdapterInfo, current: Ice.Current) throws + + /// The adapterUpdated operation is called to notify an observer when + /// a dynamically-registered adapter was updated. + /// + /// - parameter info: `AdapterInfo` The details of the updated adapter. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func adapterUpdated(info: AdapterInfo, current: Ice.Current) throws + + /// The adapterRemoved operation is called to notify an observer when + /// a dynamically-registered adapter was removed. + /// + /// - parameter id: `Swift.String` The ID of the removed adapter. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func adapterRemoved(id: Swift.String, current: Ice.Current) throws +} + + +/// Dispatcher for `ObjectObserver` servants. +public struct ObjectObserverDisp: Ice.Disp { + public let servant: ObjectObserver + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: ObjectObserver) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? ObjectObserverDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? ObjectObserverDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? ObjectObserverDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? ObjectObserverDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "objectAdded": + return try servant._iceD_objectAdded(incoming: request, current: current) + case "objectInit": + return try servant._iceD_objectInit(incoming: request, current: current) + case "objectRemoved": + return try servant._iceD_objectRemoved(incoming: request, current: current) + case "objectUpdated": + return try servant._iceD_objectUpdated(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This interface allows applications to monitor IceGrid well-known objects. +public protocol ObjectObserver { + /// objectInit is called after the registration of + /// an observer to indicate the state of the registry. + /// + /// - parameter objects: `ObjectInfoSeq` The objects registered with the Admin + /// interface (not through the deployment mechanism). + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func objectInit(objects: ObjectInfoSeq, current: Ice.Current) throws + + /// The objectAdded operation is called to notify an observer when an + /// object was added to the Admin interface. + /// + /// - parameter info: `ObjectInfo` The details of the added object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func objectAdded(info: ObjectInfo, current: Ice.Current) throws + + /// objectUpdated is called to notify an observer when + /// an object registered with the Admin interface was updated. + /// + /// - parameter info: `ObjectInfo` The details of the updated object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func objectUpdated(info: ObjectInfo, current: Ice.Current) throws + + /// objectRemoved is called to notify an observer when + /// an object registered with the Admin interface was removed. + /// + /// - parameter id: `Ice.Identity` The identity of the removed object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func objectRemoved(id: Ice.Identity, current: Ice.Current) throws +} + + +/// Dispatcher for `AdminSession` servants. +public struct AdminSessionDisp: Ice.Disp { + public let servant: AdminSession + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: AdminSession) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "finishUpdate": + return try servant._iceD_finishUpdate(incoming: request, current: current) + case "getAdmin": + return try servant._iceD_getAdmin(incoming: request, current: current) + case "getAdminCallbackTemplate": + return try servant._iceD_getAdminCallbackTemplate(incoming: request, current: current) + case "getReplicaName": + return try servant._iceD_getReplicaName(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? AdminSessionDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? AdminSessionDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? AdminSessionDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? AdminSessionDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "keepAlive": + return try servant._iceD_keepAlive(incoming: request, current: current) + case "openNodeStdErr": + return try servant._iceD_openNodeStdErr(incoming: request, current: current) + case "openNodeStdOut": + return try servant._iceD_openNodeStdOut(incoming: request, current: current) + case "openRegistryStdErr": + return try servant._iceD_openRegistryStdErr(incoming: request, current: current) + case "openRegistryStdOut": + return try servant._iceD_openRegistryStdOut(incoming: request, current: current) + case "openServerLog": + return try servant._iceD_openServerLog(incoming: request, current: current) + case "openServerStdErr": + return try servant._iceD_openServerStdErr(incoming: request, current: current) + case "openServerStdOut": + return try servant._iceD_openServerStdOut(incoming: request, current: current) + case "setObservers": + return try servant._iceD_setObservers(incoming: request, current: current) + case "setObserversByIdentity": + return try servant._iceD_setObserversByIdentity(incoming: request, current: current) + case "startUpdate": + return try servant._iceD_startUpdate(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// Used by administrative clients to view, +/// update, and receive observer updates from the IceGrid +/// registry. Admin sessions are created either via the Registry +/// object or via the registry admin SessionManager object. +public protocol AdminSession: Glacier2.Session { + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func keepAlive(current: Ice.Current) throws + + /// Get the admin interface. The admin object returned by this + /// operation can only be accessed by the session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `AdminPrx?` - The admin interface proxy. + func getAdmin(current: Ice.Current) throws -> AdminPrx? + + /// Get a "template" proxy for admin callback objects. + /// An Admin client uses this proxy to set the category of its callback + /// objects, and the published endpoints of the object adapter hosting + /// the admin callback objects. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A template proxy. The returned proxy is null when the Admin + /// session was established using Glacier2. + func getAdminCallbackTemplate(current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Set the observer proxies that receive + /// notifications when the state of the registry + /// or nodes changes. + /// + /// - parameter registryObs: `RegistryObserverPrx?` The registry observer. + /// + /// - parameter nodeObs: `NodeObserverPrx?` The node observer. + /// + /// - parameter appObs: `ApplicationObserverPrx?` The application observer. + /// + /// - parameter adptObs: `AdapterObserverPrx?` The adapter observer. + /// + /// - parameter objObs: `ObjectObserverPrx?` The object observer. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - ObserverAlreadyRegisteredException - Raised if an + /// observer is already registered with this registry. + func setObservers(registryObs: RegistryObserverPrx?, nodeObs: NodeObserverPrx?, appObs: ApplicationObserverPrx?, adptObs: AdapterObserverPrx?, objObs: ObjectObserverPrx?, current: Ice.Current) throws + + /// Set the observer identities that receive + /// notifications the state of the registry + /// or nodes changes. This operation should be used by clients that + /// are using a bidirectional connection to communicate with the + /// session. + /// + /// - parameter registryObs: `Ice.Identity` The registry observer identity. + /// + /// - parameter nodeObs: `Ice.Identity` The node observer identity. + /// + /// - parameter appObs: `Ice.Identity` The application observer. + /// + /// - parameter adptObs: `Ice.Identity` The adapter observer. + /// + /// - parameter objObs: `Ice.Identity` The object observer. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - ObserverAlreadyRegisteredException - Raised if an + /// observer is already registered with this registry. + func setObserversByIdentity(registryObs: Ice.Identity, nodeObs: Ice.Identity, appObs: Ice.Identity, adptObs: Ice.Identity, objObs: Ice.Identity, current: Ice.Current) throws + + /// Acquires an exclusive lock to start updating the registry applications. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The current serial. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the exclusive lock can't be + /// acquired. This might happen if the lock is currently acquired by + /// another session. + func startUpdate(current: Ice.Current) throws -> Swift.Int32 + + /// Finish updating the registry and release the exclusive lock. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AccessDeniedException - Raised if the session doesn't hold the + /// exclusive lock. + func finishUpdate(current: Ice.Current) throws + + /// Get the name of the registry replica hosting this session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The replica name of the registry. + func getReplicaName(current: Ice.Current) throws -> Swift.String + + /// Open the given server log file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter path: `Swift.String` The path of the log file. A log file can be opened + /// only if it's declared in the server or service deployment + /// descriptor. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerLog(id: Swift.String, path: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given server stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerStdErr(id: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given server stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter id: `Swift.String` The server id. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - DeploymentException - Raised if the server couldn't be + /// deployed on the node. + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + /// + /// - ServerNotExistException - Raised if the server doesn't + /// exist. + func openServerStdOut(id: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given node stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + func openNodeStdErr(name: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given node stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The node name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not + /// be reached. + func openNodeStdOut(name: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given registry stderr file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - RegistryNotExistException - Raised if the registry + /// doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry + /// could not be reached. + func openRegistryStdErr(name: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? + + /// Open the given registry stdout file for reading. The file can be + /// read with the returned file iterator. + /// + /// - parameter name: `Swift.String` The registry name. + /// + /// - parameter count: `Swift.Int32` Specifies where to start reading the file. If + /// negative, the file is read from the begining. If 0 or positive, + /// the file is read from the last count lines. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `FileIteratorPrx?` - An iterator to read the file. + /// + /// - throws: + /// + /// - FileNotAvailableException - Raised if the file can't be + /// read. + /// + /// - RegistryNotExistException - Raised if the registry + /// doesn't exist. + /// + /// - RegistryUnreachableException - Raised if the registry + /// could not be reached. + func openRegistryStdOut(name: Swift.String, count: Swift.Int32, current: Ice.Current) throws -> FileIteratorPrx? +} + +/// The IceGrid administrative interface. +/// Allowing access to this interface +/// is a security risk! Please see the IceGrid documentation +/// for further information. +/// +/// Admin Methods: +/// +/// - addApplication: Add an application to IceGrid. +/// +/// - syncApplication: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplication: Update a deployed application with the given update application descriptor. +/// +/// - syncApplicationWithoutRestart: Synchronize a deployed application with the given application descriptor. +/// +/// - updateApplicationWithoutRestart: Update a deployed application with the given update application descriptor only if no server restarts are necessary for the update of the application. +/// +/// - removeApplication: Remove an application from IceGrid. +/// +/// - instantiateServer: Instantiate a server template from an application on the given node. +/// +/// - patchApplication: Patch the given application data. +/// +/// - getApplicationInfo: Get an application descriptor. +/// +/// - getDefaultApplicationDescriptor: Get the default application descriptor. +/// +/// - getAllApplicationNames: Get all the IceGrid applications currently registered. +/// +/// - getServerInfo: Get the server information for the server with the given id. +/// +/// - getServerState: Get a server's state. +/// +/// - getServerPid: Get a server's system process id. +/// +/// - getServerAdminCategory: Get the category for server admin objects. +/// +/// - getServerAdmin: Get a proxy to the server's admin object. +/// +/// - enableServer: Enable or disable a server. +/// +/// - isServerEnabled: Check if the server is enabled or disabled. +/// +/// - startServer: Start a server and wait for its activation. +/// +/// - stopServer: Stop a server. +/// +/// - patchServer: Patch a server. +/// +/// - sendSignal: Send signal to a server. +/// +/// - getAllServerIds: Get all the server ids registered with IceGrid. +/// +/// - getAdapterInfo: Get the adapter information for the replica group or adapter with the given id. +/// +/// - removeAdapter: Remove the adapter with the given id. +/// +/// - getAllAdapterIds: Get all the adapter ids registered with IceGrid. +/// +/// - addObject: Add an object to the object registry. +/// +/// - updateObject: Update an object in the object registry. +/// +/// - addObjectWithType: Add an object to the object registry and explicitly specify its type. +/// +/// - removeObject: Remove an object from the object registry. +/// +/// - getObjectInfo: Get the object info for the object with the given identity. +/// +/// - getObjectInfosByType: Get the object info of all the registered objects with the given type. +/// +/// - getAllObjectInfos: Get the object info of all the registered objects whose stringified identities match the given expression. +/// +/// - pingNode: Ping an IceGrid node to see if it is active. +/// +/// - getNodeLoad: Get the load averages of the node. +/// +/// - getNodeInfo: Get the node information for the node with the given name. +/// +/// - getNodeAdmin: Get a proxy to the IceGrid node's admin object. +/// +/// - getNodeProcessorSocketCount: Get the number of physical processor sockets for the machine running the node with the given name. +/// +/// - shutdownNode: Shutdown an IceGrid node. +/// +/// - getNodeHostname: Get the hostname of this node. +/// +/// - getAllNodeNames: Get all the IceGrid nodes currently registered. +/// +/// - pingRegistry: Ping an IceGrid registry to see if it is active. +/// +/// - getRegistryInfo: Get the registry information for the registry with the given name. +/// +/// - getRegistryAdmin: Get a proxy to the IceGrid registry's admin object. +/// +/// - shutdownRegistry: Shutdown an IceGrid registry. +/// +/// - getAllRegistryNames: Get all the IceGrid registries currently registered. +/// +/// - shutdown: Shut down the IceGrid registry. +/// +/// - getSliceChecksums: Returns the checksums for the IceGrid Slice definitions. +public extension Admin { + func _iceD_addApplication(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_descriptor: ApplicationDescriptor = try inS.read { istr in + let iceP_descriptor: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_descriptor + } + + try self.addApplication(descriptor: iceP_descriptor, current: current) + + return inS.setResult() + } + + func _iceD_syncApplication(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_descriptor: ApplicationDescriptor = try inS.read { istr in + let iceP_descriptor: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_descriptor + } + + try self.syncApplication(descriptor: iceP_descriptor, current: current) + + return inS.setResult() + } + + func _iceD_updateApplication(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_descriptor: ApplicationUpdateDescriptor = try inS.read { istr in + let iceP_descriptor: ApplicationUpdateDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_descriptor + } + + try self.updateApplication(descriptor: iceP_descriptor, current: current) + + return inS.setResult() + } + + func _iceD_syncApplicationWithoutRestart(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_descriptor: ApplicationDescriptor = try inS.read { istr in + let iceP_descriptor: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_descriptor + } + + try self.syncApplicationWithoutRestart(descriptor: iceP_descriptor, current: current) + + return inS.setResult() + } + + func _iceD_updateApplicationWithoutRestart(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_descriptor: ApplicationUpdateDescriptor = try inS.read { istr in + let iceP_descriptor: ApplicationUpdateDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_descriptor + } + + try self.updateApplicationWithoutRestart(descriptor: iceP_descriptor, current: current) + + return inS.setResult() + } + + func _iceD_removeApplication(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + try self.removeApplication(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_instantiateServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_application, iceP_node, iceP_desc): (Swift.String, Swift.String, ServerInstanceDescriptor) = try inS.read { istr in + let iceP_application: Swift.String = try istr.read() + let iceP_node: Swift.String = try istr.read() + let iceP_desc: ServerInstanceDescriptor = try istr.read() + return (iceP_application, iceP_node, iceP_desc) + } + + try self.instantiateServer(application: iceP_application, node: iceP_node, desc: iceP_desc, current: current) + + return inS.setResult() + } + + func _iceD_patchApplication(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_name, iceP_shutdown): (Swift.String, Swift.Bool) = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + let iceP_shutdown: Swift.Bool = try istr.read() + return (iceP_name, iceP_shutdown) + } + + return inS.setResultPromise(patchApplicationAsync(name: iceP_name, shutdown: iceP_shutdown, current: current)) + } + + func _iceD_getApplicationInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getApplicationInfo(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + ostr.writePendingValues() + } + } + + func _iceD_getDefaultApplicationDescriptor(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getDefaultApplicationDescriptor(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + ostr.writePendingValues() + } + } + + func _iceD_getAllApplicationNames(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAllApplicationNames(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getServerInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getServerInfo(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + ostr.writePendingValues() + } + } + + func _iceD_getServerState(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getServerState(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getServerPid(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getServerPid(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getServerAdminCategory(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getServerAdminCategory(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getServerAdmin(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getServerAdmin(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_enableServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_enabled): (Swift.String, Swift.Bool) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_enabled: Swift.Bool = try istr.read() + return (iceP_id, iceP_enabled) + } + + try self.enableServer(id: iceP_id, enabled: iceP_enabled, current: current) + + return inS.setResult() + } + + func _iceD_isServerEnabled(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.isServerEnabled(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_startServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + return inS.setResultPromise(startServerAsync(id: iceP_id, current: current)) + } + + func _iceD_stopServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + return inS.setResultPromise(stopServerAsync(id: iceP_id, current: current)) + } + + func _iceD_patchServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_shutdown): (Swift.String, Swift.Bool) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_shutdown: Swift.Bool = try istr.read() + return (iceP_id, iceP_shutdown) + } + + return inS.setResultPromise(patchServerAsync(id: iceP_id, shutdown: iceP_shutdown, current: current)) + } + + func _iceD_sendSignal(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_signal): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_signal: Swift.String = try istr.read() + return (iceP_id, iceP_signal) + } + + try self.sendSignal(id: iceP_id, signal: iceP_signal, current: current) + + return inS.setResult() + } + + func _iceD_getAllServerIds(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAllServerIds(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getAdapterInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getAdapterInfo(id: iceP_id, current: current) + + return inS.setResult{ ostr in + AdapterInfoSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_removeAdapter(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + try self.removeAdapter(id: iceP_id, current: current) + + return inS.setResult() + } + + func _iceD_getAllAdapterIds(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAllAdapterIds(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_addObject(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_obj: Ice.ObjectPrx? = try inS.read { istr in + let iceP_obj: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_obj + } + + try self.addObject(obj: iceP_obj, current: current) + + return inS.setResult() + } + + func _iceD_updateObject(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_obj: Ice.ObjectPrx? = try inS.read { istr in + let iceP_obj: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_obj + } + + try self.updateObject(obj: iceP_obj, current: current) + + return inS.setResult() + } + + func _iceD_addObjectWithType(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_obj, iceP_type): (Ice.ObjectPrx?, Swift.String) = try inS.read { istr in + let iceP_obj: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + let iceP_type: Swift.String = try istr.read() + return (iceP_obj, iceP_type) + } + + try self.addObjectWithType(obj: iceP_obj, type: iceP_type, current: current) + + return inS.setResult() + } + + func _iceD_removeObject(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + try self.removeObject(id: iceP_id, current: current) + + return inS.setResult() + } + + func _iceD_getObjectInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.getObjectInfo(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getObjectInfosByType(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_type: Swift.String = try inS.read { istr in + let iceP_type: Swift.String = try istr.read() + return iceP_type + } + + let iceP_returnValue = try self.getObjectInfosByType(type: iceP_type, current: current) + + return inS.setResult{ ostr in + ObjectInfoSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_getAllObjectInfos(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_expr: Swift.String = try inS.read { istr in + let iceP_expr: Swift.String = try istr.read() + return iceP_expr + } + + let iceP_returnValue = try self.getAllObjectInfos(expr: iceP_expr, current: current) + + return inS.setResult{ ostr in + ObjectInfoSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_pingNode(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.pingNode(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getNodeLoad(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getNodeLoad(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getNodeInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getNodeInfo(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getNodeAdmin(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getNodeAdmin(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getNodeProcessorSocketCount(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getNodeProcessorSocketCount(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_shutdownNode(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + try self.shutdownNode(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_getNodeHostname(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getNodeHostname(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getAllNodeNames(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAllNodeNames(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_pingRegistry(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.pingRegistry(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getRegistryInfo(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getRegistryInfo(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getRegistryAdmin(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.getRegistryAdmin(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_shutdownRegistry(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + try self.shutdownRegistry(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_getAllRegistryNames(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAllRegistryNames(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_shutdown(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.shutdown(current: current) + + return inS.setResult() + } + + func _iceD_getSliceChecksums(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSliceChecksums(current: current) + + return inS.setResult{ ostr in + Ice.SliceChecksumDictHelper.write(to: ostr, value: iceP_returnValue) + } + } +} + +/// This interface provides access to IceGrid log file contents. +/// +/// FileIterator Methods: +/// +/// - read: Read lines from the log file. +/// +/// - destroy: Destroy the iterator. +public extension FileIterator { + func _iceD_read(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_size: Swift.Int32 = try inS.read { istr in + let iceP_size: Swift.Int32 = try istr.read() + return iceP_size + } + + let (iceP_returnValue, iceP_lines) = try self.read(size: iceP_size, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_lines) + ostr.write(iceP_returnValue) + } + } + + func _iceD_destroy(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.destroy(current: current) + + return inS.setResult() + } +} + +/// This interface allows applications to monitor changes the state +/// of the registry. +/// +/// RegistryObserver Methods: +/// +/// - registryInit: The registryInit operation is called after registration of an observer to indicate the state of the registries. +/// +/// - registryUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - registryDown: The nodeDown operation is called to notify an observer that a node went down. +public extension RegistryObserver { + func _iceD_registryInit(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_registries: RegistryInfoSeq = try inS.read { istr in + let iceP_registries: RegistryInfoSeq = try RegistryInfoSeqHelper.read(from: istr) + return iceP_registries + } + + try self.registryInit(registries: iceP_registries, current: current) + + return inS.setResult() + } + + func _iceD_registryUp(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_node: RegistryInfo = try inS.read { istr in + let iceP_node: RegistryInfo = try istr.read() + return iceP_node + } + + try self.registryUp(node: iceP_node, current: current) + + return inS.setResult() + } + + func _iceD_registryDown(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + try self.registryDown(name: iceP_name, current: current) + + return inS.setResult() + } +} + +/// The node observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// nodes. +/// +/// NodeObserver Methods: +/// +/// - nodeInit: The nodeInit operation indicates the current state of nodes. +/// +/// - nodeUp: The nodeUp operation is called to notify an observer that a node came up. +/// +/// - nodeDown: The nodeDown operation is called to notify an observer that a node went down. +/// +/// - updateServer: The updateServer operation is called to notify an observer that the state of a server changed. +/// +/// - updateAdapter: The updateAdapter operation is called to notify an observer that the state of an adapter changed. +public extension NodeObserver { + func _iceD_nodeInit(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_nodes: NodeDynamicInfoSeq = try inS.read { istr in + let iceP_nodes: NodeDynamicInfoSeq = try NodeDynamicInfoSeqHelper.read(from: istr) + return iceP_nodes + } + + try self.nodeInit(nodes: iceP_nodes, current: current) + + return inS.setResult() + } + + func _iceD_nodeUp(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_node: NodeDynamicInfo = try inS.read { istr in + let iceP_node: NodeDynamicInfo = try istr.read() + return iceP_node + } + + try self.nodeUp(node: iceP_node, current: current) + + return inS.setResult() + } + + func _iceD_nodeDown(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + try self.nodeDown(name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_updateServer(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_node, iceP_updatedInfo): (Swift.String, ServerDynamicInfo) = try inS.read { istr in + let iceP_node: Swift.String = try istr.read() + let iceP_updatedInfo: ServerDynamicInfo = try istr.read() + return (iceP_node, iceP_updatedInfo) + } + + try self.updateServer(node: iceP_node, updatedInfo: iceP_updatedInfo, current: current) + + return inS.setResult() + } + + func _iceD_updateAdapter(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_node, iceP_updatedInfo): (Swift.String, AdapterDynamicInfo) = try inS.read { istr in + let iceP_node: Swift.String = try istr.read() + let iceP_updatedInfo: AdapterDynamicInfo = try istr.read() + return (iceP_node, iceP_updatedInfo) + } + + try self.updateAdapter(node: iceP_node, updatedInfo: iceP_updatedInfo, current: current) + + return inS.setResult() + } +} + +/// The database observer interface. Observers should implement this +/// interface to receive information about the state of the IceGrid +/// registry database. +/// +/// ApplicationObserver Methods: +/// +/// - applicationInit: applicationInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - applicationAdded: The applicationAdded operation is called to notify an observer that an application was added. +/// +/// - applicationRemoved: The applicationRemoved operation is called to notify an observer that an application was removed. +/// +/// - applicationUpdated: The applicationUpdated operation is called to notify an observer that an application was updated. +public extension ApplicationObserver { + func _iceD_applicationInit(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_serial, iceP_applications): (Swift.Int32, ApplicationInfoSeq) = try inS.read { istr in + let iceP_serial: Swift.Int32 = try istr.read() + let iceP_applications: ApplicationInfoSeq = try ApplicationInfoSeqHelper.read(from: istr) + try istr.readPendingValues() + return (iceP_serial, iceP_applications) + } + + try self.applicationInit(serial: iceP_serial, applications: iceP_applications, current: current) + + return inS.setResult() + } + + func _iceD_applicationAdded(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_serial, iceP_desc): (Swift.Int32, ApplicationInfo) = try inS.read { istr in + let iceP_serial: Swift.Int32 = try istr.read() + let iceP_desc: ApplicationInfo = try istr.read() + try istr.readPendingValues() + return (iceP_serial, iceP_desc) + } + + try self.applicationAdded(serial: iceP_serial, desc: iceP_desc, current: current) + + return inS.setResult() + } + + func _iceD_applicationRemoved(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_serial, iceP_name): (Swift.Int32, Swift.String) = try inS.read { istr in + let iceP_serial: Swift.Int32 = try istr.read() + let iceP_name: Swift.String = try istr.read() + return (iceP_serial, iceP_name) + } + + try self.applicationRemoved(serial: iceP_serial, name: iceP_name, current: current) + + return inS.setResult() + } + + func _iceD_applicationUpdated(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_serial, iceP_desc): (Swift.Int32, ApplicationUpdateInfo) = try inS.read { istr in + let iceP_serial: Swift.Int32 = try istr.read() + let iceP_desc: ApplicationUpdateInfo = try istr.read() + try istr.readPendingValues() + return (iceP_serial, iceP_desc) + } + + try self.applicationUpdated(serial: iceP_serial, desc: iceP_desc, current: current) + + return inS.setResult() + } +} + +/// This interface allows applications to monitor the state of object +/// adapters that are registered with IceGrid. +/// +/// AdapterObserver Methods: +/// +/// - adapterInit: adapterInit is called after registration of an observer to indicate the state of the registry. +/// +/// - adapterAdded: The adapterAdded operation is called to notify an observer when a dynamically-registered adapter was added. +/// +/// - adapterUpdated: The adapterUpdated operation is called to notify an observer when a dynamically-registered adapter was updated. +/// +/// - adapterRemoved: The adapterRemoved operation is called to notify an observer when a dynamically-registered adapter was removed. +public extension AdapterObserver { + func _iceD_adapterInit(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_adpts: AdapterInfoSeq = try inS.read { istr in + let iceP_adpts: AdapterInfoSeq = try AdapterInfoSeqHelper.read(from: istr) + return iceP_adpts + } + + try self.adapterInit(adpts: iceP_adpts, current: current) + + return inS.setResult() + } + + func _iceD_adapterAdded(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_info: AdapterInfo = try inS.read { istr in + let iceP_info: AdapterInfo = try istr.read() + return iceP_info + } + + try self.adapterAdded(info: iceP_info, current: current) + + return inS.setResult() + } + + func _iceD_adapterUpdated(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_info: AdapterInfo = try inS.read { istr in + let iceP_info: AdapterInfo = try istr.read() + return iceP_info + } + + try self.adapterUpdated(info: iceP_info, current: current) + + return inS.setResult() + } + + func _iceD_adapterRemoved(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Swift.String = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + return iceP_id + } + + try self.adapterRemoved(id: iceP_id, current: current) + + return inS.setResult() + } +} + +/// This interface allows applications to monitor IceGrid well-known objects. +/// +/// ObjectObserver Methods: +/// +/// - objectInit: objectInit is called after the registration of an observer to indicate the state of the registry. +/// +/// - objectAdded: The objectAdded operation is called to notify an observer when an object was added to the Admin interface. +/// +/// - objectUpdated: objectUpdated is called to notify an observer when an object registered with the Admin interface was updated. +/// +/// - objectRemoved: objectRemoved is called to notify an observer when an object registered with the Admin interface was removed. +public extension ObjectObserver { + func _iceD_objectInit(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_objects: ObjectInfoSeq = try inS.read { istr in + let iceP_objects: ObjectInfoSeq = try ObjectInfoSeqHelper.read(from: istr) + return iceP_objects + } + + try self.objectInit(objects: iceP_objects, current: current) + + return inS.setResult() + } + + func _iceD_objectAdded(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_info: ObjectInfo = try inS.read { istr in + let iceP_info: ObjectInfo = try istr.read() + return iceP_info + } + + try self.objectAdded(info: iceP_info, current: current) + + return inS.setResult() + } + + func _iceD_objectUpdated(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_info: ObjectInfo = try inS.read { istr in + let iceP_info: ObjectInfo = try istr.read() + return iceP_info + } + + try self.objectUpdated(info: iceP_info, current: current) + + return inS.setResult() + } + + func _iceD_objectRemoved(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + try self.objectRemoved(id: iceP_id, current: current) + + return inS.setResult() + } +} + +/// Used by administrative clients to view, +/// update, and receive observer updates from the IceGrid +/// registry. Admin sessions are created either via the Registry +/// object or via the registry admin SessionManager object. +/// +/// AdminSession Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - getAdmin: Get the admin interface. +/// +/// - getAdminCallbackTemplate: Get a "template" proxy for admin callback objects. +/// +/// - setObservers: Set the observer proxies that receive notifications when the state of the registry or nodes changes. +/// +/// - setObserversByIdentity: Set the observer identities that receive notifications the state of the registry or nodes changes. +/// +/// - startUpdate: Acquires an exclusive lock to start updating the registry applications. +/// +/// - finishUpdate: Finish updating the registry and release the exclusive lock. +/// +/// - getReplicaName: Get the name of the registry replica hosting this session. +/// +/// - openServerLog: Open the given server log file for reading. +/// +/// - openServerStdErr: Open the given server stderr file for reading. +/// +/// - openServerStdOut: Open the given server stdout file for reading. +/// +/// - openNodeStdErr: Open the given node stderr file for reading. +/// +/// - openNodeStdOut: Open the given node stdout file for reading. +/// +/// - openRegistryStdErr: Open the given registry stderr file for reading. +/// +/// - openRegistryStdOut: Open the given registry stdout file for reading. +public extension AdminSession { + func _iceD_keepAlive(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.keepAlive(current: current) + + return inS.setResult() + } + + func _iceD_getAdmin(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAdmin(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getAdminCallbackTemplate(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getAdminCallbackTemplate(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_setObservers(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_registryObs, iceP_nodeObs, iceP_appObs, iceP_adptObs, iceP_objObs): (RegistryObserverPrx?, NodeObserverPrx?, ApplicationObserverPrx?, AdapterObserverPrx?, ObjectObserverPrx?) = try inS.read { istr in + let iceP_registryObs: RegistryObserverPrx? = try istr.read(RegistryObserverPrx.self) + let iceP_nodeObs: NodeObserverPrx? = try istr.read(NodeObserverPrx.self) + let iceP_appObs: ApplicationObserverPrx? = try istr.read(ApplicationObserverPrx.self) + let iceP_adptObs: AdapterObserverPrx? = try istr.read(AdapterObserverPrx.self) + let iceP_objObs: ObjectObserverPrx? = try istr.read(ObjectObserverPrx.self) + return (iceP_registryObs, iceP_nodeObs, iceP_appObs, iceP_adptObs, iceP_objObs) + } + + try self.setObservers(registryObs: iceP_registryObs, nodeObs: iceP_nodeObs, appObs: iceP_appObs, adptObs: iceP_adptObs, objObs: iceP_objObs, current: current) + + return inS.setResult() + } + + func _iceD_setObserversByIdentity(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_registryObs, iceP_nodeObs, iceP_appObs, iceP_adptObs, iceP_objObs): (Ice.Identity, Ice.Identity, Ice.Identity, Ice.Identity, Ice.Identity) = try inS.read { istr in + let iceP_registryObs: Ice.Identity = try istr.read() + let iceP_nodeObs: Ice.Identity = try istr.read() + let iceP_appObs: Ice.Identity = try istr.read() + let iceP_adptObs: Ice.Identity = try istr.read() + let iceP_objObs: Ice.Identity = try istr.read() + return (iceP_registryObs, iceP_nodeObs, iceP_appObs, iceP_adptObs, iceP_objObs) + } + + try self.setObserversByIdentity(registryObs: iceP_registryObs, nodeObs: iceP_nodeObs, appObs: iceP_appObs, adptObs: iceP_adptObs, objObs: iceP_objObs, current: current) + + return inS.setResult() + } + + func _iceD_startUpdate(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.startUpdate(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_finishUpdate(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.finishUpdate(current: current) + + return inS.setResult() + } + + func _iceD_getReplicaName(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getReplicaName(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openServerLog(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_path, iceP_count): (Swift.String, Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_path: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_id, iceP_path, iceP_count) + } + + let iceP_returnValue = try self.openServerLog(id: iceP_id, path: iceP_path, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openServerStdErr(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_id, iceP_count) + } + + let iceP_returnValue = try self.openServerStdErr(id: iceP_id, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openServerStdOut(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_id, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_id: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_id, iceP_count) + } + + let iceP_returnValue = try self.openServerStdOut(id: iceP_id, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openNodeStdErr(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_name, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_name, iceP_count) + } + + let iceP_returnValue = try self.openNodeStdErr(name: iceP_name, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openNodeStdOut(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_name, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_name, iceP_count) + } + + let iceP_returnValue = try self.openNodeStdOut(name: iceP_name, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openRegistryStdErr(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_name, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_name, iceP_count) + } + + let iceP_returnValue = try self.openRegistryStdErr(name: iceP_name, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_openRegistryStdOut(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_name, iceP_count): (Swift.String, Swift.Int32) = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + let iceP_count: Swift.Int32 = try istr.read() + return (iceP_name, iceP_count) + } + + let iceP_returnValue = try self.openRegistryStdOut(name: iceP_name, count: iceP_count, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/IceGrid/Descriptor.swift b/Sources/IceGrid/Descriptor.swift new file mode 100644 index 0000000..f5a368a --- /dev/null +++ b/Sources/IceGrid/Descriptor.swift @@ -0,0 +1,2954 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Descriptor.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// A mapping of string to string. +public typealias StringStringDict = [Swift.String: Swift.String] + +/// Helper class to read and write `StringStringDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct StringStringDictHelper { + /// Read a `StringStringDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `StringStringDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> StringStringDict { + let sz = try Swift.Int(istr.readSize()) + var v = StringStringDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `StringStringDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `StringStringDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> StringStringDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `StringStringDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `StringStringDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: StringStringDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `StringStringDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `StringStringDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: StringStringDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Property descriptor. +public struct PropertyDescriptor: Swift.Hashable { + /// The name of the property. + public var name: Swift.String = "" + /// The value of the property. + public var value: Swift.String = "" + + public init() {} + + public init(name: Swift.String, value: Swift.String) { + self.name = name + self.value = value + } +} + +/// An `Ice.InputStream` extension to read `PropertyDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `PropertyDescriptor` structured value from the stream. + /// + /// - returns: `PropertyDescriptor` - The structured value read from the stream. + func read() throws -> PropertyDescriptor { + var v = PropertyDescriptor() + v.name = try self.read() + v.value = try self.read() + return v + } + + /// Read an optional `PropertyDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `PropertyDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> PropertyDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as PropertyDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `PropertyDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `PropertyDescriptor` structured value to the stream. + /// + /// - parameter _: `PropertyDescriptor` - The value to write to the stream. + func write(_ v: PropertyDescriptor) { + self.write(v.name) + self.write(v.value) + } + + /// Write an optional `PropertyDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `PropertyDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: PropertyDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of property descriptors. +public typealias PropertyDescriptorSeq = [PropertyDescriptor] + +/// Helper class to read and write `PropertyDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct PropertyDescriptorSeqHelper { + /// Read a `PropertyDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `PropertyDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> PropertyDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 2) + var v = PropertyDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: PropertyDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `PropertyDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `PropertyDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> PropertyDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `PropertyDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `PropertyDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: PropertyDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `PropertyDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `PropertyDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: PropertyDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A property set descriptor. +public struct PropertySetDescriptor: Swift.Hashable { + /// References to named property sets. + public var references: Ice.StringSeq = Ice.StringSeq() + /// The property set properties. + public var properties: PropertyDescriptorSeq = PropertyDescriptorSeq() + + public init() {} + + public init(references: Ice.StringSeq, properties: PropertyDescriptorSeq) { + self.references = references + self.properties = properties + } +} + +/// An `Ice.InputStream` extension to read `PropertySetDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `PropertySetDescriptor` structured value from the stream. + /// + /// - returns: `PropertySetDescriptor` - The structured value read from the stream. + func read() throws -> PropertySetDescriptor { + var v = PropertySetDescriptor() + v.references = try self.read() + v.properties = try PropertyDescriptorSeqHelper.read(from: self) + return v + } + + /// Read an optional `PropertySetDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `PropertySetDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> PropertySetDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as PropertySetDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `PropertySetDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `PropertySetDescriptor` structured value to the stream. + /// + /// - parameter _: `PropertySetDescriptor` - The value to write to the stream. + func write(_ v: PropertySetDescriptor) { + self.write(v.references) + PropertyDescriptorSeqHelper.write(to: self, value: v.properties) + } + + /// Write an optional `PropertySetDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `PropertySetDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: PropertySetDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A mapping of property set name to property set descriptor. +public typealias PropertySetDescriptorDict = [Swift.String: PropertySetDescriptor] + +/// Helper class to read and write `PropertySetDescriptorDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct PropertySetDescriptorDictHelper { + /// Read a `PropertySetDescriptorDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `PropertySetDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> PropertySetDescriptorDict { + let sz = try Swift.Int(istr.readSize()) + var v = PropertySetDescriptorDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: PropertySetDescriptor = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `PropertySetDescriptorDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `PropertySetDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> PropertySetDescriptorDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `PropertySetDescriptorDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `PropertySetDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: PropertySetDescriptorDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `PropertySetDescriptorDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `PropertySetDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: PropertySetDescriptorDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// An Ice object descriptor. +public struct ObjectDescriptor: Swift.Hashable { + /// The identity of the object. + public var id: Ice.Identity = Ice.Identity() + /// The object type. + public var `type`: Swift.String = "" + /// Proxy options to use with the proxy created for this Ice object. If empty, + /// the proxy will be created with the proxy options specified on the object + /// adapter or replica group. + public var proxyOptions: Swift.String = "" + + public init() {} + + public init(id: Ice.Identity, `type`: Swift.String, proxyOptions: Swift.String) { + self.id = id + self.`type` = `type` + self.proxyOptions = proxyOptions + } +} + +/// An `Ice.InputStream` extension to read `ObjectDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ObjectDescriptor` structured value from the stream. + /// + /// - returns: `ObjectDescriptor` - The structured value read from the stream. + func read() throws -> ObjectDescriptor { + var v = ObjectDescriptor() + v.id = try self.read() + v.`type` = try self.read() + v.proxyOptions = try self.read() + return v + } + + /// Read an optional `ObjectDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ObjectDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ObjectDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ObjectDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ObjectDescriptor` structured value to the stream. + /// + /// - parameter _: `ObjectDescriptor` - The value to write to the stream. + func write(_ v: ObjectDescriptor) { + self.write(v.id) + self.write(v.`type`) + self.write(v.proxyOptions) + } + + /// Write an optional `ObjectDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ObjectDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of object descriptors. +public typealias ObjectDescriptorSeq = [ObjectDescriptor] + +/// Helper class to read and write `ObjectDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ObjectDescriptorSeqHelper { + /// Read a `ObjectDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ObjectDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ObjectDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 4) + var v = ObjectDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ObjectDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ObjectDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ObjectDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ObjectDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ObjectDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ObjectDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ObjectDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ObjectDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ObjectDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ObjectDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// An Ice object adapter descriptor. +public struct AdapterDescriptor: Swift.Hashable { + /// The object adapter name. + public var name: Swift.String = "" + /// The description of this object adapter. + public var description: Swift.String = "" + /// The object adapter id. + public var id: Swift.String = "" + /// The replica id of this adapter. + public var replicaGroupId: Swift.String = "" + /// The adapter priority. This is eventually used when the adapter + /// is member of a replica group to sort the adapter endpoints by + /// priority. + public var priority: Swift.String = "" + /// Flag to specify if the object adapter will register a process object. + public var registerProcess: Swift.Bool = false + /// If true the lifetime of this object adapter is the same of the + /// server lifetime. This information is used by the IceGrid node + /// to figure out the server state: the server is active only if + /// all its "server lifetime" adapters are active. + public var serverLifetime: Swift.Bool = false + /// The well-known object descriptors associated with this object adapter. + public var objects: ObjectDescriptorSeq = ObjectDescriptorSeq() + /// The allocatable object descriptors associated with this object adapter. + public var allocatables: ObjectDescriptorSeq = ObjectDescriptorSeq() + + public init() {} + + public init(name: Swift.String, description: Swift.String, id: Swift.String, replicaGroupId: Swift.String, priority: Swift.String, registerProcess: Swift.Bool, serverLifetime: Swift.Bool, objects: ObjectDescriptorSeq, allocatables: ObjectDescriptorSeq) { + self.name = name + self.description = description + self.id = id + self.replicaGroupId = replicaGroupId + self.priority = priority + self.registerProcess = registerProcess + self.serverLifetime = serverLifetime + self.objects = objects + self.allocatables = allocatables + } +} + +/// An `Ice.InputStream` extension to read `AdapterDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `AdapterDescriptor` structured value from the stream. + /// + /// - returns: `AdapterDescriptor` - The structured value read from the stream. + func read() throws -> AdapterDescriptor { + var v = AdapterDescriptor() + v.name = try self.read() + v.description = try self.read() + v.id = try self.read() + v.replicaGroupId = try self.read() + v.priority = try self.read() + v.registerProcess = try self.read() + v.serverLifetime = try self.read() + v.objects = try ObjectDescriptorSeqHelper.read(from: self) + v.allocatables = try ObjectDescriptorSeqHelper.read(from: self) + return v + } + + /// Read an optional `AdapterDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> AdapterDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as AdapterDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `AdapterDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `AdapterDescriptor` structured value to the stream. + /// + /// - parameter _: `AdapterDescriptor` - The value to write to the stream. + func write(_ v: AdapterDescriptor) { + self.write(v.name) + self.write(v.description) + self.write(v.id) + self.write(v.replicaGroupId) + self.write(v.priority) + self.write(v.registerProcess) + self.write(v.serverLifetime) + ObjectDescriptorSeqHelper.write(to: self, value: v.objects) + ObjectDescriptorSeqHelper.write(to: self, value: v.allocatables) + } + + /// Write an optional `AdapterDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: AdapterDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of adapter descriptors. +public typealias AdapterDescriptorSeq = [AdapterDescriptor] + +/// Helper class to read and write `AdapterDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct AdapterDescriptorSeqHelper { + /// Read a `AdapterDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `AdapterDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> AdapterDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 9) + var v = AdapterDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: AdapterDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `AdapterDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `AdapterDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> AdapterDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `AdapterDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `AdapterDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: AdapterDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `AdapterDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `AdapterDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: AdapterDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A Freeze database environment descriptor. +public struct DbEnvDescriptor: Swift.Hashable { + /// The name of the database environment. + public var name: Swift.String = "" + /// The description of this database environment. + public var description: Swift.String = "" + /// The home of the database environment (i.e., the directory where + /// the database files will be stored). If empty, the node will + /// provide a default database directory, otherwise the directory + /// must exist. + public var dbHome: Swift.String = "" + /// The configuration properties of the database environment. + public var properties: PropertyDescriptorSeq = PropertyDescriptorSeq() + + public init() {} + + public init(name: Swift.String, description: Swift.String, dbHome: Swift.String, properties: PropertyDescriptorSeq) { + self.name = name + self.description = description + self.dbHome = dbHome + self.properties = properties + } +} + +/// An `Ice.InputStream` extension to read `DbEnvDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `DbEnvDescriptor` structured value from the stream. + /// + /// - returns: `DbEnvDescriptor` - The structured value read from the stream. + func read() throws -> DbEnvDescriptor { + var v = DbEnvDescriptor() + v.name = try self.read() + v.description = try self.read() + v.dbHome = try self.read() + v.properties = try PropertyDescriptorSeqHelper.read(from: self) + return v + } + + /// Read an optional `DbEnvDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `DbEnvDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> DbEnvDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as DbEnvDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `DbEnvDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `DbEnvDescriptor` structured value to the stream. + /// + /// - parameter _: `DbEnvDescriptor` - The value to write to the stream. + func write(_ v: DbEnvDescriptor) { + self.write(v.name) + self.write(v.description) + self.write(v.dbHome) + PropertyDescriptorSeqHelper.write(to: self, value: v.properties) + } + + /// Write an optional `DbEnvDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `DbEnvDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: DbEnvDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of database environment descriptors. +public typealias DbEnvDescriptorSeq = [DbEnvDescriptor] + +/// Helper class to read and write `DbEnvDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct DbEnvDescriptorSeqHelper { + /// Read a `DbEnvDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `DbEnvDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> DbEnvDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 4) + var v = DbEnvDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: DbEnvDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `DbEnvDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `DbEnvDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> DbEnvDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `DbEnvDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `DbEnvDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: DbEnvDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `DbEnvDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `DbEnvDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: DbEnvDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `CommunicatorDescriptor`. +public struct CommunicatorDescriptorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::CommunicatorDescriptor"] + public static let staticId = "::IceGrid::CommunicatorDescriptor" +} + +/// A distribution descriptor defines an IcePatch2 server and the +/// directories to retrieve from the patch server. +public struct DistributionDescriptor: Swift.Hashable { + /// The proxy of the IcePatch2 server. + public var icepatch: Swift.String = "" + /// The source directories. + public var directories: Ice.StringSeq = Ice.StringSeq() + + public init() {} + + public init(icepatch: Swift.String, directories: Ice.StringSeq) { + self.icepatch = icepatch + self.directories = directories + } +} + +/// An `Ice.InputStream` extension to read `DistributionDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `DistributionDescriptor` structured value from the stream. + /// + /// - returns: `DistributionDescriptor` - The structured value read from the stream. + func read() throws -> DistributionDescriptor { + var v = DistributionDescriptor() + v.icepatch = try self.read() + v.directories = try self.read() + return v + } + + /// Read an optional `DistributionDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `DistributionDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> DistributionDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as DistributionDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `DistributionDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `DistributionDescriptor` structured value to the stream. + /// + /// - parameter _: `DistributionDescriptor` - The value to write to the stream. + func write(_ v: DistributionDescriptor) { + self.write(v.icepatch) + self.write(v.directories) + } + + /// Write an optional `DistributionDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `DistributionDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: DistributionDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Traits for Slice class `ServerDescriptor`. +public struct ServerDescriptorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::CommunicatorDescriptor", "::IceGrid::ServerDescriptor"] + public static let staticId = "::IceGrid::ServerDescriptor" +} + +/// A sequence of server descriptors. +public typealias ServerDescriptorSeq = [ServerDescriptor?] + +/// Helper class to read and write `ServerDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ServerDescriptorSeqHelper { + /// Read a `ServerDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ServerDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ServerDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 1) + var v = ServerDescriptorSeq(repeating: nil, count: sz) + for i in 0 ..< sz { + try Swift.withUnsafeMutablePointer(to: &v[i]) { p in + try istr.read(ServerDescriptor.self) { p.pointee = $0 } + } + } + return v + } + /// Read an optional `ServerDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ServerDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ServerDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ServerDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ServerDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ServerDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ServerDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `ServiceDescriptor`. +public struct ServiceDescriptorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::CommunicatorDescriptor", "::IceGrid::ServiceDescriptor"] + public static let staticId = "::IceGrid::ServiceDescriptor" +} + +/// A sequence of service descriptors. +public typealias ServiceDescriptorSeq = [ServiceDescriptor?] + +/// Helper class to read and write `ServiceDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ServiceDescriptorSeqHelper { + /// Read a `ServiceDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ServiceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ServiceDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 1) + var v = ServiceDescriptorSeq(repeating: nil, count: sz) + for i in 0 ..< sz { + try Swift.withUnsafeMutablePointer(to: &v[i]) { p in + try istr.read(ServiceDescriptor.self) { p.pointee = $0 } + } + } + return v + } + /// Read an optional `ServiceDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServiceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ServiceDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ServiceDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ServiceDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ServiceDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ServiceDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServiceDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ServiceDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A server template instance descriptor. +public struct ServerInstanceDescriptor { + /// The template used by this instance. + public var template: Swift.String = "" + /// The template parameter values. + public var parameterValues: StringStringDict = StringStringDict() + /// The property set. + public var propertySet: PropertySetDescriptor = PropertySetDescriptor() + /// The services property sets. It's only valid to set these + /// property sets if the template is an IceBox server template. + public var servicePropertySets: PropertySetDescriptorDict = PropertySetDescriptorDict() + + public init() {} + + public init(template: Swift.String, parameterValues: StringStringDict, propertySet: PropertySetDescriptor, servicePropertySets: PropertySetDescriptorDict) { + self.template = template + self.parameterValues = parameterValues + self.propertySet = propertySet + self.servicePropertySets = servicePropertySets + } +} + +/// An `Ice.InputStream` extension to read `ServerInstanceDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ServerInstanceDescriptor` structured value from the stream. + /// + /// - returns: `ServerInstanceDescriptor` - The structured value read from the stream. + func read() throws -> ServerInstanceDescriptor { + var v = ServerInstanceDescriptor() + v.template = try self.read() + v.parameterValues = try StringStringDictHelper.read(from: self) + v.propertySet = try self.read() + v.servicePropertySets = try PropertySetDescriptorDictHelper.read(from: self) + return v + } + + /// Read an optional `ServerInstanceDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerInstanceDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ServerInstanceDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ServerInstanceDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ServerInstanceDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ServerInstanceDescriptor` structured value to the stream. + /// + /// - parameter _: `ServerInstanceDescriptor` - The value to write to the stream. + func write(_ v: ServerInstanceDescriptor) { + self.write(v.template) + StringStringDictHelper.write(to: self, value: v.parameterValues) + self.write(v.propertySet) + PropertySetDescriptorDictHelper.write(to: self, value: v.servicePropertySets) + } + + /// Write an optional `ServerInstanceDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerInstanceDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ServerInstanceDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of server instance descriptors. +public typealias ServerInstanceDescriptorSeq = [ServerInstanceDescriptor] + +/// Helper class to read and write `ServerInstanceDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ServerInstanceDescriptorSeqHelper { + /// Read a `ServerInstanceDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ServerInstanceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ServerInstanceDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 5) + var v = ServerInstanceDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ServerInstanceDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ServerInstanceDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServerInstanceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ServerInstanceDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ServerInstanceDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ServerInstanceDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ServerInstanceDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ServerInstanceDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServerInstanceDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ServerInstanceDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A template descriptor for server or service templates. +public class TemplateDescriptor { + /// The template. + public var descriptor: CommunicatorDescriptor? = nil + /// The parameters required to instantiate the template. + public var parameters: Ice.StringSeq = Ice.StringSeq() + /// The parameters default values. + public var parameterDefaults: StringStringDict = StringStringDict() + + public init() {} + + public init(descriptor: CommunicatorDescriptor?, parameters: Ice.StringSeq, parameterDefaults: StringStringDict) { + self.descriptor = descriptor + self.parameters = parameters + self.parameterDefaults = parameterDefaults + } +} + +/// An `Ice.InputStream` extension to read `TemplateDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `TemplateDescriptor` structured value from the stream. + /// + /// - returns: `TemplateDescriptor` - The structured value read from the stream. + func read() throws -> TemplateDescriptor { + let v = TemplateDescriptor() + try self.read(CommunicatorDescriptor.self) { v.descriptor = $0 } + v.parameters = try self.read() + v.parameterDefaults = try StringStringDictHelper.read(from: self) + return v + } + + /// Read an optional `TemplateDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `TemplateDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> TemplateDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as TemplateDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `TemplateDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `TemplateDescriptor` structured value to the stream. + /// + /// - parameter _: `TemplateDescriptor` - The value to write to the stream. + func write(_ v: TemplateDescriptor) { + self.write(v.descriptor) + self.write(v.parameters) + StringStringDictHelper.write(to: self, value: v.parameterDefaults) + } + + /// Write an optional `TemplateDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `TemplateDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: TemplateDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A mapping of template identifier to template descriptor. +public typealias TemplateDescriptorDict = [Swift.String: TemplateDescriptor] + +/// Helper class to read and write `TemplateDescriptorDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct TemplateDescriptorDictHelper { + /// Read a `TemplateDescriptorDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `TemplateDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> TemplateDescriptorDict { + let sz = try Swift.Int(istr.readSize()) + var v = TemplateDescriptorDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: TemplateDescriptor = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `TemplateDescriptorDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `TemplateDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> TemplateDescriptorDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `TemplateDescriptorDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `TemplateDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: TemplateDescriptorDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `TemplateDescriptorDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `TemplateDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: TemplateDescriptorDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// A service template instance descriptor. +public class ServiceInstanceDescriptor { + /// The template used by this instance. + public var template: Swift.String = "" + /// The template parameter values. + public var parameterValues: StringStringDict = StringStringDict() + /// The service definition if the instance isn't a template + /// instance (i.e.: if the template attribute is empty). + public var descriptor: ServiceDescriptor? = nil + /// The property set. + public var propertySet: PropertySetDescriptor = PropertySetDescriptor() + + public init() {} + + public init(template: Swift.String, parameterValues: StringStringDict, descriptor: ServiceDescriptor?, propertySet: PropertySetDescriptor) { + self.template = template + self.parameterValues = parameterValues + self.descriptor = descriptor + self.propertySet = propertySet + } +} + +/// An `Ice.InputStream` extension to read `ServiceInstanceDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ServiceInstanceDescriptor` structured value from the stream. + /// + /// - returns: `ServiceInstanceDescriptor` - The structured value read from the stream. + func read() throws -> ServiceInstanceDescriptor { + let v = ServiceInstanceDescriptor() + v.template = try self.read() + v.parameterValues = try StringStringDictHelper.read(from: self) + try self.read(ServiceDescriptor.self) { v.descriptor = $0 } + v.propertySet = try self.read() + return v + } + + /// Read an optional `ServiceInstanceDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServiceInstanceDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ServiceInstanceDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ServiceInstanceDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ServiceInstanceDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ServiceInstanceDescriptor` structured value to the stream. + /// + /// - parameter _: `ServiceInstanceDescriptor` - The value to write to the stream. + func write(_ v: ServiceInstanceDescriptor) { + self.write(v.template) + StringStringDictHelper.write(to: self, value: v.parameterValues) + self.write(v.descriptor) + self.write(v.propertySet) + } + + /// Write an optional `ServiceInstanceDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServiceInstanceDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ServiceInstanceDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of service instance descriptors. +public typealias ServiceInstanceDescriptorSeq = [ServiceInstanceDescriptor] + +/// Helper class to read and write `ServiceInstanceDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ServiceInstanceDescriptorSeqHelper { + /// Read a `ServiceInstanceDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ServiceInstanceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ServiceInstanceDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 5) + var v = ServiceInstanceDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ServiceInstanceDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ServiceInstanceDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ServiceInstanceDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ServiceInstanceDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ServiceInstanceDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ServiceInstanceDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ServiceInstanceDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ServiceInstanceDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ServiceInstanceDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ServiceInstanceDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `IceBoxDescriptor`. +public struct IceBoxDescriptorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::CommunicatorDescriptor", "::IceGrid::IceBoxDescriptor", "::IceGrid::ServerDescriptor"] + public static let staticId = "::IceGrid::IceBoxDescriptor" +} + +/// A node descriptor. +public class NodeDescriptor { + /// The variables defined for the node. + public var variables: StringStringDict = StringStringDict() + /// The server instances. + public var serverInstances: ServerInstanceDescriptorSeq = ServerInstanceDescriptorSeq() + /// Servers (which are not template instances). + public var servers: ServerDescriptorSeq = ServerDescriptorSeq() + /// Load factor of the node. + public var loadFactor: Swift.String = "" + /// The description of this node. + public var description: Swift.String = "" + /// Property set descriptors. + public var propertySets: PropertySetDescriptorDict = PropertySetDescriptorDict() + + public init() {} + + public init(variables: StringStringDict, serverInstances: ServerInstanceDescriptorSeq, servers: ServerDescriptorSeq, loadFactor: Swift.String, description: Swift.String, propertySets: PropertySetDescriptorDict) { + self.variables = variables + self.serverInstances = serverInstances + self.servers = servers + self.loadFactor = loadFactor + self.description = description + self.propertySets = propertySets + } +} + +/// An `Ice.InputStream` extension to read `NodeDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `NodeDescriptor` structured value from the stream. + /// + /// - returns: `NodeDescriptor` - The structured value read from the stream. + func read() throws -> NodeDescriptor { + let v = NodeDescriptor() + v.variables = try StringStringDictHelper.read(from: self) + v.serverInstances = try ServerInstanceDescriptorSeqHelper.read(from: self) + v.servers = try ServerDescriptorSeqHelper.read(from: self) + v.loadFactor = try self.read() + v.description = try self.read() + v.propertySets = try PropertySetDescriptorDictHelper.read(from: self) + return v + } + + /// Read an optional `NodeDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> NodeDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as NodeDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `NodeDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `NodeDescriptor` structured value to the stream. + /// + /// - parameter _: `NodeDescriptor` - The value to write to the stream. + func write(_ v: NodeDescriptor) { + StringStringDictHelper.write(to: self, value: v.variables) + ServerInstanceDescriptorSeqHelper.write(to: self, value: v.serverInstances) + ServerDescriptorSeqHelper.write(to: self, value: v.servers) + self.write(v.loadFactor) + self.write(v.description) + PropertySetDescriptorDictHelper.write(to: self, value: v.propertySets) + } + + /// Write an optional `NodeDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: NodeDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// Mapping of node name to node descriptor. +public typealias NodeDescriptorDict = [Swift.String: NodeDescriptor] + +/// Helper class to read and write `NodeDescriptorDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct NodeDescriptorDictHelper { + /// Read a `NodeDescriptorDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `NodeDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> NodeDescriptorDict { + let sz = try Swift.Int(istr.readSize()) + var v = NodeDescriptorDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: NodeDescriptor = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `NodeDescriptorDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeDescriptorDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> NodeDescriptorDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `NodeDescriptorDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `NodeDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: NodeDescriptorDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `NodeDescriptorDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeDescriptorDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: NodeDescriptorDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `LoadBalancingPolicy`. +public struct LoadBalancingPolicyTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::LoadBalancingPolicy"] + public static let staticId = "::IceGrid::LoadBalancingPolicy" +} + +/// Traits for Slice class `RandomLoadBalancingPolicy`. +public struct RandomLoadBalancingPolicyTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::LoadBalancingPolicy", "::IceGrid::RandomLoadBalancingPolicy"] + public static let staticId = "::IceGrid::RandomLoadBalancingPolicy" +} + +/// Traits for Slice class `OrderedLoadBalancingPolicy`. +public struct OrderedLoadBalancingPolicyTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::LoadBalancingPolicy", "::IceGrid::OrderedLoadBalancingPolicy"] + public static let staticId = "::IceGrid::OrderedLoadBalancingPolicy" +} + +/// Traits for Slice class `RoundRobinLoadBalancingPolicy`. +public struct RoundRobinLoadBalancingPolicyTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::LoadBalancingPolicy", "::IceGrid::RoundRobinLoadBalancingPolicy"] + public static let staticId = "::IceGrid::RoundRobinLoadBalancingPolicy" +} + +/// Traits for Slice class `AdaptiveLoadBalancingPolicy`. +public struct AdaptiveLoadBalancingPolicyTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::AdaptiveLoadBalancingPolicy", "::IceGrid::LoadBalancingPolicy"] + public static let staticId = "::IceGrid::AdaptiveLoadBalancingPolicy" +} + +/// A replica group descriptor. +public class ReplicaGroupDescriptor { + /// The id of the replica group. + public var id: Swift.String = "" + /// The load balancing policy. + public var loadBalancing: LoadBalancingPolicy? = nil + /// Default options for proxies created for the replica group. + public var proxyOptions: Swift.String = "" + /// The object descriptors associated with this object adapter. + public var objects: ObjectDescriptorSeq = ObjectDescriptorSeq() + /// The description of this replica group. + public var description: Swift.String = "" + /// The filter to use for this replica group. + public var filter: Swift.String = "" + + public init() {} + + public init(id: Swift.String, loadBalancing: LoadBalancingPolicy?, proxyOptions: Swift.String, objects: ObjectDescriptorSeq, description: Swift.String, filter: Swift.String) { + self.id = id + self.loadBalancing = loadBalancing + self.proxyOptions = proxyOptions + self.objects = objects + self.description = description + self.filter = filter + } +} + +/// An `Ice.InputStream` extension to read `ReplicaGroupDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ReplicaGroupDescriptor` structured value from the stream. + /// + /// - returns: `ReplicaGroupDescriptor` - The structured value read from the stream. + func read() throws -> ReplicaGroupDescriptor { + let v = ReplicaGroupDescriptor() + v.id = try self.read() + try self.read(LoadBalancingPolicy.self) { v.loadBalancing = $0 } + v.proxyOptions = try self.read() + v.objects = try ObjectDescriptorSeqHelper.read(from: self) + v.description = try self.read() + v.filter = try self.read() + return v + } + + /// Read an optional `ReplicaGroupDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ReplicaGroupDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ReplicaGroupDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ReplicaGroupDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ReplicaGroupDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ReplicaGroupDescriptor` structured value to the stream. + /// + /// - parameter _: `ReplicaGroupDescriptor` - The value to write to the stream. + func write(_ v: ReplicaGroupDescriptor) { + self.write(v.id) + self.write(v.loadBalancing) + self.write(v.proxyOptions) + ObjectDescriptorSeqHelper.write(to: self, value: v.objects) + self.write(v.description) + self.write(v.filter) + } + + /// Write an optional `ReplicaGroupDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ReplicaGroupDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ReplicaGroupDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of replica groups. +public typealias ReplicaGroupDescriptorSeq = [ReplicaGroupDescriptor] + +/// Helper class to read and write `ReplicaGroupDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ReplicaGroupDescriptorSeqHelper { + /// Read a `ReplicaGroupDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ReplicaGroupDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ReplicaGroupDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 6) + var v = ReplicaGroupDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ReplicaGroupDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ReplicaGroupDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ReplicaGroupDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ReplicaGroupDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ReplicaGroupDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ReplicaGroupDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ReplicaGroupDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ReplicaGroupDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ReplicaGroupDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ReplicaGroupDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// An application descriptor. +public class ApplicationDescriptor { + /// The application name. + public var name: Swift.String = "" + /// The variables defined in the application descriptor. + public var variables: StringStringDict = StringStringDict() + /// The replica groups. + public var replicaGroups: ReplicaGroupDescriptorSeq = ReplicaGroupDescriptorSeq() + /// The server templates. + public var serverTemplates: TemplateDescriptorDict = TemplateDescriptorDict() + /// The service templates. + public var serviceTemplates: TemplateDescriptorDict = TemplateDescriptorDict() + /// The application nodes. + public var nodes: NodeDescriptorDict = NodeDescriptorDict() + /// The application distribution. + public var distrib: DistributionDescriptor = DistributionDescriptor() + /// The description of this application. + public var description: Swift.String = "" + /// Property set descriptors. + public var propertySets: PropertySetDescriptorDict = PropertySetDescriptorDict() + + public init() {} + + public init(name: Swift.String, variables: StringStringDict, replicaGroups: ReplicaGroupDescriptorSeq, serverTemplates: TemplateDescriptorDict, serviceTemplates: TemplateDescriptorDict, nodes: NodeDescriptorDict, distrib: DistributionDescriptor, description: Swift.String, propertySets: PropertySetDescriptorDict) { + self.name = name + self.variables = variables + self.replicaGroups = replicaGroups + self.serverTemplates = serverTemplates + self.serviceTemplates = serviceTemplates + self.nodes = nodes + self.distrib = distrib + self.description = description + self.propertySets = propertySets + } +} + +/// An `Ice.InputStream` extension to read `ApplicationDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ApplicationDescriptor` structured value from the stream. + /// + /// - returns: `ApplicationDescriptor` - The structured value read from the stream. + func read() throws -> ApplicationDescriptor { + let v = ApplicationDescriptor() + v.name = try self.read() + v.variables = try StringStringDictHelper.read(from: self) + v.replicaGroups = try ReplicaGroupDescriptorSeqHelper.read(from: self) + v.serverTemplates = try TemplateDescriptorDictHelper.read(from: self) + v.serviceTemplates = try TemplateDescriptorDictHelper.read(from: self) + v.nodes = try NodeDescriptorDictHelper.read(from: self) + v.distrib = try self.read() + v.description = try self.read() + v.propertySets = try PropertySetDescriptorDictHelper.read(from: self) + return v + } + + /// Read an optional `ApplicationDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ApplicationDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ApplicationDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ApplicationDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ApplicationDescriptor` structured value to the stream. + /// + /// - parameter _: `ApplicationDescriptor` - The value to write to the stream. + func write(_ v: ApplicationDescriptor) { + self.write(v.name) + StringStringDictHelper.write(to: self, value: v.variables) + ReplicaGroupDescriptorSeqHelper.write(to: self, value: v.replicaGroups) + TemplateDescriptorDictHelper.write(to: self, value: v.serverTemplates) + TemplateDescriptorDictHelper.write(to: self, value: v.serviceTemplates) + NodeDescriptorDictHelper.write(to: self, value: v.nodes) + self.write(v.distrib) + self.write(v.description) + PropertySetDescriptorDictHelper.write(to: self, value: v.propertySets) + } + + /// Write an optional `ApplicationDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ApplicationDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of application descriptors. +public typealias ApplicationDescriptorSeq = [ApplicationDescriptor] + +/// Helper class to read and write `ApplicationDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct ApplicationDescriptorSeqHelper { + /// Read a `ApplicationDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `ApplicationDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> ApplicationDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 10) + var v = ApplicationDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: ApplicationDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `ApplicationDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> ApplicationDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `ApplicationDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `ApplicationDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: ApplicationDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `ApplicationDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: ApplicationDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `BoxedString`. +public struct BoxedStringTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::BoxedString"] + public static let staticId = "::IceGrid::BoxedString" +} + +/// A node update descriptor to describe the updates to apply to a +/// node of a deployed application. +public class NodeUpdateDescriptor { + /// The name of the node to update. + public var name: Swift.String = "" + /// The updated description (or null if the description wasn't + /// updated.) + public var description: BoxedString? = nil + /// The variables to update. + public var variables: StringStringDict = StringStringDict() + /// The variables to remove. + public var removeVariables: Ice.StringSeq = Ice.StringSeq() + /// The property sets to update. + public var propertySets: PropertySetDescriptorDict = PropertySetDescriptorDict() + /// The property sets to remove. + public var removePropertySets: Ice.StringSeq = Ice.StringSeq() + /// The server instances to update. + public var serverInstances: ServerInstanceDescriptorSeq = ServerInstanceDescriptorSeq() + /// The servers which are not template instances to update. + public var servers: ServerDescriptorSeq = ServerDescriptorSeq() + /// The ids of the servers to remove. + public var removeServers: Ice.StringSeq = Ice.StringSeq() + /// The updated load factor of the node (or null if the load factor + /// was not updated). + public var loadFactor: BoxedString? = nil + + public init() {} + + public init(name: Swift.String, description: BoxedString?, variables: StringStringDict, removeVariables: Ice.StringSeq, propertySets: PropertySetDescriptorDict, removePropertySets: Ice.StringSeq, serverInstances: ServerInstanceDescriptorSeq, servers: ServerDescriptorSeq, removeServers: Ice.StringSeq, loadFactor: BoxedString?) { + self.name = name + self.description = description + self.variables = variables + self.removeVariables = removeVariables + self.propertySets = propertySets + self.removePropertySets = removePropertySets + self.serverInstances = serverInstances + self.servers = servers + self.removeServers = removeServers + self.loadFactor = loadFactor + } +} + +/// An `Ice.InputStream` extension to read `NodeUpdateDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `NodeUpdateDescriptor` structured value from the stream. + /// + /// - returns: `NodeUpdateDescriptor` - The structured value read from the stream. + func read() throws -> NodeUpdateDescriptor { + let v = NodeUpdateDescriptor() + v.name = try self.read() + try self.read(BoxedString.self) { v.description = $0 } + v.variables = try StringStringDictHelper.read(from: self) + v.removeVariables = try self.read() + v.propertySets = try PropertySetDescriptorDictHelper.read(from: self) + v.removePropertySets = try self.read() + v.serverInstances = try ServerInstanceDescriptorSeqHelper.read(from: self) + v.servers = try ServerDescriptorSeqHelper.read(from: self) + v.removeServers = try self.read() + try self.read(BoxedString.self) { v.loadFactor = $0 } + return v + } + + /// Read an optional `NodeUpdateDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeUpdateDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> NodeUpdateDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as NodeUpdateDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `NodeUpdateDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `NodeUpdateDescriptor` structured value to the stream. + /// + /// - parameter _: `NodeUpdateDescriptor` - The value to write to the stream. + func write(_ v: NodeUpdateDescriptor) { + self.write(v.name) + self.write(v.description) + StringStringDictHelper.write(to: self, value: v.variables) + self.write(v.removeVariables) + PropertySetDescriptorDictHelper.write(to: self, value: v.propertySets) + self.write(v.removePropertySets) + ServerInstanceDescriptorSeqHelper.write(to: self, value: v.serverInstances) + ServerDescriptorSeqHelper.write(to: self, value: v.servers) + self.write(v.removeServers) + self.write(v.loadFactor) + } + + /// Write an optional `NodeUpdateDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeUpdateDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: NodeUpdateDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of node update descriptors. +public typealias NodeUpdateDescriptorSeq = [NodeUpdateDescriptor] + +/// Helper class to read and write `NodeUpdateDescriptorSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct NodeUpdateDescriptorSeqHelper { + /// Read a `NodeUpdateDescriptorSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `NodeUpdateDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> NodeUpdateDescriptorSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 10) + var v = NodeUpdateDescriptorSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: NodeUpdateDescriptor = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `NodeUpdateDescriptorSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `NodeUpdateDescriptorSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> NodeUpdateDescriptorSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `NodeUpdateDescriptorSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `NodeUpdateDescriptorSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: NodeUpdateDescriptorSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `NodeUpdateDescriptorSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `NodeUpdateDescriptorSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: NodeUpdateDescriptorSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// Traits for Slice class `BoxedDistributionDescriptor`. +public struct BoxedDistributionDescriptorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::BoxedDistributionDescriptor"] + public static let staticId = "::IceGrid::BoxedDistributionDescriptor" +} + +/// An application update descriptor to describe the updates to apply +/// to a deployed application. +public class ApplicationUpdateDescriptor { + /// The name of the application to update. + public var name: Swift.String = "" + /// The updated description (or null if the description wasn't + /// updated.) + public var description: BoxedString? = nil + /// The updated distribution application descriptor. + public var distrib: BoxedDistributionDescriptor? = nil + /// The variables to update. + public var variables: StringStringDict = StringStringDict() + /// The variables to remove. + public var removeVariables: Ice.StringSeq = Ice.StringSeq() + /// The property sets to update. + public var propertySets: PropertySetDescriptorDict = PropertySetDescriptorDict() + /// The property sets to remove. + public var removePropertySets: Ice.StringSeq = Ice.StringSeq() + /// The replica groups to update. + public var replicaGroups: ReplicaGroupDescriptorSeq = ReplicaGroupDescriptorSeq() + /// The replica groups to remove. + public var removeReplicaGroups: Ice.StringSeq = Ice.StringSeq() + /// The server templates to update. + public var serverTemplates: TemplateDescriptorDict = TemplateDescriptorDict() + /// The ids of the server template to remove. + public var removeServerTemplates: Ice.StringSeq = Ice.StringSeq() + /// The service templates to update. + public var serviceTemplates: TemplateDescriptorDict = TemplateDescriptorDict() + /// The ids of the service template to remove. + public var removeServiceTemplates: Ice.StringSeq = Ice.StringSeq() + /// The application nodes to update. + public var nodes: NodeUpdateDescriptorSeq = NodeUpdateDescriptorSeq() + /// The nodes to remove. + public var removeNodes: Ice.StringSeq = Ice.StringSeq() + + public init() {} + + public init(name: Swift.String, description: BoxedString?, distrib: BoxedDistributionDescriptor?, variables: StringStringDict, removeVariables: Ice.StringSeq, propertySets: PropertySetDescriptorDict, removePropertySets: Ice.StringSeq, replicaGroups: ReplicaGroupDescriptorSeq, removeReplicaGroups: Ice.StringSeq, serverTemplates: TemplateDescriptorDict, removeServerTemplates: Ice.StringSeq, serviceTemplates: TemplateDescriptorDict, removeServiceTemplates: Ice.StringSeq, nodes: NodeUpdateDescriptorSeq, removeNodes: Ice.StringSeq) { + self.name = name + self.description = description + self.distrib = distrib + self.variables = variables + self.removeVariables = removeVariables + self.propertySets = propertySets + self.removePropertySets = removePropertySets + self.replicaGroups = replicaGroups + self.removeReplicaGroups = removeReplicaGroups + self.serverTemplates = serverTemplates + self.removeServerTemplates = removeServerTemplates + self.serviceTemplates = serviceTemplates + self.removeServiceTemplates = removeServiceTemplates + self.nodes = nodes + self.removeNodes = removeNodes + } +} + +/// An `Ice.InputStream` extension to read `ApplicationUpdateDescriptor` structured values from the stream. +public extension Ice.InputStream { + /// Read a `ApplicationUpdateDescriptor` structured value from the stream. + /// + /// - returns: `ApplicationUpdateDescriptor` - The structured value read from the stream. + func read() throws -> ApplicationUpdateDescriptor { + let v = ApplicationUpdateDescriptor() + v.name = try self.read() + try self.read(BoxedString.self) { v.description = $0 } + try self.read(BoxedDistributionDescriptor.self) { v.distrib = $0 } + v.variables = try StringStringDictHelper.read(from: self) + v.removeVariables = try self.read() + v.propertySets = try PropertySetDescriptorDictHelper.read(from: self) + v.removePropertySets = try self.read() + v.replicaGroups = try ReplicaGroupDescriptorSeqHelper.read(from: self) + v.removeReplicaGroups = try self.read() + v.serverTemplates = try TemplateDescriptorDictHelper.read(from: self) + v.removeServerTemplates = try self.read() + v.serviceTemplates = try TemplateDescriptorDictHelper.read(from: self) + v.removeServiceTemplates = try self.read() + v.nodes = try NodeUpdateDescriptorSeqHelper.read(from: self) + v.removeNodes = try self.read() + return v + } + + /// Read an optional `ApplicationUpdateDescriptor?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `ApplicationUpdateDescriptor?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> ApplicationUpdateDescriptor? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as ApplicationUpdateDescriptor + } +} + +/// An `Ice.OutputStream` extension to write `ApplicationUpdateDescriptor` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `ApplicationUpdateDescriptor` structured value to the stream. + /// + /// - parameter _: `ApplicationUpdateDescriptor` - The value to write to the stream. + func write(_ v: ApplicationUpdateDescriptor) { + self.write(v.name) + self.write(v.description) + self.write(v.distrib) + StringStringDictHelper.write(to: self, value: v.variables) + self.write(v.removeVariables) + PropertySetDescriptorDictHelper.write(to: self, value: v.propertySets) + self.write(v.removePropertySets) + ReplicaGroupDescriptorSeqHelper.write(to: self, value: v.replicaGroups) + self.write(v.removeReplicaGroups) + TemplateDescriptorDictHelper.write(to: self, value: v.serverTemplates) + self.write(v.removeServerTemplates) + TemplateDescriptorDictHelper.write(to: self, value: v.serviceTemplates) + self.write(v.removeServiceTemplates) + NodeUpdateDescriptorSeqHelper.write(to: self, value: v.nodes) + self.write(v.removeNodes) + } + + /// Write an optional `ApplicationUpdateDescriptor?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `ApplicationUpdateDescriptor?` - The value to write to the stream. + func write(tag: Swift.Int32, value: ApplicationUpdateDescriptor?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// :nodoc: +public class CommunicatorDescriptor_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return CommunicatorDescriptor.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_CommunicatorDescriptor() -> Ice.ValueTypeResolver { + return CommunicatorDescriptor_TypeResolver() + } +} + +/// A communicator descriptor. +open class CommunicatorDescriptor: Ice.Value { + /// The object adapters. + public var adapters: AdapterDescriptorSeq = AdapterDescriptorSeq() + /// The property set. + public var propertySet: PropertySetDescriptor = PropertySetDescriptor() + /// The database environments. + public var dbEnvs: DbEnvDescriptorSeq = DbEnvDescriptorSeq() + /// The path of each log file. + public var logs: Ice.StringSeq = Ice.StringSeq() + /// A description of this descriptor. + public var description: Swift.String = "" + + public required init() {} + + public init(adapters: AdapterDescriptorSeq, propertySet: PropertySetDescriptor, dbEnvs: DbEnvDescriptorSeq, logs: Ice.StringSeq, description: Swift.String) { + self.adapters = adapters + self.propertySet = propertySet + self.dbEnvs = dbEnvs + self.logs = logs + self.description = description + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return CommunicatorDescriptorTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return CommunicatorDescriptorTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.adapters = try AdapterDescriptorSeqHelper.read(from: istr) + self.propertySet = try istr.read() + self.dbEnvs = try DbEnvDescriptorSeqHelper.read(from: istr) + self.logs = try istr.read() + self.description = try istr.read() + try istr.endSlice() + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: CommunicatorDescriptorTraits.staticId, compactId: -1, last: true) + AdapterDescriptorSeqHelper.write(to: ostr, value: self.adapters) + ostr.write(self.propertySet) + DbEnvDescriptorSeqHelper.write(to: ostr, value: self.dbEnvs) + ostr.write(self.logs) + ostr.write(self.description) + ostr.endSlice() + } +} + +/// :nodoc: +public class ServerDescriptor_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return ServerDescriptor.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServerDescriptor() -> Ice.ValueTypeResolver { + return ServerDescriptor_TypeResolver() + } +} + +/// An Ice server descriptor. +open class ServerDescriptor: CommunicatorDescriptor { + /// The server id. + public var id: Swift.String = "" + /// The path of the server executable. + public var exe: Swift.String = "" + /// The Ice version used by this server. This is only required if + /// backward compatibility with servers using old Ice versions is + /// needed (otherwise the registry will assume the server is using + /// the same Ice version). + /// For example "3.1.1", "3.2", "3.3.0". + public var iceVersion: Swift.String = "" + /// The path to the server working directory. + public var pwd: Swift.String = "" + /// The command line options to pass to the server executable. + public var options: Ice.StringSeq = Ice.StringSeq() + /// The server environment variables. + public var envs: Ice.StringSeq = Ice.StringSeq() + /// The server activation mode (possible values are "on-demand" or + /// "manual"). + public var activation: Swift.String = "" + /// The activation timeout (an integer value representing the + /// number of seconds to wait for activation). + public var activationTimeout: Swift.String = "" + /// The deactivation timeout (an integer value representing the + /// number of seconds to wait for deactivation). + public var deactivationTimeout: Swift.String = "" + /// Specifies if the server depends on the application + /// distribution. + public var applicationDistrib: Swift.Bool = false + /// The distribution descriptor. + public var distrib: DistributionDescriptor = DistributionDescriptor() + /// Specifies if the server is allocatable. + public var allocatable: Swift.Bool = false + /// The user account used to run the server. + public var user: Swift.String = "" + + public required init() { + super.init() + } + + public init(adapters: AdapterDescriptorSeq, propertySet: PropertySetDescriptor, dbEnvs: DbEnvDescriptorSeq, logs: Ice.StringSeq, description: Swift.String, id: Swift.String, exe: Swift.String, iceVersion: Swift.String, pwd: Swift.String, options: Ice.StringSeq, envs: Ice.StringSeq, activation: Swift.String, activationTimeout: Swift.String, deactivationTimeout: Swift.String, applicationDistrib: Swift.Bool, distrib: DistributionDescriptor, allocatable: Swift.Bool, user: Swift.String) { + self.id = id + self.exe = exe + self.iceVersion = iceVersion + self.pwd = pwd + self.options = options + self.envs = envs + self.activation = activation + self.activationTimeout = activationTimeout + self.deactivationTimeout = deactivationTimeout + self.applicationDistrib = applicationDistrib + self.distrib = distrib + self.allocatable = allocatable + self.user = user + super.init(adapters: adapters, propertySet: propertySet, dbEnvs: dbEnvs, logs: logs, description: description) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return ServerDescriptorTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return ServerDescriptorTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + self.exe = try istr.read() + self.iceVersion = try istr.read() + self.pwd = try istr.read() + self.options = try istr.read() + self.envs = try istr.read() + self.activation = try istr.read() + self.activationTimeout = try istr.read() + self.deactivationTimeout = try istr.read() + self.applicationDistrib = try istr.read() + self.distrib = try istr.read() + self.allocatable = try istr.read() + self.user = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServerDescriptorTraits.staticId, compactId: -1, last: false) + ostr.write(self.id) + ostr.write(self.exe) + ostr.write(self.iceVersion) + ostr.write(self.pwd) + ostr.write(self.options) + ostr.write(self.envs) + ostr.write(self.activation) + ostr.write(self.activationTimeout) + ostr.write(self.deactivationTimeout) + ostr.write(self.applicationDistrib) + ostr.write(self.distrib) + ostr.write(self.allocatable) + ostr.write(self.user) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class ServiceDescriptor_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return ServiceDescriptor.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServiceDescriptor() -> Ice.ValueTypeResolver { + return ServiceDescriptor_TypeResolver() + } +} + +/// An IceBox service descriptor. +open class ServiceDescriptor: CommunicatorDescriptor { + /// The service name. + public var name: Swift.String = "" + /// The entry point of the IceBox service. + public var entry: Swift.String = "" + + public required init() { + super.init() + } + + public init(adapters: AdapterDescriptorSeq, propertySet: PropertySetDescriptor, dbEnvs: DbEnvDescriptorSeq, logs: Ice.StringSeq, description: Swift.String, name: Swift.String, entry: Swift.String) { + self.name = name + self.entry = entry + super.init(adapters: adapters, propertySet: propertySet, dbEnvs: dbEnvs, logs: logs, description: description) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return ServiceDescriptorTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return ServiceDescriptorTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + self.entry = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServiceDescriptorTraits.staticId, compactId: -1, last: false) + ostr.write(self.name) + ostr.write(self.entry) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class IceBoxDescriptor_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return IceBoxDescriptor.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_IceBoxDescriptor() -> Ice.ValueTypeResolver { + return IceBoxDescriptor_TypeResolver() + } +} + +/// An IceBox server descriptor. +open class IceBoxDescriptor: ServerDescriptor { + /// The service instances. + public var services: ServiceInstanceDescriptorSeq = ServiceInstanceDescriptorSeq() + + public required init() { + super.init() + } + + public init(adapters: AdapterDescriptorSeq, propertySet: PropertySetDescriptor, dbEnvs: DbEnvDescriptorSeq, logs: Ice.StringSeq, description: Swift.String, id: Swift.String, exe: Swift.String, iceVersion: Swift.String, pwd: Swift.String, options: Ice.StringSeq, envs: Ice.StringSeq, activation: Swift.String, activationTimeout: Swift.String, deactivationTimeout: Swift.String, applicationDistrib: Swift.Bool, distrib: DistributionDescriptor, allocatable: Swift.Bool, user: Swift.String, services: ServiceInstanceDescriptorSeq) { + self.services = services + super.init(adapters: adapters, propertySet: propertySet, dbEnvs: dbEnvs, logs: logs, description: description, id: id, exe: exe, iceVersion: iceVersion, pwd: pwd, options: options, envs: envs, activation: activation, activationTimeout: activationTimeout, deactivationTimeout: deactivationTimeout, applicationDistrib: applicationDistrib, distrib: distrib, allocatable: allocatable, user: user) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return IceBoxDescriptorTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return IceBoxDescriptorTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.services = try ServiceInstanceDescriptorSeqHelper.read(from: istr) + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: IceBoxDescriptorTraits.staticId, compactId: -1, last: false) + ServiceInstanceDescriptorSeqHelper.write(to: ostr, value: self.services) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class LoadBalancingPolicy_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return LoadBalancingPolicy.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_LoadBalancingPolicy() -> Ice.ValueTypeResolver { + return LoadBalancingPolicy_TypeResolver() + } +} + +/// A base class for load balancing policies. +open class LoadBalancingPolicy: Ice.Value { + /// The number of replicas that will be used to gather the + /// endpoints of a replica group. + public var nReplicas: Swift.String = "" + + public required init() {} + + public init(nReplicas: Swift.String) { + self.nReplicas = nReplicas + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return LoadBalancingPolicyTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return LoadBalancingPolicyTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.nReplicas = try istr.read() + try istr.endSlice() + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: LoadBalancingPolicyTraits.staticId, compactId: -1, last: true) + ostr.write(self.nReplicas) + ostr.endSlice() + } +} + +/// :nodoc: +public class RandomLoadBalancingPolicy_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return RandomLoadBalancingPolicy.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_RandomLoadBalancingPolicy() -> Ice.ValueTypeResolver { + return RandomLoadBalancingPolicy_TypeResolver() + } +} + +/// Random load balancing policy. +open class RandomLoadBalancingPolicy: LoadBalancingPolicy { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return RandomLoadBalancingPolicyTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return RandomLoadBalancingPolicyTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: RandomLoadBalancingPolicyTraits.staticId, compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class OrderedLoadBalancingPolicy_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return OrderedLoadBalancingPolicy.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_OrderedLoadBalancingPolicy() -> Ice.ValueTypeResolver { + return OrderedLoadBalancingPolicy_TypeResolver() + } +} + +/// Ordered load balancing policy. +open class OrderedLoadBalancingPolicy: LoadBalancingPolicy { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return OrderedLoadBalancingPolicyTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return OrderedLoadBalancingPolicyTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: OrderedLoadBalancingPolicyTraits.staticId, compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class RoundRobinLoadBalancingPolicy_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return RoundRobinLoadBalancingPolicy.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_RoundRobinLoadBalancingPolicy() -> Ice.ValueTypeResolver { + return RoundRobinLoadBalancingPolicy_TypeResolver() + } +} + +/// Round robin load balancing policy. +open class RoundRobinLoadBalancingPolicy: LoadBalancingPolicy { + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return RoundRobinLoadBalancingPolicyTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return RoundRobinLoadBalancingPolicyTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: RoundRobinLoadBalancingPolicyTraits.staticId, compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class AdaptiveLoadBalancingPolicy_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return AdaptiveLoadBalancingPolicy.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_AdaptiveLoadBalancingPolicy() -> Ice.ValueTypeResolver { + return AdaptiveLoadBalancingPolicy_TypeResolver() + } +} + +/// Adaptive load balancing policy. +open class AdaptiveLoadBalancingPolicy: LoadBalancingPolicy { + /// The load sample to use for the load balancing. The allowed + /// values for this attribute are "1", "5" and "15", representing + /// respectively the load average over the past minute, the past 5 + /// minutes and the past 15 minutes. + public var loadSample: Swift.String = "" + + public required init() { + super.init() + } + + public init(nReplicas: Swift.String, loadSample: Swift.String) { + self.loadSample = loadSample + super.init(nReplicas: nReplicas) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return AdaptiveLoadBalancingPolicyTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return AdaptiveLoadBalancingPolicyTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.loadSample = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AdaptiveLoadBalancingPolicyTraits.staticId, compactId: -1, last: false) + ostr.write(self.loadSample) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class BoxedString_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return BoxedString.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_BoxedString() -> Ice.ValueTypeResolver { + return BoxedString_TypeResolver() + } +} + +/// A "boxed" string. +open class BoxedString: Ice.Value { + /// The value of the boxed string. + public var value: Swift.String = "" + + public required init() {} + + public init(value: Swift.String) { + self.value = value + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return BoxedStringTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return BoxedStringTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.value = try istr.read() + try istr.endSlice() + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: BoxedStringTraits.staticId, compactId: -1, last: true) + ostr.write(self.value) + ostr.endSlice() + } +} + +/// :nodoc: +public class BoxedDistributionDescriptor_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return BoxedDistributionDescriptor.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_BoxedDistributionDescriptor() -> Ice.ValueTypeResolver { + return BoxedDistributionDescriptor_TypeResolver() + } +} + +/// A "boxed" distribution descriptor. +open class BoxedDistributionDescriptor: Ice.Value { + /// The value of the boxed distribution descriptor. + public var value: DistributionDescriptor = DistributionDescriptor() + + public required init() {} + + public init(value: DistributionDescriptor) { + self.value = value + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return BoxedDistributionDescriptorTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return BoxedDistributionDescriptorTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.value = try istr.read() + try istr.endSlice() + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: BoxedDistributionDescriptorTraits.staticId, compactId: -1, last: true) + ostr.write(self.value) + ostr.endSlice() + } +} diff --git a/Sources/IceGrid/Exception.swift b/Sources/IceGrid/Exception.swift new file mode 100644 index 0000000..812970a --- /dev/null +++ b/Sources/IceGrid/Exception.swift @@ -0,0 +1,962 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Exception.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// :nodoc: +public class ApplicationNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ApplicationNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ApplicationNotExistException() -> Ice.UserExceptionTypeResolver { + return ApplicationNotExistException_TypeResolver() + } +} + +/// This exception is raised if an application does not exist. +open class ApplicationNotExistException: Ice.UserException { + /// The name of the application. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ApplicationNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ApplicationNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ServerNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ServerNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServerNotExistException() -> Ice.UserExceptionTypeResolver { + return ServerNotExistException_TypeResolver() + } +} + +/// This exception is raised if a server does not exist. +open class ServerNotExistException: Ice.UserException { + /// The identifier of the server. + public var id: Swift.String = "" + + public required init() {} + + public init(id: Swift.String) { + self.id = id + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ServerNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServerNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ServerStartException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ServerStartException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServerStartException() -> Ice.UserExceptionTypeResolver { + return ServerStartException_TypeResolver() + } +} + +/// This exception is raised if a server failed to start. +open class ServerStartException: Ice.UserException { + /// The identifier of the server. + public var id: Swift.String = "" + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(id: Swift.String, reason: Swift.String) { + self.id = id + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ServerStartException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServerStartException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ServerStopException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ServerStopException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServerStopException() -> Ice.UserExceptionTypeResolver { + return ServerStopException_TypeResolver() + } +} + +/// This exception is raised if a server failed to stop. +open class ServerStopException: Ice.UserException { + /// The identifier of the server. + public var id: Swift.String = "" + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(id: Swift.String, reason: Swift.String) { + self.id = id + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ServerStopException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServerStopException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class AdapterNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return AdapterNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_AdapterNotExistException() -> Ice.UserExceptionTypeResolver { + return AdapterNotExistException_TypeResolver() + } +} + +/// This exception is raised if an adapter does not exist. +open class AdapterNotExistException: Ice.UserException { + /// The id of the object adapter. + public var id: Swift.String = "" + + public required init() {} + + public init(id: Swift.String) { + self.id = id + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::AdapterNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AdapterNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ObjectExistsException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ObjectExistsException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ObjectExistsException() -> Ice.UserExceptionTypeResolver { + return ObjectExistsException_TypeResolver() + } +} + +/// This exception is raised if an object already exists. +open class ObjectExistsException: Ice.UserException { + /// The identity of the object. + public var id: Ice.Identity = Ice.Identity() + + public required init() {} + + public init(id: Ice.Identity) { + self.id = id + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ObjectExistsException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ObjectExistsException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ObjectNotRegisteredException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ObjectNotRegisteredException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ObjectNotRegisteredException() -> Ice.UserExceptionTypeResolver { + return ObjectNotRegisteredException_TypeResolver() + } +} + +/// This exception is raised if an object is not registered. +open class ObjectNotRegisteredException: Ice.UserException { + /// The identity of the object. + public var id: Ice.Identity = Ice.Identity() + + public required init() {} + + public init(id: Ice.Identity) { + self.id = id + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ObjectNotRegisteredException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ObjectNotRegisteredException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class NodeNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return NodeNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_NodeNotExistException() -> Ice.UserExceptionTypeResolver { + return NodeNotExistException_TypeResolver() + } +} + +/// This exception is raised if a node does not exist. +open class NodeNotExistException: Ice.UserException { + /// The node name. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::NodeNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: NodeNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class RegistryNotExistException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return RegistryNotExistException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_RegistryNotExistException() -> Ice.UserExceptionTypeResolver { + return RegistryNotExistException_TypeResolver() + } +} + +/// This exception is raised if a registry does not exist. +open class RegistryNotExistException: Ice.UserException { + /// The registry name. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::RegistryNotExistException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: RegistryNotExistException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class DeploymentException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return DeploymentException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_DeploymentException() -> Ice.UserExceptionTypeResolver { + return DeploymentException_TypeResolver() + } +} + +/// An exception for deployment errors. +open class DeploymentException: Ice.UserException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::DeploymentException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: DeploymentException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class NodeUnreachableException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return NodeUnreachableException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_NodeUnreachableException() -> Ice.UserExceptionTypeResolver { + return NodeUnreachableException_TypeResolver() + } +} + +/// This exception is raised if a node could not be reached. +open class NodeUnreachableException: Ice.UserException { + /// The name of the node that is not reachable. + public var name: Swift.String = "" + /// The reason why the node couldn't be reached. + public var reason: Swift.String = "" + + public required init() {} + + public init(name: Swift.String, reason: Swift.String) { + self.name = name + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::NodeUnreachableException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: NodeUnreachableException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ServerUnreachableException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ServerUnreachableException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ServerUnreachableException() -> Ice.UserExceptionTypeResolver { + return ServerUnreachableException_TypeResolver() + } +} + +/// This exception is raised if a server could not be reached. +open class ServerUnreachableException: Ice.UserException { + /// The id of the server that is not reachable. + public var name: Swift.String = "" + /// The reason why the server couldn't be reached. + public var reason: Swift.String = "" + + public required init() {} + + public init(name: Swift.String, reason: Swift.String) { + self.name = name + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ServerUnreachableException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ServerUnreachableException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class RegistryUnreachableException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return RegistryUnreachableException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_RegistryUnreachableException() -> Ice.UserExceptionTypeResolver { + return RegistryUnreachableException_TypeResolver() + } +} + +/// This exception is raised if a registry could not be reached. +open class RegistryUnreachableException: Ice.UserException { + /// The name of the registry that is not reachable. + public var name: Swift.String = "" + /// The reason why the registry couldn't be reached. + public var reason: Swift.String = "" + + public required init() {} + + public init(name: Swift.String, reason: Swift.String) { + self.name = name + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::RegistryUnreachableException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: RegistryUnreachableException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class BadSignalException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return BadSignalException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_BadSignalException() -> Ice.UserExceptionTypeResolver { + return BadSignalException_TypeResolver() + } +} + +/// This exception is raised if an unknown signal was sent to +/// to a server. +open class BadSignalException: Ice.UserException { + /// The details of the unknown signal. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::BadSignalException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: BadSignalException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class PatchException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return PatchException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_PatchException() -> Ice.UserExceptionTypeResolver { + return PatchException_TypeResolver() + } +} + +/// This exception is raised if a patch failed. +open class PatchException: Ice.UserException { + /// The reasons why the patch failed. + public var reasons: Ice.StringSeq = Ice.StringSeq() + + public required init() {} + + public init(reasons: Ice.StringSeq) { + self.reasons = reasons + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::PatchException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: PatchException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reasons) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reasons = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class AccessDeniedException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return AccessDeniedException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_AccessDeniedException() -> Ice.UserExceptionTypeResolver { + return AccessDeniedException_TypeResolver() + } +} + +/// This exception is raised if a registry lock wasn't +/// acquired or is already held by a session. +open class AccessDeniedException: Ice.UserException { + /// The id of the user holding the lock (if any). + public var lockUserId: Swift.String = "" + + public required init() {} + + public init(lockUserId: Swift.String) { + self.lockUserId = lockUserId + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::AccessDeniedException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AccessDeniedException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.lockUserId) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.lockUserId = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class AllocationException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return AllocationException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_AllocationException() -> Ice.UserExceptionTypeResolver { + return AllocationException_TypeResolver() + } +} + +/// This exception is raised if the allocation of an object failed. +open class AllocationException: Ice.UserException { + /// The reason why the object couldn't be allocated. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::AllocationException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AllocationException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class AllocationTimeoutException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return AllocationTimeoutException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_AllocationTimeoutException() -> Ice.UserExceptionTypeResolver { + return AllocationTimeoutException_TypeResolver() + } +} + +/// This exception is raised if the request to allocate an object times +/// out. +open class AllocationTimeoutException: AllocationException { + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::AllocationTimeoutException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AllocationTimeoutException.ice_staticId(), compactId: -1, last: false) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } +} + +/// :nodoc: +public class PermissionDeniedException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return PermissionDeniedException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_PermissionDeniedException() -> Ice.UserExceptionTypeResolver { + return PermissionDeniedException_TypeResolver() + } +} + +/// This exception is raised if a client is denied the ability to create +/// a session with IceGrid. +open class PermissionDeniedException: Ice.UserException { + /// The reason why permission was denied. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::PermissionDeniedException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: PermissionDeniedException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class ObserverAlreadyRegisteredException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ObserverAlreadyRegisteredException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ObserverAlreadyRegisteredException() -> Ice.UserExceptionTypeResolver { + return ObserverAlreadyRegisteredException_TypeResolver() + } +} + +/// This exception is raised if an observer is already registered with +/// the registry. +open class ObserverAlreadyRegisteredException: Ice.UserException { + /// The identity of the observer. + public var id: Ice.Identity = Ice.Identity() + + public required init() {} + + public init(id: Ice.Identity) { + self.id = id + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ObserverAlreadyRegisteredException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ObserverAlreadyRegisteredException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.id) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.id = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class FileNotAvailableException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return FileNotAvailableException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_FileNotAvailableException() -> Ice.UserExceptionTypeResolver { + return FileNotAvailableException_TypeResolver() + } +} + +/// This exception is raised if a file is not available. +open class FileNotAvailableException: Ice.UserException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::FileNotAvailableException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: FileNotAvailableException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} diff --git a/Sources/IceGrid/FileParser.swift b/Sources/IceGrid/FileParser.swift new file mode 100644 index 0000000..147c860 --- /dev/null +++ b/Sources/IceGrid/FileParser.swift @@ -0,0 +1,316 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `FileParser.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// :nodoc: +public class ParseException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return ParseException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_ParseException() -> Ice.UserExceptionTypeResolver { + return ParseException_TypeResolver() + } +} + +/// This exception is raised if an error occurs during parsing. +open class ParseException: Ice.UserException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::ParseException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: ParseException.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// Traits for Slice interface `FileParser`. +public struct FileParserTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::FileParser"] + public static let staticId = "::IceGrid::FileParser" +} + +/// icegridadmin provides a FileParser +/// object to transform XML files into ApplicationDescriptor +/// objects. +/// +/// FileParserPrx Methods: +/// +/// - parse: Parse a file. +/// +/// - parseAsync: Parse a file. +public protocol FileParserPrx: Ice.ObjectPrx {} + +private final class FileParserPrxI: Ice.ObjectPrxI, FileParserPrx { + public override class func ice_staticId() -> Swift.String { + return FileParserTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `FileParserPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `FileParserPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: FileParserPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> FileParserPrx? { + return try FileParserPrxI.checkedCast(prx: prx, facet: facet, context: context) as FileParserPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `FileParserPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `FileParserPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: FileParserPrx.Protocol, facet: Swift.String? = nil) -> FileParserPrx { + return FileParserPrxI.uncheckedCast(prx: prx, facet: facet) as FileParserPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `FileParserPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: FileParserPrx.Protocol) -> Swift.String { + return FileParserTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `FileParserPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `FileParserPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FileParserPrx?` - The extracted proxy + func read(_ type: FileParserPrx.Protocol) throws -> FileParserPrx? { + return try read() as FileParserPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `FileParserPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FileParserPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: FileParserPrx.Protocol) throws -> FileParserPrx? { + return try read(tag: tag) as FileParserPrxI? + } +} + +/// icegridadmin provides a FileParser +/// object to transform XML files into ApplicationDescriptor +/// objects. +/// +/// FileParserPrx Methods: +/// +/// - parse: Parse a file. +/// +/// - parseAsync: Parse a file. +public extension FileParserPrx { + /// Parse a file. + /// + /// - parameter xmlFile: `Swift.String` Full pathname to the file. + /// + /// - parameter adminProxy: `AdminPrx?` An Admin proxy, used only to retrieve default + /// templates when needed. May be null. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `ApplicationDescriptor` - The application descriptor. + /// + /// - throws: + /// + /// - ParseException - Raised if an error occurred during parsing. + func parse(xmlFile iceP_xmlFile: Swift.String, adminProxy iceP_adminProxy: AdminPrx?, context: Ice.Context? = nil) throws -> ApplicationDescriptor { + return try _impl._invoke(operation: "parse", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_xmlFile) + ostr.write(iceP_adminProxy) + }, + read: { istr in + let iceP_returnValue: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ParseException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Parse a file. + /// + /// - parameter xmlFile: `Swift.String` Full pathname to the file. + /// + /// - parameter adminProxy: `AdminPrx?` An Admin proxy, used only to retrieve default + /// templates when needed. May be null. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func parseAsync(xmlFile iceP_xmlFile: Swift.String, adminProxy iceP_adminProxy: AdminPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "parse", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_xmlFile) + ostr.write(iceP_adminProxy) + }, + read: { istr in + let iceP_returnValue: ApplicationDescriptor = try istr.read() + try istr.readPendingValues() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as ParseException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `FileParser` servants. +public struct FileParserDisp: Ice.Disp { + public let servant: FileParser + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: FileParser) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "ice_id": + return try (servant as? Object ?? FileParserDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? FileParserDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? FileParserDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? FileParserDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "parse": + return try servant._iceD_parse(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// icegridadmin provides a FileParser +/// object to transform XML files into ApplicationDescriptor +/// objects. +public protocol FileParser { + /// Parse a file. + /// + /// - parameter xmlFile: `Swift.String` Full pathname to the file. + /// + /// - parameter adminProxy: `AdminPrx?` An Admin proxy, used only to retrieve default + /// templates when needed. May be null. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `ApplicationDescriptor` - The application descriptor. + /// + /// - throws: + /// + /// - ParseException - Raised if an error occurred during parsing. + func parse(xmlFile: Swift.String, adminProxy: AdminPrx?, current: Ice.Current) throws -> ApplicationDescriptor +} + +/// icegridadmin provides a FileParser +/// object to transform XML files into ApplicationDescriptor +/// objects. +/// +/// FileParser Methods: +/// +/// - parse: Parse a file. +public extension FileParser { + func _iceD_parse(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_xmlFile, iceP_adminProxy): (Swift.String, AdminPrx?) = try inS.read { istr in + let iceP_xmlFile: Swift.String = try istr.read() + let iceP_adminProxy: AdminPrx? = try istr.read(AdminPrx.self) + return (iceP_xmlFile, iceP_adminProxy) + } + + let iceP_returnValue = try self.parse(xmlFile: iceP_xmlFile, adminProxy: iceP_adminProxy, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + ostr.writePendingValues() + } + } +} diff --git a/Sources/IceGrid/PluginFacade.swift b/Sources/IceGrid/PluginFacade.swift new file mode 100644 index 0000000..e4669a4 --- /dev/null +++ b/Sources/IceGrid/PluginFacade.swift @@ -0,0 +1,242 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `PluginFacade.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// The ReplicaGroupFilter is used by IceGrid to filter adapters +/// returned to the client when it resolves a filtered replica group. +/// +/// IceGrid provides the list of available adapters. The implementation +/// of this method can use the provided context and connection to +/// filter and return the filtered set of adapters. +public protocol ReplicaGroupFilter: Swift.AnyObject { + /// Filter the the given set of adapters. + /// + /// - parameter replicaGroupId: `Swift.String` The replica group ID. + /// + /// - parameter adapterIds: `Ice.StringSeq` The adpater IDs to filter. + /// + /// - parameter con: `Ice.Connection?` The connection from the Ice client which is + /// resolving the replica group endpoints. + /// + /// - parameter ctx: `Ice.Context` The context from the Ice client which is resolving + /// the replica group endpoints. + /// + /// - returns: `Ice.StringSeq` - The filtered adapter IDs. + func filter(replicaGroupId: Swift.String, adapterIds: Ice.StringSeq, con: Ice.Connection?, ctx: Ice.Context) throws -> Ice.StringSeq +} + +/// The TypeFilter is used by IceGrid to filter well-known proxies +/// returned to the client when it searches a well-known object by +/// type. +/// +/// IceGrid provides the list of available proxies. The implementation +/// of this method can use the provided context and connection to +/// filter and return the filtered set of proxies. +public protocol TypeFilter: Swift.AnyObject { + /// Filter the the given set of proxies. + /// + /// - parameter type: `Swift.String` The type. + /// + /// - parameter proxies: `Ice.ObjectProxySeq` The proxies to filter. + /// + /// - parameter con: `Ice.Connection?` The connection from the Ice client which is + /// looking up well-known objects by type. + /// + /// - parameter ctx: `Ice.Context` The context from the Ice client which is looking up + /// well-known objects by type. + /// + /// - returns: `Ice.ObjectProxySeq` - The filtered proxies. + func filter(type: Swift.String, proxies: Ice.ObjectProxySeq, con: Ice.Connection?, ctx: Ice.Context) throws -> Ice.ObjectProxySeq +} + +/// The RegistryPluginFacade is implemented by IceGrid and can be used +/// by plugins and filter implementations to retrieve information from +/// IceGrid about the well-known objects or adapters. It's also used to +/// register/unregister replica group and type filters. +public protocol RegistryPluginFacade: Swift.AnyObject { + /// Get an application descriptor. + /// + /// - parameter _: `Swift.String` The application name. + /// + /// - returns: `ApplicationInfo` - The application descriptor. + /// + /// - throws: + /// + /// - ApplicationNotExistException - Raised if the application + /// doesn't exist. + func getApplicationInfo(_ name: Swift.String) throws -> ApplicationInfo + + /// Get the server information for the server with the given id. + /// + /// - parameter _: `Swift.String` The server id. + /// + /// - returns: `ServerInfo` - The server information. + /// + /// - throws: + /// + /// - ServerNotExistException - Raised if the server doesn't exist. + func getServerInfo(_ id: Swift.String) throws -> ServerInfo + + /// Get the ID of the server to which the given adapter belongs. + /// + /// - parameter _: `Swift.String` The adapter ID. + /// + /// - returns: `Swift.String` - The server ID or the empty string if the given + /// identifier is not associated to an object adapter defined with + /// an application descriptor. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't + /// exist. + func getAdapterServer(_ adapterId: Swift.String) throws -> Swift.String + + /// Get the name of the application to which the given adapter belongs. + /// + /// - parameter _: `Swift.String` The adapter ID. + /// + /// - returns: `Swift.String` - The application name or the empty string if the given + /// identifier is not associated to a replica group or object + /// adapter defined with an application descriptor. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't + /// exist. + func getAdapterApplication(_ adapterId: Swift.String) throws -> Swift.String + + /// Get the name of the node to which the given adapter belongs. + /// + /// - parameter _: `Swift.String` The adapter ID. + /// + /// - returns: `Swift.String` - The node name or the empty string if the given + /// identifier is not associated to an object adapter defined with + /// an application descriptor. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't + /// exist. + func getAdapterNode(_ adapterId: Swift.String) throws -> Swift.String + + /// Get the adapter information for the replica group or adapter + /// with the given id. + /// + /// - parameter _: `Swift.String` The adapter id. + /// + /// - returns: `AdapterInfoSeq` - A sequence of adapter information structures. If the + /// given id refers to an adapter, this sequence will contain only + /// one element. If the given id refers to a replica group, the + /// sequence will contain the adapter information of each member of + /// the replica group. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter or + /// replica group doesn't exist. + func getAdapterInfo(_ id: Swift.String) throws -> AdapterInfoSeq + + /// Get the object info for the object with the given identity. + /// + /// - parameter _: `Ice.Identity` The identity of the object. + /// + /// - returns: `ObjectInfo` - The object info. + /// + /// - throws: + /// + /// - ObjectNotRegisteredException - Raised if the object isn't + /// registered with the registry. + func getObjectInfo(_ id: Ice.Identity) throws -> ObjectInfo + + /// Get the node information for the node with the given name. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - returns: `NodeInfo` - The node information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeInfo(_ name: Swift.String) throws -> NodeInfo + + /// Get the load averages of the node. + /// + /// - parameter _: `Swift.String` The node name. + /// + /// - returns: `LoadInfo` - The node load information. + /// + /// - throws: + /// + /// - NodeNotExistException - Raised if the node doesn't exist. + /// + /// - NodeUnreachableException - Raised if the node could not be + /// reached. + func getNodeLoad(_ name: Swift.String) throws -> LoadInfo + + /// Get the property value for the given property and adapter. The + /// property is looked up in the server or service descriptor where + /// the adapter is defined. + /// + /// - parameter adapterId: `Swift.String` The adapter ID + /// + /// - parameter name: `Swift.String` The name of the property. + /// + /// - returns: `Swift.String` - The property value. + /// + /// - throws: + /// + /// - AdapterNotExistException - Raised if the adapter doesn't exist. + func getPropertyForAdapter(adapterId: Swift.String, name: Swift.String) throws -> Swift.String + + /// Add a replica group filter. + /// + /// - parameter id: `Swift.String` The identifier of the filter. This identifier must + /// match the value of the "filter" attribute specified in the + /// replica group descriptor. To filter dynamically registered + /// replica groups, you should use the empty filter id. + /// + /// - parameter filter: `ReplicaGroupFilter?` The filter implementation. + func addReplicaGroupFilter(id: Swift.String, filter: ReplicaGroupFilter?) + + /// Remove a replica group filter. + /// + /// - parameter id: `Swift.String` The identifier of the filter. + /// + /// - parameter filter: `ReplicaGroupFilter?` The filter implementation. + /// + /// - returns: `Swift.Bool` - True of the filter was removed, false otherwise. + func removeReplicaGroupFilter(id: Swift.String, filter: ReplicaGroupFilter?) -> Swift.Bool + + /// Add a type filter. + /// + /// - parameter type: `Swift.String` The type to register this filter with. + /// + /// - parameter filter: `TypeFilter?` The filter implementation. + func addTypeFilter(type: Swift.String, filter: TypeFilter?) + + /// Remove a type filter. + /// + /// - parameter type: `Swift.String` The type to register this filter with. + /// + /// - parameter filter: `TypeFilter?` The filter implementation. + /// + /// - returns: `Swift.Bool` - True of the filter was removed, false otherwise. + func removeTypeFilter(type: Swift.String, filter: TypeFilter?) -> Swift.Bool +} diff --git a/Sources/IceGrid/Registry.swift b/Sources/IceGrid/Registry.swift new file mode 100644 index 0000000..905162a --- /dev/null +++ b/Sources/IceGrid/Registry.swift @@ -0,0 +1,1667 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Registry.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// Determines which load sampling interval to use. +public enum LoadSample: Swift.UInt8 { + /// LoadSample1 Sample every minute. + case LoadSample1 = 0 + /// LoadSample5 Sample every five minutes. + case LoadSample5 = 1 + /// LoadSample15 Sample every fifteen minutes. + case LoadSample15 = 2 + public init() { + self = .LoadSample1 + } +} + +/// An `Ice.InputStream` extension to read `LoadSample` enumerated values from the stream. +public extension Ice.InputStream { + /// Read an enumerated value. + /// + /// - returns: `LoadSample` - The enumarated value. + func read() throws -> LoadSample { + let rawValue: Swift.UInt8 = try read(enumMaxValue: 2) + guard let val = LoadSample(rawValue: rawValue) else { + throw Ice.MarshalException(reason: "invalid enum value") + } + return val + } + + /// Read an optional enumerated value from the stream. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `LoadSample` - The enumerated value. + func read(tag: Swift.Int32) throws -> LoadSample? { + guard try readOptional(tag: tag, expectedFormat: .Size) else { + return nil + } + return try read() as LoadSample + } +} + +/// An `Ice.OutputStream` extension to write `LoadSample` enumerated values to the stream. +public extension Ice.OutputStream { + /// Writes an enumerated value to the stream. + /// + /// parameter _: `LoadSample` - The enumerator to write. + func write(_ v: LoadSample) { + write(enum: v.rawValue, maxValue: 2) + } + + /// Writes an optional enumerated value to the stream. + /// + /// parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// parameter _: `LoadSample` - The enumerator to write. + func write(tag: Swift.Int32, value: LoadSample?) { + guard let v = value else { + return + } + write(tag: tag, val: v.rawValue, maxValue: 2) + } +} + +/// Traits for Slice interface `Query`. +public struct QueryTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::Query"] + public static let staticId = "::IceGrid::Query" +} + +/// Traits for Slice interface `Registry`. +public struct RegistryTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::Registry"] + public static let staticId = "::IceGrid::Registry" +} + +/// Traits for Slice interface `Locator`. +public struct LocatorTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Locator", "::Ice::Object", "::IceGrid::Locator"] + public static let staticId = "::IceGrid::Locator" +} + +/// The IceGrid query interface. This interface is accessible to +/// Ice clients who wish to look up well-known objects. +/// +/// QueryPrx Methods: +/// +/// - findObjectById: Find a well-known object by identity. +/// +/// - findObjectByIdAsync: Find a well-known object by identity. +/// +/// - findObjectByType: Find a well-known object by type. +/// +/// - findObjectByTypeAsync: Find a well-known object by type. +/// +/// - findObjectByTypeOnLeastLoadedNode: Find a well-known object by type on the least-loaded node. +/// +/// - findObjectByTypeOnLeastLoadedNodeAsync: Find a well-known object by type on the least-loaded node. +/// +/// - findAllObjectsByType: Find all the well-known objects with the given type. +/// +/// - findAllObjectsByTypeAsync: Find all the well-known objects with the given type. +/// +/// - findAllReplicas: Find all the object replicas associated with the given proxy. +/// +/// - findAllReplicasAsync: Find all the object replicas associated with the given proxy. +public protocol QueryPrx: Ice.ObjectPrx {} + +private final class QueryPrxI: Ice.ObjectPrxI, QueryPrx { + public override class func ice_staticId() -> Swift.String { + return QueryTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `QueryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `QueryPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: QueryPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> QueryPrx? { + return try QueryPrxI.checkedCast(prx: prx, facet: facet, context: context) as QueryPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `QueryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `QueryPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: QueryPrx.Protocol, facet: Swift.String? = nil) -> QueryPrx { + return QueryPrxI.uncheckedCast(prx: prx, facet: facet) as QueryPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `QueryPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: QueryPrx.Protocol) -> Swift.String { + return QueryTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `QueryPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `QueryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `QueryPrx?` - The extracted proxy + func read(_ type: QueryPrx.Protocol) throws -> QueryPrx? { + return try read() as QueryPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `QueryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `QueryPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: QueryPrx.Protocol) throws -> QueryPrx? { + return try read(tag: tag) as QueryPrxI? + } +} + +/// The IceGrid query interface. This interface is accessible to +/// Ice clients who wish to look up well-known objects. +/// +/// QueryPrx Methods: +/// +/// - findObjectById: Find a well-known object by identity. +/// +/// - findObjectByIdAsync: Find a well-known object by identity. +/// +/// - findObjectByType: Find a well-known object by type. +/// +/// - findObjectByTypeAsync: Find a well-known object by type. +/// +/// - findObjectByTypeOnLeastLoadedNode: Find a well-known object by type on the least-loaded node. +/// +/// - findObjectByTypeOnLeastLoadedNodeAsync: Find a well-known object by type on the least-loaded node. +/// +/// - findAllObjectsByType: Find all the well-known objects with the given type. +/// +/// - findAllObjectsByTypeAsync: Find all the well-known objects with the given type. +/// +/// - findAllReplicas: Find all the object replicas associated with the given proxy. +/// +/// - findAllReplicasAsync: Find all the object replicas associated with the given proxy. +public extension QueryPrx { + /// Find a well-known object by identity. + /// + /// - parameter _: `Ice.Identity` The identity. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null if no such object has been found. + func findObjectById(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "findObjectById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Find a well-known object by identity. + /// + /// - parameter _: `Ice.Identity` The identity. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findObjectByIdAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findObjectById", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Find a well-known object by type. If there are several objects + /// registered for the given type, the object is randomly + /// selected. + /// + /// - parameter _: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null, if no such object has been found. + func findObjectByType(_ iceP_type: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "findObjectByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Find a well-known object by type. If there are several objects + /// registered for the given type, the object is randomly + /// selected. + /// + /// - parameter _: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findObjectByTypeAsync(_ iceP_type: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findObjectByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Find a well-known object by type on the least-loaded node. If + /// the registry does not know which node hosts the object + /// (for example, because the object was registered with a direct proxy), the + /// registry assumes the object is hosted on a node that has a load + /// average of 1.0. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter sample: `LoadSample` The sampling interval. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null, if no such object has been found. + func findObjectByTypeOnLeastLoadedNode(type iceP_type: Swift.String, sample iceP_sample: LoadSample, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "findObjectByTypeOnLeastLoadedNode", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + ostr.write(iceP_sample) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Find a well-known object by type on the least-loaded node. If + /// the registry does not know which node hosts the object + /// (for example, because the object was registered with a direct proxy), the + /// registry assumes the object is hosted on a node that has a load + /// average of 1.0. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter sample: `LoadSample` The sampling interval. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findObjectByTypeOnLeastLoadedNodeAsync(type iceP_type: Swift.String, sample iceP_sample: LoadSample, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findObjectByTypeOnLeastLoadedNode", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + ostr.write(iceP_sample) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Find all the well-known objects with the given type. + /// + /// - parameter _: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectProxySeq` - The proxies or an empty sequence, if no such objects + /// have been found. + func findAllObjectsByType(_ iceP_type: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectProxySeq { + return try _impl._invoke(operation: "findAllObjectsByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectProxySeq = try Ice.ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Find all the well-known objects with the given type. + /// + /// - parameter _: `Swift.String` The object type. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findAllObjectsByTypeAsync(_ iceP_type: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findAllObjectsByType", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectProxySeq = try Ice.ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Find all the object replicas associated with the given + /// proxy. If the given proxy is not an indirect proxy from a + /// replica group, an empty sequence is returned. + /// + /// - parameter _: `Ice.ObjectPrx?` The object proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectProxySeq` - The proxies of each object replica or an empty sequence, + /// if the given proxy is not from a replica group. + func findAllReplicas(_ iceP_proxy: Ice.ObjectPrx?, context: Ice.Context? = nil) throws -> Ice.ObjectProxySeq { + return try _impl._invoke(operation: "findAllReplicas", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_proxy) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectProxySeq = try Ice.ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Find all the object replicas associated with the given + /// proxy. If the given proxy is not an indirect proxy from a + /// replica group, an empty sequence is returned. + /// + /// - parameter _: `Ice.ObjectPrx?` The object proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func findAllReplicasAsync(_ iceP_proxy: Ice.ObjectPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "findAllReplicas", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_proxy) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectProxySeq = try Ice.ObjectProxySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The IceGrid registry allows clients create sessions +/// directly with the registry. +/// +/// RegistryPrx Methods: +/// +/// - createSession: Create a client session. +/// +/// - createSessionAsync: Create a client session. +/// +/// - createAdminSession: Create an administrative session. +/// +/// - createAdminSessionAsync: Create an administrative session. +/// +/// - createSessionFromSecureConnection: Create a client session from a secure connection. +/// +/// - createSessionFromSecureConnectionAsync: Create a client session from a secure connection. +/// +/// - createAdminSessionFromSecureConnection: Create an administrative session from a secure connection. +/// +/// - createAdminSessionFromSecureConnectionAsync: Create an administrative session from a secure connection. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - getSessionTimeoutAsync: Get the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +/// +/// - getACMTimeoutAsync: Get the value of the ACM timeout. +public protocol RegistryPrx: Ice.ObjectPrx {} + +private final class RegistryPrxI: Ice.ObjectPrxI, RegistryPrx { + public override class func ice_staticId() -> Swift.String { + return RegistryTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `RegistryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `RegistryPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: RegistryPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> RegistryPrx? { + return try RegistryPrxI.checkedCast(prx: prx, facet: facet, context: context) as RegistryPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `RegistryPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `RegistryPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: RegistryPrx.Protocol, facet: Swift.String? = nil) -> RegistryPrx { + return RegistryPrxI.uncheckedCast(prx: prx, facet: facet) as RegistryPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `RegistryPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: RegistryPrx.Protocol) -> Swift.String { + return RegistryTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `RegistryPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `RegistryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RegistryPrx?` - The extracted proxy + func read(_ type: RegistryPrx.Protocol) throws -> RegistryPrx? { + return try read() as RegistryPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `RegistryPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `RegistryPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: RegistryPrx.Protocol) throws -> RegistryPrx? { + return try read(tag: tag) as RegistryPrxI? + } +} + +/// The IceGrid registry allows clients create sessions +/// directly with the registry. +/// +/// RegistryPrx Methods: +/// +/// - createSession: Create a client session. +/// +/// - createSessionAsync: Create a client session. +/// +/// - createAdminSession: Create an administrative session. +/// +/// - createAdminSessionAsync: Create an administrative session. +/// +/// - createSessionFromSecureConnection: Create a client session from a secure connection. +/// +/// - createSessionFromSecureConnectionAsync: Create a client session from a secure connection. +/// +/// - createAdminSessionFromSecureConnection: Create an administrative session from a secure connection. +/// +/// - createAdminSessionFromSecureConnectionAsync: Create an administrative session from a secure connection. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - getSessionTimeoutAsync: Get the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +/// +/// - getACMTimeoutAsync: Get the value of the ACM timeout. +public extension RegistryPrx { + /// Create a client session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createSession(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "createSession", + mode: .Normal, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a client session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionAsync(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createSession", + mode: .Normal, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create an administrative session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `AdminSessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createAdminSession(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil) throws -> AdminSessionPrx? { + return try _impl._invoke(operation: "createAdminSession", + mode: .Normal, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: AdminSessionPrx? = try istr.read(AdminSessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create an administrative session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createAdminSessionAsync(userId iceP_userId: Swift.String, password iceP_password: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createAdminSession", + mode: .Normal, + write: { ostr in + ostr.write(iceP_userId) + ostr.write(iceP_password) + }, + read: { istr in + let iceP_returnValue: AdminSessionPrx? = try istr.read(AdminSessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create a client session from a secure connection. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createSessionFromSecureConnection(context: Ice.Context? = nil) throws -> SessionPrx? { + return try _impl._invoke(operation: "createSessionFromSecureConnection", + mode: .Normal, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a client session from a secure connection. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createSessionFromSecureConnectionAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createSessionFromSecureConnection", + mode: .Normal, + read: { istr in + let iceP_returnValue: SessionPrx? = try istr.read(SessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create an administrative session from a secure connection. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `AdminSessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createAdminSessionFromSecureConnection(context: Ice.Context? = nil) throws -> AdminSessionPrx? { + return try _impl._invoke(operation: "createAdminSessionFromSecureConnection", + mode: .Normal, + read: { istr in + let iceP_returnValue: AdminSessionPrx? = try istr.read(AdminSessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create an administrative session from a secure connection. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createAdminSessionFromSecureConnectionAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "createAdminSessionFromSecureConnection", + mode: .Normal, + read: { istr in + let iceP_returnValue: AdminSessionPrx? = try istr.read(AdminSessionPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as PermissionDeniedException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the session timeout. If a client or administrative client + /// doesn't call the session keepAlive method in the time interval + /// defined by this timeout, IceGrid might reap the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getSessionTimeout(context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getSessionTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the session timeout. If a client or administrative client + /// doesn't call the session keepAlive method in the time interval + /// defined by this timeout, IceGrid might reap the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSessionTimeoutAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSessionTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the value of the ACM timeout. Clients supporting ACM + /// connection heartbeats can enable them instead of explicitly + /// sending keep alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getACMTimeout(context: Ice.Context? = nil) throws -> Swift.Int32 { + return try _impl._invoke(operation: "getACMTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the value of the ACM timeout. Clients supporting ACM + /// connection heartbeats can enable them instead of explicitly + /// sending keep alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getACMTimeoutAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getACMTimeout", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.Int32 = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// The IceGrid locator interface provides access to the Query +/// and Registry object of the IceGrid registry. +/// +/// LocatorPrx Methods: +/// +/// - getLocalRegistry: Get the proxy of the registry object hosted by this IceGrid registry. +/// +/// - getLocalRegistryAsync: Get the proxy of the registry object hosted by this IceGrid registry. +/// +/// - getLocalQuery: Get the proxy of the query object hosted by this IceGrid registry. +/// +/// - getLocalQueryAsync: Get the proxy of the query object hosted by this IceGrid registry. +public protocol LocatorPrx: Ice.LocatorPrx {} + +private final class LocatorPrxI: Ice.ObjectPrxI, LocatorPrx { + public override class func ice_staticId() -> Swift.String { + return LocatorTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `LocatorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `LocatorPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: LocatorPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> LocatorPrx? { + return try LocatorPrxI.checkedCast(prx: prx, facet: facet, context: context) as LocatorPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `LocatorPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `LocatorPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: LocatorPrx.Protocol, facet: Swift.String? = nil) -> LocatorPrx { + return LocatorPrxI.uncheckedCast(prx: prx, facet: facet) as LocatorPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `LocatorPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: LocatorPrx.Protocol) -> Swift.String { + return LocatorTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `LocatorPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `LocatorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorPrx?` - The extracted proxy + func read(_ type: LocatorPrx.Protocol) throws -> LocatorPrx? { + return try read() as LocatorPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `LocatorPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `LocatorPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: LocatorPrx.Protocol) throws -> LocatorPrx? { + return try read(tag: tag) as LocatorPrxI? + } +} + +/// The IceGrid locator interface provides access to the Query +/// and Registry object of the IceGrid registry. +/// +/// LocatorPrx Methods: +/// +/// - getLocalRegistry: Get the proxy of the registry object hosted by this IceGrid registry. +/// +/// - getLocalRegistryAsync: Get the proxy of the registry object hosted by this IceGrid registry. +/// +/// - getLocalQuery: Get the proxy of the query object hosted by this IceGrid registry. +/// +/// - getLocalQueryAsync: Get the proxy of the query object hosted by this IceGrid registry. +public extension LocatorPrx { + /// Get the proxy of the registry object hosted by this IceGrid + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `RegistryPrx?` - The proxy of the registry object. + func getLocalRegistry(context: Ice.Context? = nil) throws -> RegistryPrx? { + return try _impl._invoke(operation: "getLocalRegistry", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: RegistryPrx? = try istr.read(RegistryPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the proxy of the registry object hosted by this IceGrid + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getLocalRegistryAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getLocalRegistry", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: RegistryPrx? = try istr.read(RegistryPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get the proxy of the query object hosted by this IceGrid + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `QueryPrx?` - The proxy of the query object. + func getLocalQuery(context: Ice.Context? = nil) throws -> QueryPrx? { + return try _impl._invoke(operation: "getLocalQuery", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: QueryPrx? = try istr.read(QueryPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the proxy of the query object hosted by this IceGrid + /// registry. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getLocalQueryAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getLocalQuery", + mode: .Idempotent, + read: { istr in + let iceP_returnValue: QueryPrx? = try istr.read(QueryPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Query` servants. +public struct QueryDisp: Ice.Disp { + public let servant: Query + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Query) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "findAllObjectsByType": + return try servant._iceD_findAllObjectsByType(incoming: request, current: current) + case "findAllReplicas": + return try servant._iceD_findAllReplicas(incoming: request, current: current) + case "findObjectById": + return try servant._iceD_findObjectById(incoming: request, current: current) + case "findObjectByType": + return try servant._iceD_findObjectByType(incoming: request, current: current) + case "findObjectByTypeOnLeastLoadedNode": + return try servant._iceD_findObjectByTypeOnLeastLoadedNode(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? QueryDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? QueryDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? QueryDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? QueryDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The IceGrid query interface. This interface is accessible to +/// Ice clients who wish to look up well-known objects. +public protocol Query { + /// Find a well-known object by identity. + /// + /// - parameter id: `Ice.Identity` The identity. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null if no such object has been found. + func findObjectById(id: Ice.Identity, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Find a well-known object by type. If there are several objects + /// registered for the given type, the object is randomly + /// selected. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null, if no such object has been found. + func findObjectByType(type: Swift.String, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Find a well-known object by type on the least-loaded node. If + /// the registry does not know which node hosts the object + /// (for example, because the object was registered with a direct proxy), the + /// registry assumes the object is hosted on a node that has a load + /// average of 1.0. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter sample: `LoadSample` The sampling interval. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy or null, if no such object has been found. + func findObjectByTypeOnLeastLoadedNode(type: Swift.String, sample: LoadSample, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Find all the well-known objects with the given type. + /// + /// - parameter type: `Swift.String` The object type. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectProxySeq` - The proxies or an empty sequence, if no such objects + /// have been found. + func findAllObjectsByType(type: Swift.String, current: Ice.Current) throws -> Ice.ObjectProxySeq + + /// Find all the object replicas associated with the given + /// proxy. If the given proxy is not an indirect proxy from a + /// replica group, an empty sequence is returned. + /// + /// - parameter proxy: `Ice.ObjectPrx?` The object proxy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectProxySeq` - The proxies of each object replica or an empty sequence, + /// if the given proxy is not from a replica group. + func findAllReplicas(proxy: Ice.ObjectPrx?, current: Ice.Current) throws -> Ice.ObjectProxySeq +} + + +/// Dispatcher for `Registry` servants. +public struct RegistryDisp: Ice.Disp { + public let servant: Registry + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Registry) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "createAdminSession": + return try servant._iceD_createAdminSession(incoming: request, current: current) + case "createAdminSessionFromSecureConnection": + return try servant._iceD_createAdminSessionFromSecureConnection(incoming: request, current: current) + case "createSession": + return try servant._iceD_createSession(incoming: request, current: current) + case "createSessionFromSecureConnection": + return try servant._iceD_createSessionFromSecureConnection(incoming: request, current: current) + case "getACMTimeout": + return try servant._iceD_getACMTimeout(incoming: request, current: current) + case "getSessionTimeout": + return try servant._iceD_getSessionTimeout(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? RegistryDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? RegistryDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? RegistryDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? RegistryDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The IceGrid registry allows clients create sessions +/// directly with the registry. +public protocol Registry { + /// Create a client session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createSession(userId: Swift.String, password: Swift.String, current: Ice.Current) throws -> SessionPrx? + + /// Create an administrative session. + /// + /// - parameter userId: `Swift.String` The user id. + /// + /// - parameter password: `Swift.String` The password for the given user id. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `AdminSessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createAdminSession(userId: Swift.String, password: Swift.String, current: Ice.Current) throws -> AdminSessionPrx? + + /// Create a client session from a secure connection. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `SessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createSessionFromSecureConnection(current: Ice.Current) throws -> SessionPrx? + + /// Create an administrative session from a secure connection. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `AdminSessionPrx?` - A proxy for the newly created session. + /// + /// - throws: + /// + /// - PermissionDeniedException - Raised if the password for + /// the given user id is not correct, or if the user is not allowed + /// access. + func createAdminSessionFromSecureConnection(current: Ice.Current) throws -> AdminSessionPrx? + + /// Get the session timeout. If a client or administrative client + /// doesn't call the session keepAlive method in the time interval + /// defined by this timeout, IceGrid might reap the session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getSessionTimeout(current: Ice.Current) throws -> Swift.Int32 + + /// Get the value of the ACM timeout. Clients supporting ACM + /// connection heartbeats can enable them instead of explicitly + /// sending keep alives requests. + /// + /// NOTE: This method is only available since Ice 3.6. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.Int32` - The timeout (in seconds). + func getACMTimeout(current: Ice.Current) throws -> Swift.Int32 +} + + +/// Dispatcher for `Locator` servants. +public struct LocatorDisp: Ice.Disp { + public let servant: Locator + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Locator) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "findAdapterById": + return try servant._iceD_findAdapterById(incoming: request, current: current) + case "findObjectById": + return try servant._iceD_findObjectById(incoming: request, current: current) + case "getLocalQuery": + return try servant._iceD_getLocalQuery(incoming: request, current: current) + case "getLocalRegistry": + return try servant._iceD_getLocalRegistry(incoming: request, current: current) + case "getRegistry": + return try servant._iceD_getRegistry(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? LocatorDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// The IceGrid locator interface provides access to the Query +/// and Registry object of the IceGrid registry. +public protocol Locator: Ice.Locator { + /// Get the proxy of the registry object hosted by this IceGrid + /// registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `RegistryPrx?` - The proxy of the registry object. + func getLocalRegistry(current: Ice.Current) throws -> RegistryPrx? + + /// Get the proxy of the query object hosted by this IceGrid + /// registry. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `QueryPrx?` - The proxy of the query object. + func getLocalQuery(current: Ice.Current) throws -> QueryPrx? +} + +/// The IceGrid query interface. This interface is accessible to +/// Ice clients who wish to look up well-known objects. +/// +/// Query Methods: +/// +/// - findObjectById: Find a well-known object by identity. +/// +/// - findObjectByType: Find a well-known object by type. +/// +/// - findObjectByTypeOnLeastLoadedNode: Find a well-known object by type on the least-loaded node. +/// +/// - findAllObjectsByType: Find all the well-known objects with the given type. +/// +/// - findAllReplicas: Find all the object replicas associated with the given proxy. +public extension Query { + func _iceD_findObjectById(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + let iceP_returnValue = try self.findObjectById(id: iceP_id, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_findObjectByType(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_type: Swift.String = try inS.read { istr in + let iceP_type: Swift.String = try istr.read() + return iceP_type + } + + let iceP_returnValue = try self.findObjectByType(type: iceP_type, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_findObjectByTypeOnLeastLoadedNode(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_type, iceP_sample): (Swift.String, LoadSample) = try inS.read { istr in + let iceP_type: Swift.String = try istr.read() + let iceP_sample: LoadSample = try istr.read() + return (iceP_type, iceP_sample) + } + + let iceP_returnValue = try self.findObjectByTypeOnLeastLoadedNode(type: iceP_type, sample: iceP_sample, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_findAllObjectsByType(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_type: Swift.String = try inS.read { istr in + let iceP_type: Swift.String = try istr.read() + return iceP_type + } + + let iceP_returnValue = try self.findAllObjectsByType(type: iceP_type, current: current) + + return inS.setResult{ ostr in + Ice.ObjectProxySeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_findAllReplicas(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_proxy: Ice.ObjectPrx? = try inS.read { istr in + let iceP_proxy: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_proxy + } + + let iceP_returnValue = try self.findAllReplicas(proxy: iceP_proxy, current: current) + + return inS.setResult{ ostr in + Ice.ObjectProxySeqHelper.write(to: ostr, value: iceP_returnValue) + } + } +} + +/// The IceGrid registry allows clients create sessions +/// directly with the registry. +/// +/// Registry Methods: +/// +/// - createSession: Create a client session. +/// +/// - createAdminSession: Create an administrative session. +/// +/// - createSessionFromSecureConnection: Create a client session from a secure connection. +/// +/// - createAdminSessionFromSecureConnection: Create an administrative session from a secure connection. +/// +/// - getSessionTimeout: Get the session timeout. +/// +/// - getACMTimeout: Get the value of the ACM timeout. +public extension Registry { + func _iceD_createSession(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_userId, iceP_password): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_userId: Swift.String = try istr.read() + let iceP_password: Swift.String = try istr.read() + return (iceP_userId, iceP_password) + } + + let iceP_returnValue = try self.createSession(userId: iceP_userId, password: iceP_password, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_createAdminSession(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_userId, iceP_password): (Swift.String, Swift.String) = try inS.read { istr in + let iceP_userId: Swift.String = try istr.read() + let iceP_password: Swift.String = try istr.read() + return (iceP_userId, iceP_password) + } + + let iceP_returnValue = try self.createAdminSession(userId: iceP_userId, password: iceP_password, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_createSessionFromSecureConnection(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.createSessionFromSecureConnection(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_createAdminSessionFromSecureConnection(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.createAdminSessionFromSecureConnection(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getSessionTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSessionTimeout(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getACMTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getACMTimeout(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} + +/// The IceGrid locator interface provides access to the Query +/// and Registry object of the IceGrid registry. +/// +/// Locator Methods: +/// +/// - getLocalRegistry: Get the proxy of the registry object hosted by this IceGrid registry. +/// +/// - getLocalQuery: Get the proxy of the query object hosted by this IceGrid registry. +public extension Locator { + func _iceD_getLocalRegistry(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getLocalRegistry(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getLocalQuery(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getLocalQuery(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/IceGrid/Session.swift b/Sources/IceGrid/Session.swift new file mode 100644 index 0000000..727323f --- /dev/null +++ b/Sources/IceGrid/Session.swift @@ -0,0 +1,630 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Session.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit +import Glacier2 + +/// Traits for Slice interface `Session`. +public struct SessionTraits: Ice.SliceTraits { + public static let staticIds = ["::Glacier2::Session", "::Ice::Object", "::IceGrid::Session"] + public static let staticId = "::IceGrid::Session" +} + +/// A session object is used by IceGrid clients to allocate and +/// release objects. Client sessions are created either via the +/// Registry object or via the registry client SessionManager +/// object. +/// +/// SessionPrx Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - keepAliveAsync: Keep the session alive. +/// +/// - allocateObjectById: Allocate an object. +/// +/// - allocateObjectByIdAsync: Allocate an object. +/// +/// - allocateObjectByType: Allocate an object with the given type. +/// +/// - allocateObjectByTypeAsync: Allocate an object with the given type. +/// +/// - releaseObject: Release an object that was allocated using allocateObjectById or allocateObjectByType. +/// +/// - releaseObjectAsync: Release an object that was allocated using allocateObjectById or allocateObjectByType. +/// +/// - setAllocationTimeout: Set the allocation timeout. +/// +/// - setAllocationTimeoutAsync: Set the allocation timeout. +public protocol SessionPrx: Glacier2.SessionPrx {} + +private final class SessionPrxI: Ice.ObjectPrxI, SessionPrx { + public override class func ice_staticId() -> Swift.String { + return SessionTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `SessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `SessionPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: SessionPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> SessionPrx? { + return try SessionPrxI.checkedCast(prx: prx, facet: facet, context: context) as SessionPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `SessionPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `SessionPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: SessionPrx.Protocol, facet: Swift.String? = nil) -> SessionPrx { + return SessionPrxI.uncheckedCast(prx: prx, facet: facet) as SessionPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `SessionPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: SessionPrx.Protocol) -> Swift.String { + return SessionTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `SessionPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `SessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionPrx?` - The extracted proxy + func read(_ type: SessionPrx.Protocol) throws -> SessionPrx? { + return try read() as SessionPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `SessionPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `SessionPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: SessionPrx.Protocol) throws -> SessionPrx? { + return try read(tag: tag) as SessionPrxI? + } +} + +/// A session object is used by IceGrid clients to allocate and +/// release objects. Client sessions are created either via the +/// Registry object or via the registry client SessionManager +/// object. +/// +/// SessionPrx Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - keepAliveAsync: Keep the session alive. +/// +/// - allocateObjectById: Allocate an object. +/// +/// - allocateObjectByIdAsync: Allocate an object. +/// +/// - allocateObjectByType: Allocate an object with the given type. +/// +/// - allocateObjectByTypeAsync: Allocate an object with the given type. +/// +/// - releaseObject: Release an object that was allocated using allocateObjectById or allocateObjectByType. +/// +/// - releaseObjectAsync: Release an object that was allocated using allocateObjectById or allocateObjectByType. +/// +/// - setAllocationTimeout: Set the allocation timeout. +/// +/// - setAllocationTimeoutAsync: Set the allocation timeout. +public extension SessionPrx { + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func keepAlive(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "keepAlive", + mode: .Idempotent, + context: context) + } + + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func keepAliveAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "keepAlive", + mode: .Idempotent, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Allocate an object. Depending on the allocation timeout, this + /// operation might hang until the object is available or until the + /// timeout is reached. + /// + /// - parameter _: `Ice.Identity` The identity of the object to allocate. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy of the allocated object. + /// + /// - throws: + /// + /// - AllocationException - Raised if the object can't be + /// allocated. + /// + /// - ObjectNotRegisteredException - Raised if the object with + /// the given identity is not registered with the registry. + func allocateObjectById(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "allocateObjectById", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Allocate an object. Depending on the allocation timeout, this + /// operation might hang until the object is available or until the + /// timeout is reached. + /// + /// - parameter _: `Ice.Identity` The identity of the object to allocate. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func allocateObjectByIdAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "allocateObjectById", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Allocate an object with the given type. Depending on the + /// allocation timeout, this operation can block until an object + /// becomes available or until the timeout is reached. + /// + /// - parameter _: `Swift.String` The type of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The proxy of the allocated object. + /// + /// - throws: + /// + /// - AllocationException - Raised if the object could not be allocated. + func allocateObjectByType(_ iceP_type: Swift.String, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "allocateObjectByType", + mode: .Normal, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Allocate an object with the given type. Depending on the + /// allocation timeout, this operation can block until an object + /// becomes available or until the timeout is reached. + /// + /// - parameter _: `Swift.String` The type of the object. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func allocateObjectByTypeAsync(_ iceP_type: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "allocateObjectByType", + mode: .Normal, + write: { ostr in + ostr.write(iceP_type) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Release an object that was allocated using allocateObjectById or + /// allocateObjectByType. + /// + /// - parameter _: `Ice.Identity` The identity of the object to release. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - AllocationException - Raised if the given object can't be + /// released. This might happen if the object isn't allocatable or + /// isn't allocated by the session. + /// + /// - ObjectNotRegisteredException - Raised if the object with + /// the given identity is not registered with the registry. + func releaseObject(_ iceP_id: Ice.Identity, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "releaseObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Release an object that was allocated using allocateObjectById or + /// allocateObjectByType. + /// + /// - parameter _: `Ice.Identity` The identity of the object to release. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func releaseObjectAsync(_ iceP_id: Ice.Identity, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "releaseObject", + mode: .Normal, + write: { ostr in + ostr.write(iceP_id) + }, + userException:{ ex in + do { + throw ex + } catch let error as AllocationException { + throw error + } catch let error as ObjectNotRegisteredException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Set the allocation timeout. If no objects are available for an + /// allocation request, a call to allocateObjectById or + /// allocateObjectByType will block for the duration of this + /// timeout. + /// + /// - parameter _: `Swift.Int32` The timeout in milliseconds. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func setAllocationTimeout(_ iceP_timeout: Swift.Int32, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "setAllocationTimeout", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_timeout) + }, + context: context) + } + + /// Set the allocation timeout. If no objects are available for an + /// allocation request, a call to allocateObjectById or + /// allocateObjectByType will block for the duration of this + /// timeout. + /// + /// - parameter _: `Swift.Int32` The timeout in milliseconds. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func setAllocationTimeoutAsync(_ iceP_timeout: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "setAllocationTimeout", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_timeout) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Session` servants. +public struct SessionDisp: Ice.Disp { + public let servant: Session + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Session) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "allocateObjectById": + return try servant._iceD_allocateObjectById(incoming: request, current: current) + case "allocateObjectByType": + return try servant._iceD_allocateObjectByType(incoming: request, current: current) + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? SessionDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "keepAlive": + return try servant._iceD_keepAlive(incoming: request, current: current) + case "releaseObject": + return try servant._iceD_releaseObject(incoming: request, current: current) + case "setAllocationTimeout": + return try servant._iceD_setAllocationTimeout(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// A session object is used by IceGrid clients to allocate and +/// release objects. Client sessions are created either via the +/// Registry object or via the registry client SessionManager +/// object. +public protocol Session: Glacier2.Session { + /// Keep the session alive. Clients should call this operation + /// regularly to prevent the server from reaping the session. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func keepAlive(current: Ice.Current) throws + + /// Allocate an object. Depending on the allocation timeout, this + /// operation might hang until the object is available or until the + /// timeout is reached. + /// + /// - parameter id: `Ice.Identity` The identity of the object to allocate. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func allocateObjectByIdAsync(id: Ice.Identity, current: Ice.Current) -> PromiseKit.Promise + + /// Allocate an object with the given type. Depending on the + /// allocation timeout, this operation can block until an object + /// becomes available or until the timeout is reached. + /// + /// - parameter type: `Swift.String` The type of the object. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func allocateObjectByTypeAsync(type: Swift.String, current: Ice.Current) -> PromiseKit.Promise + + /// Release an object that was allocated using allocateObjectById or + /// allocateObjectByType. + /// + /// - parameter id: `Ice.Identity` The identity of the object to release. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - AllocationException - Raised if the given object can't be + /// released. This might happen if the object isn't allocatable or + /// isn't allocated by the session. + /// + /// - ObjectNotRegisteredException - Raised if the object with + /// the given identity is not registered with the registry. + func releaseObject(id: Ice.Identity, current: Ice.Current) throws + + /// Set the allocation timeout. If no objects are available for an + /// allocation request, a call to allocateObjectById or + /// allocateObjectByType will block for the duration of this + /// timeout. + /// + /// - parameter timeout: `Swift.Int32` The timeout in milliseconds. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func setAllocationTimeout(timeout: Swift.Int32, current: Ice.Current) throws +} + +/// A session object is used by IceGrid clients to allocate and +/// release objects. Client sessions are created either via the +/// Registry object or via the registry client SessionManager +/// object. +/// +/// Session Methods: +/// +/// - keepAlive: Keep the session alive. +/// +/// - allocateObjectById: Allocate an object. +/// +/// - allocateObjectByType: Allocate an object with the given type. +/// +/// - releaseObject: Release an object that was allocated using allocateObjectById or allocateObjectByType. +/// +/// - setAllocationTimeout: Set the allocation timeout. +public extension Session { + func _iceD_keepAlive(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.keepAlive(current: current) + + return inS.setResult() + } + + func _iceD_allocateObjectById(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + return inS.setResultPromise(allocateObjectByIdAsync(id: iceP_id, current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_allocateObjectByType(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_type: Swift.String = try inS.read { istr in + let iceP_type: Swift.String = try istr.read() + return iceP_type + } + + return inS.setResultPromise(allocateObjectByTypeAsync(type: iceP_type, current: current)) { (ostr, retVals) in + let iceP_returnValue = retVals + ostr.write(iceP_returnValue) + } + } + + func _iceD_releaseObject(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_id: Ice.Identity = try inS.read { istr in + let iceP_id: Ice.Identity = try istr.read() + return iceP_id + } + + try self.releaseObject(id: iceP_id, current: current) + + return inS.setResult() + } + + func _iceD_setAllocationTimeout(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_timeout: Swift.Int32 = try inS.read { istr in + let iceP_timeout: Swift.Int32 = try istr.read() + return iceP_timeout + } + + try self.setAllocationTimeout(timeout: iceP_timeout, current: current) + + return inS.setResult() + } +} diff --git a/Sources/IceGrid/UserAccountMapper.swift b/Sources/IceGrid/UserAccountMapper.swift new file mode 100644 index 0000000..9c6c03f --- /dev/null +++ b/Sources/IceGrid/UserAccountMapper.swift @@ -0,0 +1,306 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `UserAccountMapper.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// :nodoc: +public class UserAccountNotFoundException_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return UserAccountNotFoundException.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceGrid_UserAccountNotFoundException() -> Ice.UserExceptionTypeResolver { + return UserAccountNotFoundException_TypeResolver() + } +} + +/// This exception is raised if a user account for a given session +/// identifier can't be found. +open class UserAccountNotFoundException: Ice.UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceGrid::UserAccountNotFoundException" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: UserAccountNotFoundException.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// Traits for Slice interface `UserAccountMapper`. +public struct UserAccountMapperTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceGrid::UserAccountMapper"] + public static let staticId = "::IceGrid::UserAccountMapper" +} + +/// A user account mapper object is used by IceGrid nodes to map +/// session identifiers to user accounts. +/// +/// UserAccountMapperPrx Methods: +/// +/// - getUserAccount: Get the name of the user account for the given user. +/// +/// - getUserAccountAsync: Get the name of the user account for the given user. +public protocol UserAccountMapperPrx: Ice.ObjectPrx {} + +private final class UserAccountMapperPrxI: Ice.ObjectPrxI, UserAccountMapperPrx { + public override class func ice_staticId() -> Swift.String { + return UserAccountMapperTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `UserAccountMapperPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `UserAccountMapperPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: UserAccountMapperPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> UserAccountMapperPrx? { + return try UserAccountMapperPrxI.checkedCast(prx: prx, facet: facet, context: context) as UserAccountMapperPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `UserAccountMapperPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `UserAccountMapperPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: UserAccountMapperPrx.Protocol, facet: Swift.String? = nil) -> UserAccountMapperPrx { + return UserAccountMapperPrxI.uncheckedCast(prx: prx, facet: facet) as UserAccountMapperPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `UserAccountMapperPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: UserAccountMapperPrx.Protocol) -> Swift.String { + return UserAccountMapperTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `UserAccountMapperPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `UserAccountMapperPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `UserAccountMapperPrx?` - The extracted proxy + func read(_ type: UserAccountMapperPrx.Protocol) throws -> UserAccountMapperPrx? { + return try read() as UserAccountMapperPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `UserAccountMapperPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `UserAccountMapperPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: UserAccountMapperPrx.Protocol) throws -> UserAccountMapperPrx? { + return try read(tag: tag) as UserAccountMapperPrxI? + } +} + +/// A user account mapper object is used by IceGrid nodes to map +/// session identifiers to user accounts. +/// +/// UserAccountMapperPrx Methods: +/// +/// - getUserAccount: Get the name of the user account for the given user. +/// +/// - getUserAccountAsync: Get the name of the user account for the given user. +public extension UserAccountMapperPrx { + /// Get the name of the user account for the given user. This is + /// used by IceGrid nodes to figure out the user account to use + /// to run servers. + /// + /// - parameter _: `Swift.String` The value of the server descriptor's user + /// attribute. If this attribute is not defined, and the server's + /// activation mode is session, the default value of + /// user is the session identifier. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The user account name. + /// + /// - throws: + /// + /// - UserAccountNotFoundException - Raised if no user account + /// is found for the given user. + func getUserAccount(_ iceP_user: Swift.String, context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getUserAccount", + mode: .Normal, + write: { ostr in + ostr.write(iceP_user) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as UserAccountNotFoundException { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Get the name of the user account for the given user. This is + /// used by IceGrid nodes to figure out the user account to use + /// to run servers. + /// + /// - parameter _: `Swift.String` The value of the server descriptor's user + /// attribute. If this attribute is not defined, and the server's + /// activation mode is session, the default value of + /// user is the session identifier. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getUserAccountAsync(_ iceP_user: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getUserAccount", + mode: .Normal, + write: { ostr in + ostr.write(iceP_user) + }, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as UserAccountNotFoundException { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `UserAccountMapper` servants. +public struct UserAccountMapperDisp: Ice.Disp { + public let servant: UserAccountMapper + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: UserAccountMapper) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "getUserAccount": + return try servant._iceD_getUserAccount(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? UserAccountMapperDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? UserAccountMapperDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? UserAccountMapperDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? UserAccountMapperDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// A user account mapper object is used by IceGrid nodes to map +/// session identifiers to user accounts. +public protocol UserAccountMapper { + /// Get the name of the user account for the given user. This is + /// used by IceGrid nodes to figure out the user account to use + /// to run servers. + /// + /// - parameter user: `Swift.String` The value of the server descriptor's user + /// attribute. If this attribute is not defined, and the server's + /// activation mode is session, the default value of + /// user is the session identifier. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The user account name. + /// + /// - throws: + /// + /// - UserAccountNotFoundException - Raised if no user account + /// is found for the given user. + func getUserAccount(user: Swift.String, current: Ice.Current) throws -> Swift.String +} + +/// A user account mapper object is used by IceGrid nodes to map +/// session identifiers to user accounts. +/// +/// UserAccountMapper Methods: +/// +/// - getUserAccount: Get the name of the user account for the given user. +public extension UserAccountMapper { + func _iceD_getUserAccount(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_user: Swift.String = try inS.read { istr in + let iceP_user: Swift.String = try istr.read() + return iceP_user + } + + let iceP_returnValue = try self.getUserAccount(user: iceP_user, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/IceImpl/BlobjectFacade.mm b/Sources/IceImpl/BlobjectFacade.mm new file mode 100644 index 0000000..446535f --- /dev/null +++ b/Sources/IceImpl/BlobjectFacade.mm @@ -0,0 +1,46 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "BlobjectFacade.h" +#import "ObjectAdapter.h" +#import "Convert.h" + +#import "Connection.h" + +void +BlobjectFacade::ice_invokeAsync(std::pair inEncaps, + std::function&)> response, + std::function error, + const Ice::Current& current) +{ + ICEBlobjectResponse responseCallback = ^(bool ok, const void* outParams, long count) { + const Ice::Byte* start = static_cast(outParams); + response(ok, std::make_pair(start, start + static_cast(count))); + }; + + ICEBlobjectException exceptionCallback = ^(ICERuntimeException* e) { + error(convertException(e)); + }; + + ICEObjectAdapter* adapter = [ICEObjectAdapter getHandle:current.adapter]; + ICEConnection* con = [ICEConnection getHandle:current.con]; + + @autoreleasepool + { + [_facade facadeInvoke:adapter + inEncapsBytes:const_cast(inEncaps.first) + inEncapsCount:static_cast(inEncaps.second - inEncaps.first) + con:con + name:toNSString(current.id.name) category:toNSString(current.id.category) + facet:toNSString(current.facet) + operation:toNSString(current.operation) + mode:static_cast(current.mode) + context:toNSDictionary(current.ctx) + requestId:current.requestId + encodingMajor:current.encoding.major + encodingMinor:current.encoding.minor + response:responseCallback + exception:exceptionCallback]; + } +} diff --git a/Sources/IceImpl/Communicator.mm b/Sources/IceImpl/Communicator.mm new file mode 100644 index 0000000..63f6be1 --- /dev/null +++ b/Sources/IceImpl/Communicator.mm @@ -0,0 +1,454 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Communicator.h" +#import "ObjectAdapter.h" +#import "ObjectPrx.h" +#import "Logger.h" +#import "ImplicitContext.h" +#import "Properties.h" +#import "IceUtil.h" +#import "BlobjectFacade.h" +#import "Process.h" +#import "PropertiesAdmin.h" +#import "UnsupportedAdminFacet.h" + +#import "LoggerWrapperI.h" +#import "Convert.h" + +#include +#include + +@implementation ICECommunicator + +-(std::shared_ptr) communicator +{ + return std::static_pointer_cast(self.cppObject); +} + +-(void) destroy +{ + self.communicator->destroy(); +} + +-(void) shutdown +{ + self.communicator->shutdown(); +} + +-(void) waitForShutdown +{ + self.communicator->waitForShutdown(); +} + +-(bool) isShutdown +{ + return self.communicator->isShutdown(); +} + +-(id) stringToProxy:(NSString*)str error:(NSError**)error +{ + try + { + auto prx = self.communicator->stringToProxy(fromNSString(str)); + if(prx) + { + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + return [NSNull null]; + } + catch(const std::exception& e) + { + *error = convertException(e); + return nil; + } +} + +-(nullable id) propertyToProxy:(NSString*)property error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto prx = self.communicator->propertyToProxy(fromNSString(property)); + if(prx) + { + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + return [NSNull null]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(NSDictionary*) proxyToProperty:(ICEObjectPrx*)prx property:(NSString*)property error:(NSError* _Nullable * _Nullable)error +{ + return toNSDictionary(self.communicator->proxyToProperty([prx prx], fromNSString(property))); +} + +-(ICEObjectAdapter*) createObjectAdapter:(NSString*)name error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto oa = self.communicator->createObjectAdapter(fromNSString(name)); + return [ICEObjectAdapter getHandle:oa]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(ICEObjectAdapter*) createObjectAdapterWithEndpoints:(NSString*)name endpoints:(NSString*)endpoints error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto oa = self.communicator->createObjectAdapterWithEndpoints(fromNSString(name), fromNSString(endpoints)); + return [ICEObjectAdapter getHandle:oa]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(ICEObjectAdapter*) createObjectAdapterWithRouter:(NSString*)name router:(ICEObjectPrx*)router error:(NSError* _Nullable * _Nullable)error +{ + try + { + assert(router); + auto oa = self.communicator->createObjectAdapterWithRouter(fromNSString(name), + Ice::uncheckedCast([router prx])); + return [ICEObjectAdapter getHandle:oa]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(ICEImplicitContext*) getImplicitContext +{ + auto implicitContext = self.communicator->getImplicitContext(); + return [ICEImplicitContext getHandle:implicitContext]; +} + +// id may be either a Swift logger or a wrapper around a C++ logger +-(id) getLogger +{ + auto logger = self.communicator->getLogger(); + + auto swiftLogger = std::dynamic_pointer_cast(logger); + if(swiftLogger) + { + return swiftLogger->getLogger(); + } + + return [ICELogger getHandle:logger]; +} + +-(nullable ICEObjectPrx*) getDefaultRouter +{ + return [[ICEObjectPrx alloc] initWithCppObjectPrx:self.communicator->getDefaultRouter()]; +} + +-(BOOL) setDefaultRouter:(ICEObjectPrx*)router error:(NSError**)error +{ + try + { + auto r = router ? [router prx] : nullptr; + self.communicator->setDefaultRouter(Ice::uncheckedCast(r)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(nullable ICEObjectPrx*) getDefaultLocator +{ + return [[ICEObjectPrx alloc] initWithCppObjectPrx:self.communicator->getDefaultLocator()]; +} + +-(BOOL) setDefaultLocator:(ICEObjectPrx*)locator error:(NSError**)error +{ + try + { + auto l = locator ? [locator prx] : nullptr; + self.communicator->setDefaultLocator((Ice::uncheckedCast(l))); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(BOOL) flushBatchRequests:(uint8_t)compress error:(NSError**)error +{ + try + { + self.communicator->flushBatchRequests(Ice::CompressBatch(compress)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) flushBatchRequestsAsync:(uint8_t)compress + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent +{ + try + { + self.communicator->flushBatchRequestsAsync(Ice::CompressBatch(compress), + [exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }, + [sent](bool sentSynchronously) + { + if(sent) + { + sent(sentSynchronously); + } + }); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(nullable ICEObjectPrx*) createAdmin:(ICEObjectAdapter* _Nullable)adminAdapter + name:(NSString*)name + category:(NSString*)category + error:(NSError**)error +{ + + try + { + auto ident = Ice::Identity{fromNSString(name), fromNSString(category)}; + auto adapter = adminAdapter ? [adminAdapter objectAdapter] : nullptr; + auto prx = self.communicator->createAdmin(adapter, ident); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } + +} + +-(nullable id) getAdmin:(NSError**)error +{ + try + { + auto adminPrx = self.communicator->getAdmin(); + return adminPrx ? [[ICEObjectPrx alloc] initWithCppObjectPrx:adminPrx] : [NSNull null]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(BOOL) addAdminFacet:(id)facade facet:(NSString*)facet error:(NSError**)error +{ + try + { + auto servant = std::make_shared(facade); + self.communicator->addAdminFacet(servant, fromNSString(facet)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(id) removeAdminFacet:(NSString*)facet error:(NSError**)error +{ + try + { + // servant can either be a Swift wrapped facet or a builtin admin facet + return [self facetToFacade:self.communicator->removeAdminFacet(fromNSString(facet))]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable id) findAdminFacet:(NSString*)facet error:(NSError**)error +{ + try + { + // servant can either be null, a Swift wrapped facet, or a builtin admin facet + auto servant = self.communicator->findAdminFacet(fromNSString(facet)); + + if(!servant) + { + return [NSNull null]; + } + + return [self facetToFacade:servant]; + + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable NSDictionary>*) findAllAdminFacets:(NSError**)error +{ + try + { + NSMutableDictionary>* facets = [NSMutableDictionary dictionary]; + + for(const auto& d : self.communicator->findAllAdminFacets()) + { + [facets setObject:[self facetToFacade:d.second] forKey:toNSString(d.first)]; + } + + return facets; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(ICEProperties*) getProperties +{ + auto props = self.communicator->getProperties(); + return [ICEProperties getHandle:props]; +} + +-(nullable dispatch_queue_t) getClientDispatchQueue:(NSError* _Nullable * _Nullable)error +{ + try + { + return self.communicator->getClientDispatchQueue(); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable dispatch_queue_t) getServerDispatchQueue:(NSError* _Nullable * _Nullable)error +{ + try + { + return self.communicator->getServerDispatchQueue(); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(void) getDefaultEncoding:(uint8_t*)major minor:(uint8_t*)minor +{ + auto defaultEncoding = IceInternal::getInstance(self.communicator)->defaultsAndOverrides()->defaultEncoding; + *major = defaultEncoding.major; + *minor = defaultEncoding.minor; +} + +-(uint8_t) getDefaultFormat +{ + return static_cast(IceInternal::getInstance(self.communicator)->defaultsAndOverrides()->defaultFormat); +} + +-(id) facetToFacade:(const std::shared_ptr&) servant +{ + if(!servant) + { + return nil; + } + + auto blobjectFacade = std::dynamic_pointer_cast(servant); + if(blobjectFacade) + { + return blobjectFacade->getFacade(); + } + + Class factory = [ICEUtil adminFacetFactory]; + + auto process = std::dynamic_pointer_cast(servant); + if(process) + { + return [factory createProcess:self handle:[ICEProcess getHandle:process]]; + } + + auto propertiesAdmin = std::dynamic_pointer_cast(servant); + if(propertiesAdmin) + { + return [factory createProperties:self handle: [ICEPropertiesAdmin getHandle:propertiesAdmin]]; + } + + return [factory createUnsupported:self handle:[ICEUnsupportedAdminFacet getHandle:servant]]; +} + +-(void) setSslCertificateVerifier:(nullable bool (^)(id))verifier +{ + auto pluginManager = self.communicator->getPluginManager(); + auto plugin = std::dynamic_pointer_cast(pluginManager->getPlugin("IceSSL")); + assert(plugin); + + plugin->setCertificateVerifier([verifier] (const std::shared_ptr& info) -> bool { + return verifier(createConnectionInfo(info)); + }); +} + +-(void) setSslPasswordPrompt:(nullable NSString* (^)())prompt; +{ + auto pluginManager = self.communicator->getPluginManager(); + auto plugin = std::dynamic_pointer_cast(pluginManager->getPlugin("IceSSL")); + assert(plugin); + plugin->setPasswordPrompt([prompt] { + return fromNSString(prompt()); + }); +} + +-(BOOL) initializePlugins: (NSError**)error +{ + try + { + self.communicator->getPluginManager()->initializePlugins(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} +@end diff --git a/Sources/IceImpl/Connection.mm b/Sources/IceImpl/Connection.mm new file mode 100644 index 0000000..ef756ac --- /dev/null +++ b/Sources/IceImpl/Connection.mm @@ -0,0 +1,385 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Connection.h" +#import "Endpoint.h" +#import "ObjectAdapter.h" +#import "ObjectPrx.h" +#import "IceUtil.h" +#import "Convert.h" + +@implementation ICEConnection + +-(std::shared_ptr) connection +{ + return std::static_pointer_cast(self.cppObject); +} + +-(void) close:(uint8_t)mode +{ + self.connection->close(Ice::ConnectionClose(mode)); +} + +-(nullable ICEObjectPrx*) createProxy:(NSString*)name category:(NSString*)category error:(NSError**)error +{ + try + { + auto cppPrx = self.connection->createProxy(Ice::Identity{fromNSString(name), fromNSString(category)}); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:cppPrx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(BOOL) setAdapter:(ICEObjectAdapter* _Nullable)oa error:(NSError* _Nullable * _Nullable)error; +{ + try + { + self.connection->setAdapter(oa == nil ? nullptr : [oa objectAdapter]); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(nullable ICEObjectAdapter*) getAdapter +{ + auto cppAdapter = self.connection->getAdapter(); + + return [ICEObjectAdapter getHandle:cppAdapter]; +} + +-(ICEEndpoint*) getEndpoint +{ + auto endpoint = self.connection->getEndpoint(); + return [ICEEndpoint getHandle:endpoint]; +} + +-(BOOL) flushBatchRequests:(uint8_t)compress error:(NSError**)error +{ + try + { + self.connection->flushBatchRequests(Ice::CompressBatch(compress)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) flushBatchRequestsAsync:(uint8_t)compress + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent +{ + try + { + self.connection->flushBatchRequestsAsync(Ice::CompressBatch(compress), + [exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }, + [sent](bool sentSynchronously) + { + if(sent) + { + sent(sentSynchronously); + } + }); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(BOOL) setCloseCallback:(void (^)(ICEConnection*))callback error:(NSError**)error +{ + try + { + if(!callback) + { + self.connection->setCloseCallback(nullptr); + } + else + { + self.connection->setCloseCallback([callback](auto connection) + { + ICEConnection* conn = [ICEConnection getHandle:connection]; + assert(conn); + @autoreleasepool + { + callback(conn); + } + }); + } + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) setHeartbeatCallback:(void (^)(ICEConnection*))callback +{ + if(!callback) + { + self.connection->setHeartbeatCallback(nullptr); + } + else + { + self.connection->setHeartbeatCallback([callback](auto connection) + { + ICEConnection* conn = [ICEConnection getHandle:connection]; + assert(conn); + @autoreleasepool + { + callback(conn); + } + }); + } +} + +-(BOOL) heartbeat:(NSError**)error +{ + try + { + self.connection->heartbeat(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) heartbeatAsync:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent +{ + try + { + self.connection->heartbeatAsync([exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }, + [sent](bool sentSynchronously) + { + if(sent) + { + sent(sentSynchronously); + } + }); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(void) setACM:(NSNumber* _Nullable)timeout close:(NSNumber* _Nullable)close heartbeat:(NSNumber* _Nullable)heartbeat +{ + Ice::optional opTimeout; + Ice::optional opClose; + Ice::optional opHeartbeat; + + if(timeout != nil) + { + opTimeout = [timeout intValue]; + } + + if(close != nil) + { + opClose = Ice::ACMClose([close unsignedCharValue]); + } + + if(heartbeat != nil) + { + opHeartbeat = Ice::ACMHeartbeat([heartbeat unsignedCharValue]); + } + + self.connection->setACM(opTimeout, opClose, opHeartbeat); +} + +-(void) getACM:(int32_t*)timeout close:(uint8_t*)close heartbeat:(uint8_t*)heartbeat +{ + auto acm = self.connection->getACM(); + *timeout = acm.timeout; + *close = static_cast(acm.close); + *heartbeat = static_cast(acm.heartbeat); +} + +-(NSString*) type +{ + return toNSString(self.connection->type()); +} + +-(int32_t) timeout +{ + return self.connection->timeout(); +} + +-(NSString*) toString +{ + return toNSString(self.connection->toString()); +} + +-(id) getInfo:(NSError**)error +{ + try + { + auto info = self.connection->getInfo(); + return createConnectionInfo(info); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(BOOL) setBufferSize:(int32_t)rcvSize sndSize:(int32_t)sndSize error:(NSError**)error +{ + try + { + self.connection->setBufferSize(rcvSize, sndSize); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(BOOL) throwException:(NSError**)error +{ + try + { + self.connection->throwException(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} +@end + +id createConnectionInfo(std::shared_ptr infoPtr) +{ + id underlying = infoPtr->underlying ? createConnectionInfo(infoPtr->underlying) : [NSNull null]; + + Class factory = [ICEUtil connectionInfoFactory]; + + auto ipInfo = std::dynamic_pointer_cast(infoPtr); + if(ipInfo) + { + [factory createIPConnectionInfo:underlying + incoming:infoPtr->incoming + adapterName:toNSString(infoPtr->adapterName) + connectionId:toNSString(ipInfo->connectionId) + localAddress:toNSString(ipInfo->localAddress) + localPort:ipInfo->localPort + remoteAddress:toNSString(ipInfo->remoteAddress) + remotePort:ipInfo->remotePort]; + } + + auto tcpInfo = std::dynamic_pointer_cast(infoPtr); + if(tcpInfo) + { + return [factory createTCPConnectionInfo:underlying + incoming:tcpInfo->incoming + adapterName:toNSString(tcpInfo->adapterName) + connectionId:toNSString(tcpInfo->connectionId) + localAddress:toNSString(tcpInfo->localAddress) + localPort:tcpInfo->localPort + remoteAddress:toNSString(tcpInfo->remoteAddress) + remotePort:tcpInfo->remotePort + rcvSize:tcpInfo->rcvSize + sndSize:tcpInfo->sndSize]; + } + + auto udpInfo = std::dynamic_pointer_cast(infoPtr); + if(udpInfo) + { + return [factory createUDPConnectionInfo:underlying + incoming:infoPtr->incoming + adapterName:toNSString(infoPtr->adapterName) + connectionId:toNSString(ipInfo->connectionId) + localAddress:toNSString(ipInfo->localAddress) + localPort:ipInfo->localPort + remoteAddress:toNSString(ipInfo->remoteAddress) + remotePort:ipInfo->remotePort + mcastAddress:toNSString(udpInfo->mcastAddress) + mcastPort:udpInfo->mcastPort + rcvSize:udpInfo->rcvSize + sndSize:udpInfo->sndSize]; + } + + auto wsInfo = std::dynamic_pointer_cast(infoPtr); + if(wsInfo) + { + return [factory createWSConnectionInfo:underlying + incoming:wsInfo->incoming + adapterName:toNSString(wsInfo->adapterName) + connectionId:toNSString(wsInfo->adapterName) + headers:toNSDictionary(wsInfo->headers)]; + } + + auto sslInfo = std::dynamic_pointer_cast(infoPtr); + if(sslInfo) + { + return [factory createSSLConnectionInfo:underlying + incoming:sslInfo->incoming + adapterName:toNSString(sslInfo->adapterName) + connectionId:toNSString(sslInfo->connectionId) + cipher:toNSString(sslInfo->cipher) + certs:toNSArray(sslInfo->certs) + verified:sslInfo->verified]; + } + +#if TARGET_OS_IPHONE + + auto iapInfo = std::dynamic_pointer_cast(infoPtr); + if(iapInfo) + { + return [factory createIAPConnectionInfo:underlying + incoming:iapInfo->incoming + adapterName:toNSString(iapInfo->adapterName) + connectionId:toNSString(iapInfo->connectionId) + name:toNSString(iapInfo->name) + manufacturer:toNSString(iapInfo->manufacturer) + modelNumber:toNSString(iapInfo->modelNumber) + firmwareRevision:toNSString(iapInfo->firmwareRevision) + hardwareRevision:toNSString(iapInfo->hardwareRevision) + protocol:toNSString(iapInfo->protocol)]; + } + +#endif + + return [NSNull null]; +} diff --git a/Sources/IceImpl/Connector.h b/Sources/IceImpl/Connector.h new file mode 100644 index 0000000..16a38ec --- /dev/null +++ b/Sources/IceImpl/Connector.h @@ -0,0 +1,52 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IAP_CONNECTOR_H +#define ICE_IAP_CONNECTOR_H + +#include +#include +#include +#include +#include + +#import +#import + +namespace IceObjC +{ + +class iAPEndpointI; + +class Instance; +typedef IceUtil::Handle InstancePtr; + +class iAPConnector : public IceInternal::Connector +{ +public: + + virtual IceInternal::TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const IceInternal::Connector&) const; + virtual bool operator<(const IceInternal::Connector&) const; + +private: + + iAPConnector(const IceInternal::ProtocolInstancePtr&, Ice::Int, const std::string&, NSString*, EAAccessory*); + virtual ~iAPConnector(); + friend class iAPEndpointI; + + const IceInternal::ProtocolInstancePtr _instance; + const Ice::Int _timeout; + const std::string _connectionId; + NSString* _protocol; + EAAccessory* _accessory; +}; + +} + +#endif diff --git a/Sources/IceImpl/Connector.mm b/Sources/IceImpl/Connector.mm new file mode 100644 index 0000000..0a24468 --- /dev/null +++ b/Sources/IceImpl/Connector.mm @@ -0,0 +1,159 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "Transceiver.h" +#include "EndpointI.h" +#include "Connector.h" + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +TransceiverPtr +IceObjC::iAPConnector::connect() +{ + EASession* session = [[EASession alloc] initWithAccessory:_accessory forProtocol:_protocol]; + if(!session) + { + throw Ice::ConnectFailedException(__FILE__, __LINE__, 0); + } + TransceiverPtr transceiver = new iAPTransceiver(_instance, session); +#if defined(__clang__) && !__has_feature(objc_arc) + [session release]; +#endif + return transceiver; +} + +Short +IceObjC::iAPConnector::type() const +{ + return _instance->type(); +} + +string +IceObjC::iAPConnector::toString() const +{ + ostringstream os; + os << [_accessory.name UTF8String]; + os << " model `" << [_accessory.modelNumber UTF8String] << "'"; + os << " made by `" << [_accessory.manufacturer UTF8String] << "'"; + os << " protocol `" << [_protocol UTF8String] << "'"; + return os.str(); +} + +bool +IceObjC::iAPConnector::operator==(const IceInternal::Connector& r) const +{ + const iAPConnector* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + if(![_accessory isEqual:p->_accessory]) + { + return false; + } + + if(![_protocol isEqual:p->_protocol]) + { + return false; + } + + return true; +} + +bool +IceObjC::iAPConnector::operator<(const IceInternal::Connector& r) const +{ + const iAPConnector* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + + if([_accessory hash] < [p->_accessory hash]) + { + return true; + } + else if([p->_accessory hash] < [_accessory hash]) + { + return false; + } + + NSInteger order = [_protocol compare:p->_protocol]; + if(order == NSOrderedAscending) + { + return true; + } + else if(order == NSOrderedDescending) + { + return false; + } + + return false; +} + +IceObjC::iAPConnector::iAPConnector(const ProtocolInstancePtr& instance, + Ice::Int timeout, + const string& connectionId, + NSString* protocol, + EAAccessory* accessory) : + _instance(instance), + _timeout(timeout), + _connectionId(connectionId), +#if defined(__clang__) && !__has_feature(objc_arc) + _protocol([protocol retain]), + _accessory([accessory retain]) +#else + _protocol(protocol), + _accessory(accessory) +#endif +{ +} + +IceObjC::iAPConnector::~iAPConnector() +{ +#if defined(__clang__) && !__has_feature(objc_arc) + [_protocol release]; + [_accessory release]; +#endif +} + +#endif diff --git a/Sources/IceImpl/Convert.h b/Sources/IceImpl/Convert.h new file mode 100644 index 0000000..1da07ec --- /dev/null +++ b/Sources/IceImpl/Convert.h @@ -0,0 +1,124 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +#include +#include +#include +#include + +@class ICERuntimeException; + +namespace IceSSL +{ + class Certificate; +} + +NSError* convertException(std::exception_ptr); +NSError* convertException(const std::exception&); +std::exception_ptr convertException(ICERuntimeException*); + +inline NSString* +toNSString(const std::string& s) +{ + return [[NSString alloc] initWithUTF8String:s.c_str()]; +} + +inline std::string +fromNSString(NSString* s) +{ + return s == nil ? std::string() : [s UTF8String]; +} + +inline NSObject* +toObjC(const std::string& s) +{ + return [[NSString alloc] initWithUTF8String:s.c_str()]; +} + +inline void +fromObjC(id object, std::string& s) +{ + s = object == [NSNull null] ? ::std::string() : [object UTF8String]; +} + +NSObject* toObjC(const std::shared_ptr& endpoint); +void fromObjC(id object, std::shared_ptr& endpoint); + +NSObject* toObjC(const std::shared_ptr& cert); + +template NSMutableArray* +toNSArray(const std::vector& seq) +{ + NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:seq.size()]; + for(typename std::vector::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + NSObject* obj = toObjC(*p); + [array addObject:obj]; + } + return array; +} + +template std::vector& +fromNSArray(NSArray* array, std::vector& seq) +{ + if(array != nil) + { + seq.reserve([array count]); + NSEnumerator* enumerator = [array objectEnumerator]; + id obj = nil; + while((obj = [enumerator nextObject])) + { + T v; + fromObjC(obj, v); + seq.push_back(v); + } + } + return seq; +} + +template NSMutableData* +toNSData(const std::vector& seq) +{ + NSMutableData* array = [[NSMutableData alloc] initWithLength:seq.size() * sizeof(T)]; + T* target = (T*)[array bytes]; + for(typename std::vector::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + *target++ = *p; + } + return array; +} + +template NSMutableDictionary* +toNSDictionary(const std::map& dict) +{ + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:dict.size()]; + for(typename std::map::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + NSObject* key = toObjC(p->first); + NSObject* value = toObjC(p->second); + [dictionary setObject:value forKey:key]; + } + return dictionary; +} + +template std::map& +fromNSDictionary(NSDictionary* dictionary, std::map& dict) +{ + if(dictionary != nil) + { + NSEnumerator* enumerator = [dictionary keyEnumerator]; + id obj = nil; + while((obj = [enumerator nextObject])) + { + K k; + fromObjC(obj, k); + V v; + fromObjC([dictionary objectForKey:obj], v); + dict.insert(std::pair(k, v)); + } + } + return dict; +} diff --git a/Sources/IceImpl/Convert.mm b/Sources/IceImpl/Convert.mm new file mode 100644 index 0000000..4d74369 --- /dev/null +++ b/Sources/IceImpl/Convert.mm @@ -0,0 +1,392 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "BlobjectFacade.h" +#import "Exception.h" +#import "IceUtil.h" +#import "Convert.h" + +NSError* +convertException(std::exception_ptr excPtr) +{ + try + { + std::rethrow_exception(excPtr); + } + catch(const std::exception& exc) + { + return convertException(exc); + } + assert(false); +} + +NSError* +convertException(const std::exception& exc) +{ + Class factory = [ICEUtil exceptionFactory]; + + if(dynamic_cast(&exc)) + { + auto iceEx = dynamic_cast(&exc); + + try + { + iceEx->ice_throw(); + } + catch(const Ice::InitializationException& e) + { + return [factory initializationException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::PluginInitializationException& e) + { + return [factory pluginInitializationException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CollocationOptimizationException& e) + { + return [factory collocationOptimizationException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::AlreadyRegisteredException& e) + { + return [factory alreadyRegisteredException:toNSString(e.kindOfObject) id:toNSString(e.id) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::NotRegisteredException& e) + { + return [factory notRegisteredException:toNSString(e.kindOfObject) id:toNSString(e.id) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::TwowayOnlyException& e) + { + return [factory twowayOnlyException:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CloneNotImplementedException& e) + { + return [factory cloneNotImplementedException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::VersionMismatchException& e) + { + return [factory versionMismatchException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CommunicatorDestroyedException& e) + { + return [factory communicatorDestroyedException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ObjectAdapterDeactivatedException& e) + { + return [factory objectAdapterDeactivatedException:toNSString(e.name) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ObjectAdapterIdInUseException& e) + { + return [factory objectAdapterIdInUseException:toNSString(e.id) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::NoEndpointException& e) + { + return [factory noEndpointException:toNSString(e.proxy) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::EndpointParseException& e) + { + return [factory endpointParseException:toNSString(e.str) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::EndpointSelectionTypeParseException& e) + { + return [factory endpointSelectionTypeParseException:toNSString(e.str) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::VersionParseException& e) + { + return [factory versionParseException:toNSString(e.str) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::IdentityParseException& e) + { + return [factory identityParseException:toNSString(e.str) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ProxyParseException& e) + { + return [factory proxyParseException:toNSString(e.str) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::IllegalIdentityException& e) + { + return [factory illegalIdentityException:toNSString(e.id.name) category:toNSString(e.id.category) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::IllegalServantException& e) + { + return [factory illegalServantException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::DNSException& e) + { + return [factory dNSException:e.error host:toNSString(e.host) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::OperationInterruptedException& e) + { + return [factory operationInterruptedException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::InvocationCanceledException& e) + { + return [factory invocationCanceledException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::FeatureNotSupportedException& e) + { + return [factory featureNotSupportedException:toNSString(e.unsupportedFeature) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::FixedProxyException& e) + { + return [factory fixedProxyException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ResponseSentException& e) + { + return [factory responseSentException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::SecurityException& e) + { + return [factory securityException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownLocalException& e) + { + return [factory unknownLocalException:toNSString(e.unknown) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownUserException& e) + { + return [factory unknownUserException:toNSString(e.unknown) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownException& e) + { + return [factory unknownException:toNSString(e.unknown) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ObjectNotExistException& e) + { + return [factory objectNotExistException:toNSString(e.id.name) category:toNSString(e.id.category) facet:toNSString(e.facet) operation:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::FacetNotExistException& e) + { + return [factory facetNotExistException:toNSString(e.id.name) category:toNSString(e.id.category) facet:toNSString(e.facet) operation:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::OperationNotExistException& e) + { + return [factory operationNotExistException:toNSString(e.id.name) category:toNSString(e.id.category) facet:toNSString(e.facet) operation:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::RequestFailedException& e) + { + return [factory requestFailedException:toNSString(e.id.name) category:toNSString(e.id.category) facet:toNSString(e.facet) operation:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectionRefusedException& e) + { + return [factory connectionRefusedException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::FileException& e) + { + return [factory fileException:e.error path:toNSString(e.path) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectFailedException& e) + { + return [factory connectFailedException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectionLostException& e) + { + return [factory connectionLostException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::SocketException& e) + { + return [factory socketException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::SyscallException& e) + { + return [factory syscallException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectTimeoutException& e) + { + return [factory connectTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CloseTimeoutException& e) + { + return [factory closeTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectionTimeoutException& e) + { + return [factory connectionTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::InvocationTimeoutException& e) + { + return [factory invocationTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::TimeoutException& e) + { + return [factory timeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::BadMagicException& e) + { + NSData* badMagic = [[NSData alloc] initWithBytes:e.badMagic.data() length:e.badMagic.size()]; + return [factory badMagicException:toNSString(e.reason) badMagic:badMagic file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnsupportedProtocolException& e) + { + return [factory unsupportedProtocolException:toNSString(e.reason) badMajor:e.bad.major badMinor:e.bad.minor supportedMajor:e.supported.major supportedMinor:e.supported.minor file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnsupportedEncodingException& e) + { + return [factory unsupportedEncodingException:toNSString(e.reason) badMajor:e.bad.major badMinor:e.bad.minor supportedMajor:e.supported.major supportedMinor:e.supported.minor file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownMessageException& e) + { + return [factory unknownMessageException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectionNotValidatedException& e) + { + return [factory connectionNotValidatedException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownRequestIdException& e) + { + return [factory unknownRequestIdException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnknownReplyStatusException& e) + { + return [factory unknownReplyStatusException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CloseConnectionException& e) + { + return [factory closeConnectionException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ConnectionManuallyClosedException& e) + { + return [factory connectionManuallyClosedException:e.graceful file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::IllegalMessageSizeException& e) + { + return [factory illegalMessageSizeException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::CompressionException& e) + { + return [factory compressionException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::DatagramLimitException& e) + { + return [factory datagramLimitException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ProxyUnmarshalException& e) + { + return [factory proxyUnmarshalException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnmarshalOutOfBoundsException& e) + { + return [factory unmarshalOutOfBoundsException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::NoValueFactoryException& e) + { + return [factory noValueFactoryException:toNSString(e.reason) type:toNSString(e.type) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::UnexpectedObjectException& e) + { + return [factory unexpectedObjectException:toNSString(e.reason) type:toNSString(e.type) expectedType:toNSString(e.expectedType) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::MemoryLimitException& e) + { + return [factory memoryLimitException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::StringConversionException& e) + { + return [factory stringConversionException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::EncapsulationException& e) + { + return [factory encapsulationException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::MarshalException& e) + { + return [factory marshalException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::ProtocolException& e) + { + return [factory protocolException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; + } + catch(const Ice::LocalException& e) + { + return [factory localException:toNSString(e.ice_file()) line:e.ice_line()]; + } + } + else + { + return [factory runtimeError:toNSString(exc.what())]; + } + + return nil; +} + +std::exception_ptr +convertException(ICERuntimeException* exc) +{ + const auto file = fromNSString([exc file]); + const auto line = [exc line]; + + @try + { + @throw exc; + } + @catch(ICEObjectNotExistException* e) + { + return std::make_exception_ptr(Ice::ObjectNotExistException(file.c_str(), + line, + Ice::Identity{fromNSString([e name]), + fromNSString([e category])}, + fromNSString([e facet]), + fromNSString([e operation]))); + } + @catch(ICEFacetNotExistException* e) + { + return std::make_exception_ptr(Ice::FacetNotExistException(file.c_str(), + line, + Ice::Identity{fromNSString([e name]), + fromNSString([e category])}, + fromNSString([e facet]), + fromNSString([e operation]))); + } + @catch(ICEOperationNotExistException* e) + { + return std::make_exception_ptr(Ice::OperationNotExistException(file.c_str(), + line, + Ice::Identity{fromNSString([e name]), + fromNSString([e category])}, + fromNSString([e facet]), + fromNSString([e operation]))); + } + @catch(ICEUnknownUserException* e) + { + return std::make_exception_ptr(Ice::UnknownUserException(file.c_str(), + line, + fromNSString([e unknown]))); + } + @catch(ICEUnknownLocalException* e) + { + return std::make_exception_ptr(Ice::UnknownLocalException(file.c_str(), + line, + fromNSString([e unknown]))); + } + @catch(ICEUnknownException* e) + { + return std::make_exception_ptr(Ice::UnknownException(file.c_str(), + line, + fromNSString([e unknown]))); + } + @catch(...) + { + + return std::make_exception_ptr(Ice::UnknownException(file.c_str(), + line, + fromNSString(NSStringFromClass([exc class])))); + } +} + +NSObject* +toObjC(const std::shared_ptr& endpoint) +{ + return [ICEEndpoint getHandle:endpoint]; +} + +void +fromObjC(id object, std::shared_ptr& endpoint) +{ + ICEEndpoint* endpt = object; + endpoint = object == [NSNull null] ? nullptr : [endpt endpoint]; +} + +NSObject* +toObjC(const std::shared_ptr& cert) +{ + return toNSString(cert->encode()); +} diff --git a/Sources/IceImpl/Endpoint.mm b/Sources/IceImpl/Endpoint.mm new file mode 100644 index 0000000..0ee26c4 --- /dev/null +++ b/Sources/IceImpl/Endpoint.mm @@ -0,0 +1,147 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Endpoint.h" +#import "IceUtil.h" +#import "Convert.h" + +@implementation ICEEndpointInfo + +-(std::shared_ptr) info +{ + return std::static_pointer_cast(self.cppObject); +} + +-(int16_t) getType +{ + return self.info->type(); +} + +-(BOOL) getDatagram +{ + return self.info->datagram(); +} + +-(BOOL) getSecure +{ + return self.info->secure(); +} + +@end + +@implementation ICEEndpoint + +-(std::shared_ptr) endpoint +{ + return std::static_pointer_cast(self.cppObject); +} + +-(NSString*) toString +{ + return toNSString(self.endpoint->toString()); +} + +-(id) getInfo +{ + auto info = self.endpoint->getInfo(); + return [ICEEndpoint createEndpointInfo:info]; +} + +-(bool) isEqual:(ICEEndpoint*)other +{ + return Ice::targetEqualTo(self.endpoint, other.endpoint); +} + ++(id) createEndpointInfo:(std::shared_ptr)infoPtr +{ + ICEEndpointInfo* handle = [ICEEndpointInfo getHandle:infoPtr]; + id underlying = infoPtr->underlying ? [self createEndpointInfo:infoPtr->underlying] : [NSNull null]; + + Class factory = [ICEUtil endpointInfoFactory]; + + // + // Don't use info->type() to determine the type of the EndpointInfo object. When an endpoint is the + // underlying endpoint of a parent, the child's value for type() is the same as its parent. We have + // to use type casts instead. + // + + auto opaqueInfo = std::dynamic_pointer_cast(infoPtr); + if(opaqueInfo) + { + NSData* rawBytes = [[NSData alloc] initWithBytes:opaqueInfo->rawBytes.data() + length:opaqueInfo->rawBytes.size()]; + + return [factory createOpaqueEndpointInfo:handle + underlying:underlying + timeout:opaqueInfo->timeout + compress:opaqueInfo->compress + encodingMajor:opaqueInfo->rawEncoding.major + encodingMinor:opaqueInfo->rawEncoding.minor + rawBytes:rawBytes]; + } + + auto udpInfo = std::dynamic_pointer_cast(infoPtr); + if(udpInfo) + { + return [factory createUDPEndpointInfo:handle + underlying:underlying + timeout:udpInfo->timeout + compress:udpInfo->compress + host:toNSString(udpInfo->host) + port:udpInfo->port + sourceAddress:toNSString(udpInfo->sourceAddress) + mcastInterface:toNSString(udpInfo->mcastInterface) + mcastTtl:udpInfo->mcastTtl]; + } + + auto ipInfo = std::dynamic_pointer_cast(infoPtr); + if(std::dynamic_pointer_cast(infoPtr)) + { + return [factory createTCPEndpointInfo:handle + underlying:underlying + timeout:ipInfo->timeout + compress:ipInfo->compress + host:toNSString(ipInfo->host) + port:ipInfo->port + sourceAddress:toNSString(ipInfo->sourceAddress)]; + } + + auto wsInfo = std::dynamic_pointer_cast(infoPtr); + if(wsInfo) + { + return [factory createWSEndpointInfo:handle + underlying:underlying + timeout:infoPtr->timeout + compress:infoPtr->compress + resource:toNSString(wsInfo->resource)]; + } + + if(std::dynamic_pointer_cast(infoPtr)) + { + return [factory createSSLEndpointInfo:handle + underlying:underlying + timeout:infoPtr->timeout + compress:infoPtr->compress]; + } + +#if TARGET_OS_IPHONE + + auto iapInfo = std::dynamic_pointer_cast(infoPtr); + if(iapInfo) + { + return [factory createIAPEndpointInfo:handle + underlying:underlying + timeout:iapInfo->timeout + compress:iapInfo->compress + manufacturer:toNSString(iapInfo->manufacturer) + modelNumber:toNSString(iapInfo->modelNumber) + name:toNSString(iapInfo->name) + protocol:toNSString(iapInfo->protocol)]; + } + +#endif + + return [NSNull null]; +} +@end diff --git a/Sources/IceImpl/EndpointI.h b/Sources/IceImpl/EndpointI.h new file mode 100644 index 0000000..faabe7b --- /dev/null +++ b/Sources/IceImpl/EndpointI.h @@ -0,0 +1,107 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IAP_ENDPOINT_I_H +#define ICE_IAP_ENDPOINT_I_H + +#include +#include +#include + +namespace IceObjC +{ + +class iAPEndpointI; +#ifdef ICE_CPP11_MAPPING // C++11 mapping +typedef ::std::shared_ptr iAPEndpointIPtr; +#else +typedef IceUtil::Handle iAPEndpointIPtr; +#endif + +class iAPEndpointI : public IceInternal::EndpointI +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + iAPEndpointI(const IceInternal::ProtocolInstancePtr&, const std::string&, const std::string&, const std::string&, + const std::string&, Ice::Int, const std::string&, bool); + iAPEndpointI(const IceInternal::ProtocolInstancePtr&); + iAPEndpointI(const IceInternal::ProtocolInstancePtr&, Ice::InputStream*); + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; + virtual bool datagram() const; + virtual bool secure() const; + + virtual Ice::Int timeout() const; + virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; + virtual const std::string& connectionId() const; + virtual IceInternal::EndpointIPtr connectionId(const std::string&) const; + virtual bool compress() const; + virtual IceInternal::EndpointIPtr compress(bool) const; + + virtual IceInternal::TransceiverPtr transceiver() const; + virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; + virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; + virtual std::vector expandIfWildcard() const; + virtual std::vector expandHost(IceInternal::EndpointIPtr&) const; + virtual bool equivalent(const IceInternal::EndpointIPtr&) const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + + virtual std::string options() const; + virtual ::Ice::Int hash() const; + +private: + + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + + // + // All members are const, because endpoints are immutable. + // + const IceInternal::ProtocolInstancePtr _instance; + const std::string _manufacturer; + const std::string _modelNumber; + const std::string _name; + const std::string _protocol; + const Ice::Int _timeout; + const std::string _connectionId; + const bool _compress; +}; + +class iAPEndpointFactory : public IceInternal::EndpointFactory +{ +public: + + iAPEndpointFactory(const IceInternal::ProtocolInstancePtr&); + + virtual ~iAPEndpointFactory(); + + virtual Ice::Short type() const; + virtual std::string protocol() const; + virtual IceInternal::EndpointIPtr create(std::vector&, bool) const; + virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const; + virtual void destroy(); + + virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const; + +private: + + IceInternal::ProtocolInstancePtr _instance; +}; + +} + +#endif diff --git a/Sources/IceImpl/EndpointI.mm b/Sources/IceImpl/EndpointI.mm new file mode 100644 index 0000000..649b285 --- /dev/null +++ b/Sources/IceImpl/EndpointI.mm @@ -0,0 +1,713 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "EndpointI.h" +#include "Connector.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +namespace +{ + +class iAPEndpointFactoryPlugin : public Ice::Plugin +{ +public: + + iAPEndpointFactoryPlugin(const Ice::CommunicatorPtr& com) + { + ProtocolPluginFacadePtr f = getProtocolPluginFacade(com); + + // iAP transport + ProtocolInstancePtr iap = new ProtocolInstance(com, iAPEndpointType, "iap", false); + f->addEndpointFactory(new IceObjC::iAPEndpointFactory(iap)); + + // SSL based on iAP transport + ProtocolInstancePtr iaps = new ProtocolInstance(com, iAPSEndpointType, "iaps", true); + f->addEndpointFactory(new UnderlyingEndpointFactory(iaps, SSLEndpointType, iAPEndpointType)); + } + + virtual void initialize() {} + virtual void destroy() {} +}; + +} + +extern "C" ICEIAP_API Plugin* +createIceIAP(const CommunicatorPtr& com, const string&, const StringSeq&) +{ + return new iAPEndpointFactoryPlugin(com); +} + +namespace Ice +{ + +ICEIAP_API void +registerIceIAP(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceIAP", createIceIAP, loadOnInitialize); +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICEIAP_API void +ICEregisterIceIAP(bool loadOnInitialize) +{ + Ice::registerIceIAP(loadOnInitialize); +} + +IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, const string& m, + const string& o, const string& n, const string& p, Int ti, + const string& conId, bool co) : + _instance(instance), + _manufacturer(m), + _modelNumber(o), + _name(n), + _protocol(p), + _timeout(ti), + _connectionId(conId), + _compress(co) +{ +} + +IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance) : + _instance(instance), + _timeout(-1), + _compress(false) +{ +} + +IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : + _instance(instance), + _timeout(-1), + _compress(false) +{ + s->read(const_cast(_manufacturer), false); + s->read(const_cast(_modelNumber), false); + s->read(const_cast(_name), false); + s->read(const_cast(_protocol), false); + s->read(const_cast(_timeout)); + s->read(const_cast(_compress)); +} + +void +IceObjC::iAPEndpointI::streamWriteImpl(OutputStream* s) const +{ + s->write(_manufacturer, false); + s->write(_modelNumber, false); + s->write(_name, false); + s->write(_protocol, false); + s->write(_timeout); + s->write(_compress); +} + +EndpointInfoPtr +IceObjC::iAPEndpointI::getInfo() const ICE_NOEXCEPT +{ + IceIAP::EndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); + info->timeout = _timeout; + info->compress = _compress; + info->manufacturer = _manufacturer; + info->modelNumber = _modelNumber; + info->name = _name; + info->protocol = _protocol; + return info; +} + +Short +IceObjC::iAPEndpointI::type() const +{ + return _instance->type(); +} + +const string& +IceObjC::iAPEndpointI::protocol() const +{ + return _instance->protocol(); +} + +bool +IceObjC::iAPEndpointI::datagram() const +{ + return false; +} + +bool +IceObjC::iAPEndpointI::secure() const +{ + return _instance->secure(); +} + +Int +IceObjC::iAPEndpointI::timeout() const +{ + return _timeout; +} + +EndpointIPtr +IceObjC::iAPEndpointI::timeout(Int t) const +{ + if(t == _timeout) + { + return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); + } + else + { + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId, + _compress); + } +} + +const string& +IceObjC::iAPEndpointI::connectionId() const +{ + return _connectionId; +} + +EndpointIPtr +IceObjC::iAPEndpointI::connectionId(const string& cId) const +{ + if(cId == _connectionId) + { + return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); + } + else + { + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId, + _compress); + } +} + +bool +IceObjC::iAPEndpointI::compress() const +{ + return _compress; +} + +EndpointIPtr +IceObjC::iAPEndpointI::compress(bool c) const +{ + if(c == _compress) + { + return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); + } + else + { + return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, + _connectionId, c); + } +} + +TransceiverPtr +IceObjC::iAPEndpointI::transceiver() const +{ + return 0; +} + +void +IceObjC::iAPEndpointI::connectors_async(Ice::EndpointSelectionType /*selType*/, + const EndpointI_connectorsPtr& callback) const +{ + try + { + vector c; + + EAAccessoryManager* manager = [EAAccessoryManager sharedAccessoryManager]; + if(manager == nil) + { + throw Ice::ConnectFailedException(__FILE__, __LINE__, 0); + } + + NSString* protocol = _protocol.empty() ? @"com.zeroc.ice" : [[NSString alloc] initWithUTF8String:_protocol.c_str()]; + NSArray* array = [manager connectedAccessories]; + NSEnumerator* enumerator = [array objectEnumerator]; + EAAccessory* accessory = nil; + while((accessory = [enumerator nextObject])) + { + if(!accessory.connected) + { + continue; + } + if(!_manufacturer.empty() && _manufacturer != [accessory.manufacturer UTF8String]) + { + continue; + } + if(!_modelNumber.empty() && _modelNumber != [accessory.modelNumber UTF8String]) + { + continue; + } + if(!_name.empty() && _name != [accessory.name UTF8String]) + { + continue; + } + if(![accessory.protocolStrings containsObject:protocol]) + { + continue; + } + c.push_back(new iAPConnector(_instance, _timeout, _connectionId, protocol, accessory)); + } +#if defined(__clang__) && !__has_feature(objc_arc) + [protocol release]; +#endif + if(c.empty()) + { + throw Ice::ConnectFailedException(__FILE__, __LINE__, 0); + } + callback->connectors(c); + } + catch(const Ice::LocalException& ex) + { + callback->exception(ex); + } +} + +AcceptorPtr +IceObjC::iAPEndpointI::acceptor(const string&) const +{ + assert(false); + return 0; +} + +vector +IceObjC::iAPEndpointI::expandIfWildcard() const +{ + vector endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); + return endps; +} + +vector +IceObjC::iAPEndpointI::expandHost(EndpointIPtr&) const +{ + vector endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); + return endps; +} + +bool +IceObjC::iAPEndpointI::equivalent(const EndpointIPtr& endpoint) const +{ + const iAPEndpointI* endpointI = dynamic_cast(endpoint.get()); + if(!endpointI) + { + return false; + } + return endpointI->_manufacturer == _manufacturer && + endpointI->_modelNumber == _modelNumber && + endpointI->_name == _name && + endpointI->_protocol == _protocol; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceObjC::iAPEndpointI::operator==(const Ice::Endpoint& r) const +#else +IceObjC::iAPEndpointI::operator==(const Ice::LocalObject& r) const +#endif +{ + const iAPEndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_manufacturer != p->_manufacturer) + { + return false; + } + + if(_modelNumber != p->_modelNumber) + { + return false; + } + + if(_name != p->_name) + { + return false; + } + + if(_protocol != p->_protocol) + { + return false; + } + + if(_timeout != p->_timeout) + { + return false; + } + + if(_connectionId != p->_connectionId) + { + return false; + } + + if(_compress != p->_compress) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceObjC::iAPEndpointI::operator<(const Ice::Endpoint& r) const +#else +IceObjC::iAPEndpointI::operator<(const Ice::LocalObject& r) const +#endif +{ + const iAPEndpointI* p = dynamic_cast(&r); + if(!p) + { + const IceInternal::EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(_manufacturer < p->_manufacturer) + { + return true; + } + else if(p->_manufacturer < _manufacturer) + { + return false; + } + + if(_modelNumber < p->_modelNumber) + { + return true; + } + else if(p->_modelNumber < _modelNumber) + { + return false; + } + + if(_name < p->_name) + { + return true; + } + else if(p->_name < _name) + { + return false; + } + + if(_protocol < p->_protocol) + { + return true; + } + else if(p->_protocol < _protocol) + { + return false; + } + + if(_timeout < p->_timeout) + { + return true; + } + else if(p->_timeout < _timeout) + { + return false; + } + + if(_connectionId < p->_connectionId) + { + return true; + } + else if(p->_connectionId < _connectionId) + { + return false; + } + + if(!_compress && p->_compress) + { + return true; + } + else if(p->_compress < _compress) + { + return false; + } + + return false; +} + +string +IceObjC::iAPEndpointI::options() const +{ + // + // WARNING: Certain features, such as proxy validation in Glacier2, + // depend on the format of proxy strings. Changes to toString() and + // methods called to generate parts of the reference string could break + // these features. Please review for all features that depend on the + // format of proxyToString() before changing this and related code. + // + ostringstream s; + if(!_manufacturer.empty()) + { + s << " -m "; + bool addQuote = _manufacturer.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _manufacturer; + if(addQuote) + { + s << "\""; + } + } + + if(!_modelNumber.empty()) + { + s << " -o "; + bool addQuote = _modelNumber.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _modelNumber; + if(addQuote) + { + s << "\""; + } + } + + if(!_name.empty()) + { + s << " -n "; + bool addQuote = _name.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _name; + if(addQuote) + { + s << "\""; + } + } + + if(!_protocol.empty()) + { + s << " -p "; + bool addQuote = _protocol.find(':') != string::npos; + if(addQuote) + { + s << "\""; + } + s << _protocol; + if(addQuote) + { + s << "\""; + } + } + + if(_timeout != -1) + { + s << " -t " << _timeout; + } + + if(_compress) + { + s << " -z"; + } + return s.str(); +} + +Ice::Int +IceObjC::iAPEndpointI::hash() const +{ + Ice::Int h = 5381; + hashAdd(h, _manufacturer); + hashAdd(h, _modelNumber); + hashAdd(h, _name); + hashAdd(h, _protocol); + hashAdd(h, _timeout); + hashAdd(h, _connectionId); + return h; +} + +bool +IceObjC::iAPEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) +{ + switch(option[1]) + { + case 'm': + { + if(argument.empty()) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "no argument provided for -h option in endpoint " + endpoint; + throw ex; + } + const_cast(_manufacturer) = argument; + break; + } + + case 'o': + { + if(argument.empty()) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "no argument provided for -h option in endpoint " + endpoint; + throw ex; + } + const_cast(_modelNumber) = argument; + break; + } + + case 'n': + { + if(argument.empty()) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "no argument provided for -h option in endpoint " + endpoint; + throw ex; + } + const_cast(_name) = argument; + break; + } + + case 'p': + { + if(argument.empty()) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "no argument provided for -h option in endpoint " + endpoint; + throw ex; + } + const_cast(_protocol) = argument; + break; + } + + case 't': + { + if(argument == "infinite") + { + const_cast(_timeout) = -1; + } + else + { + istringstream t(argument); + if(!(t >> const_cast(_timeout)) || !t.eof() || _timeout < 1) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint; + throw ex; + } + } + break; + } + + case 'z': + { + if(!argument.empty()) + { + EndpointParseException ex(__FILE__, __LINE__); + ex.str = "no argument provided for -h option in endpoint " + endpoint; + throw ex; + } + const_cast(_compress) = true; + break; + } + + default: + { + return false; + } + } + return true; +} + +IceObjC::iAPEndpointFactory::iAPEndpointFactory(const ProtocolInstancePtr& instance) : + _instance(instance) +{ +} + +IceObjC::iAPEndpointFactory::~iAPEndpointFactory() +{ +} + +Short +IceObjC::iAPEndpointFactory::type() const +{ + return _instance->type(); +} + +string +IceObjC::iAPEndpointFactory::protocol() const +{ + return _instance->protocol(); +} + +EndpointIPtr +IceObjC::iAPEndpointFactory::create(vector& args, bool oaEndpoint) const +{ + if(oaEndpoint) + { + return 0; + } + EndpointIPtr endpt = ICE_MAKE_SHARED(iAPEndpointI, _instance); + endpt->initWithOptions(args); + return endpt; +} + +EndpointIPtr +IceObjC::iAPEndpointFactory::read(InputStream* s) const +{ + return ICE_MAKE_SHARED(iAPEndpointI, _instance, s); +} + +void +IceObjC::iAPEndpointFactory::destroy() +{ + _instance = 0; +} + +EndpointFactoryPtr +IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance) const +{ + return new iAPEndpointFactory(instance); +} + +#endif diff --git a/Sources/IceImpl/Exception.mm b/Sources/IceImpl/Exception.mm new file mode 100644 index 0000000..d63b1e4 --- /dev/null +++ b/Sources/IceImpl/Exception.mm @@ -0,0 +1,36 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Exception.h" + +@implementation ICERuntimeException +@synthesize file; +@synthesize line; +@end + +@implementation ICERequestFailedException +@synthesize name; +@synthesize category; +@synthesize facet; +@synthesize operation; +@end + +@implementation ICEObjectNotExistException +@end + +@implementation ICEFacetNotExistException +@end + +@implementation ICEOperationNotExistException +@end + +@implementation ICEUnknownException +@synthesize unknown; +@end + +@implementation ICEUnknownLocalException +@end + +@implementation ICEUnknownUserException +@end diff --git a/Sources/IceImpl/IceUtil.mm b/Sources/IceImpl/IceUtil.mm new file mode 100644 index 0000000..86fcfae --- /dev/null +++ b/Sources/IceImpl/IceUtil.mm @@ -0,0 +1,220 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Logger.h" +#import "Properties.h" +#import "IceUtil.h" +#import "Convert.h" +#import "LoggerWrapperI.h" + +#import +#import +#import + +namespace +{ + class Init + { + public: + + Init() + { + // + // Register plug-ins included in the Ice framework (a single binary file) + // See also RegisterPluginsInit.cpp in cpp/src/Ice + // + Ice::registerIceSSL(false); + Ice::registerIceDiscovery(false); + Ice::registerIceLocatorDiscovery(false); +#if defined(__APPLE__) && TARGET_OS_IPHONE != 0 + Ice::registerIceIAP(false); +#endif + } + }; + Init init; +} + +@implementation ICEUtil +static Class _exceptionFactory; +static Class _connectionInfoFactory; +static Class _endpointInfoFactory; +static Class _adminFacetFactory; + ++(Class) exceptionFactory +{ + return _exceptionFactory; +} + ++(Class) connectionInfoFactory +{ + return _connectionInfoFactory; +} + ++(Class) endpointInfoFactory +{ + return _endpointInfoFactory; +} + ++(Class) adminFacetFactory +{ + return _adminFacetFactory; +} + ++(BOOL) registerFactories:(Class)exception + connectionInfo:(Class)connectionInfo + endpointInfo:(Class)endpointInfo + adminFacet:(Class)adminFacet +{ + _exceptionFactory = exception; + _connectionInfoFactory = connectionInfo; + _endpointInfoFactory = endpointInfo; + _adminFacetFactory = adminFacet; + return true; +} + ++(ICECommunicator*) initialize:(NSArray*)swiftArgs + properties:(ICEProperties*)properties + withConfigFile:(BOOL)withConfigFile + logger:(id)logger + remArgs:(NSArray**)remArgs + error:(NSError**)error +{ + Ice::StringSeq args; + fromNSArray(swiftArgs, args); + + assert(properties); + assert(withConfigFile || args.empty()); + + // + // Collect InitializationData members. + // + Ice::InitializationData initData; + initData.properties = [properties properties]; + + if(logger) + { + initData.logger = std::make_shared(logger); + } + + try + { + std::shared_ptr communicator; + if(withConfigFile) + { + communicator = Ice::initialize(args, initData); + *remArgs = toNSArray(args); + } + else + { + communicator = Ice::initialize(initData); + } + return [ICECommunicator getHandle:communicator]; + } + catch(const std::exception& err) + { + *error = convertException(err); + } + return nil; +} + ++(ICEProperties*) createProperties +{ + return [ICEProperties getHandle:Ice::createProperties()]; +} + ++(ICEProperties*) createProperties:(NSArray*)swiftArgs + defaults:(ICEProperties*)defaults + remArgs:(NSArray**)remArgs + error:(NSError**)error +{ + try + { + std::vector a; + fromNSArray(swiftArgs, a); + std::shared_ptr def; + if(defaults) + { + def = [defaults properties]; + } + auto props = Ice::createProperties(a, def); + + // a now contains remaning arguments that were not used by Ice::createProperties + if(remArgs) + { + *remArgs = toNSArray(a); + } + return [ICEProperties getHandle:props]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + } + + return nil; +} + ++(BOOL) stringToIdentity:(NSString*)str + name:(NSString* __strong _Nonnull * _Nonnull)name + category:(NSString* __strong _Nonnull * _Nonnull)category + error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto ident = Ice::stringToIdentity(fromNSString(str)); + *name = toNSString(ident.name); + *category = toNSString(ident.category); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + ++(NSString*) identityToString:(NSString*)name + category:(NSString*)category + mode:(uint8_t)mode +{ + Ice::Identity identity{fromNSString(name), fromNSString(category)}; + return toNSString(Ice::identityToString(identity, static_cast(mode))); +} + ++(NSString*) encodingVersionToString:(UInt8)major minor:(UInt8)minor +{ + Ice::EncodingVersion v {major, minor}; + return toNSString(Ice::encodingVersionToString(v)); +} + ++(NSString*) escapeString:(NSString *)string + special:(NSString *)special + communicator:(ICECommunicator*)communicator error:(NSError *__autoreleasing _Nullable *)error +{ + try + { + + auto instance = IceInternal::getInstance([communicator communicator]); + return toNSString(IceInternal::escapeString(fromNSString(string), + fromNSString(special), + instance->toStringMode())); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } + +} + ++(NSString*) errorToString:(int32_t)error +{ + return toNSString(IceUtilInternal::errorToString(error)); +} + ++(NSString*) errorToStringDNS:(int32_t)error +{ + return toNSString(IceInternal::errorToStringDNS(error)); +} + +@end diff --git a/Sources/IceImpl/ImplicitContext.mm b/Sources/IceImpl/ImplicitContext.mm new file mode 100644 index 0000000..01f448c --- /dev/null +++ b/Sources/IceImpl/ImplicitContext.mm @@ -0,0 +1,47 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "ImplicitContext.h" +#import "Convert.h" + +@implementation ICEImplicitContext + +-(std::shared_ptr) implicitContext +{ + return std::static_pointer_cast(self.cppObject); +} + +-(NSDictionary*) getContext +{ + return toNSDictionary(self.implicitContext->getContext()); +} + +-(void) setContext:(NSDictionary*)context +{ + Ice::Context c; + fromNSDictionary(context, c); + self.implicitContext->setContext(c); +} + +-(bool) containsKey:(NSString*)string +{ + return self.implicitContext->containsKey(fromNSString(string)); +} + +-(NSString*) get:(NSString*)key +{ + return toNSString(self.implicitContext->get(fromNSString(key))); +} + +-(NSString*) put:(NSString*)key value:(NSString*)value +{ + return toNSString(self.implicitContext->put(fromNSString(key), fromNSString(value))); +} + +-(NSString*) remove:(NSString*)key +{ + return toNSString(self.implicitContext->remove(fromNSString(key))); +} + +@end diff --git a/Sources/IceImpl/LocalObject.mm b/Sources/IceImpl/LocalObject.mm new file mode 100644 index 0000000..092397a --- /dev/null +++ b/Sources/IceImpl/LocalObject.mm @@ -0,0 +1,64 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#import "LocalObject.h" + +namespace +{ + std::unordered_map cachedObjects; +} + +@implementation ICELocalObject + +-(instancetype) initWithCppObject:(std::shared_ptr)cppObject +{ + assert(cppObject); + self = [super init]; + if(!self) + { + return nil; + } + + _cppObject = std::move(cppObject); + + @synchronized([ICELocalObject class]) + { + assert(cachedObjects.find(_cppObject.get()) == cachedObjects.end()); + cachedObjects.insert(std::make_pair(_cppObject.get(), self)); + } + return self; +} + ++(nullable instancetype) getHandle:(std::shared_ptr)cppObject +{ + if(cppObject == nullptr) + { + return nil; + } + @synchronized([ICELocalObject class]) + { + std::unordered_map::const_iterator p = cachedObjects.find(cppObject.get()); + if(p != cachedObjects.end()) + { + return p->second; + } + else + { + return [[[self class] alloc] initWithCppObject:std::move(cppObject)]; + } + } +} + +-(void) dealloc { + assert(_cppObject != nullptr); + @synchronized([ICELocalObject class]) + { + cachedObjects.erase(_cppObject.get()); + _cppObject = nullptr; + } +} + +@end diff --git a/Sources/IceImpl/Logger.mm b/Sources/IceImpl/Logger.mm new file mode 100644 index 0000000..ed10e27 --- /dev/null +++ b/Sources/IceImpl/Logger.mm @@ -0,0 +1,43 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Logger.h" +#import "Convert.h" + +@implementation ICELogger +-(std::shared_ptr) logger +{ + return std::static_pointer_cast(self.cppObject); +} + +-(void) print:(NSString*)message +{ + self.logger->print(fromNSString(message)); +} + +-(void) trace:(NSString*)category message:(NSString*)message +{ + self.logger->trace(fromNSString(category), fromNSString(message)); +} + +-(void) warning:(NSString*)message +{ + self.logger->warning(fromNSString(message)); +} + +-(void) error:(NSString*)message +{ + self.logger->error(fromNSString(message)); +} + +-(NSString*) getPrefix +{ + return toNSString(self.logger->getPrefix()); +} + +-(id) cloneWithPrefix:(NSString*)prefix +{ + return [ICELogger getHandle:self.logger->cloneWithPrefix(fromNSString(prefix))]; +} +@end diff --git a/Sources/IceImpl/LoggerWrapperI.h b/Sources/IceImpl/LoggerWrapperI.h new file mode 100644 index 0000000..95dd0b4 --- /dev/null +++ b/Sources/IceImpl/LoggerWrapperI.h @@ -0,0 +1,64 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Convert.h" + +class LoggerWrapperI : public Ice::Logger +{ +public: + + LoggerWrapperI(id logger) : _logger(logger) + { + } + + virtual ~LoggerWrapperI() + { + } + + virtual void + print(const std::string& msg) + { + [_logger print:toNSString(msg)]; + } + + virtual void + trace(const std::string& category, const std::string& msg) + { + [_logger trace:toNSString(category) message:toNSString(msg)]; + } + + virtual void + warning(const std::string& msg) + { + [_logger warning:toNSString(msg)]; + } + + virtual void + error(const std::string& msg) + { + [_logger error:toNSString(msg)]; + } + + virtual std::shared_ptr + cloneWithPrefix(const std::string& prefix) + { + return std::make_shared([_logger cloneWithPrefix:toNSString(prefix)]); + } + + virtual std::string + getPrefix() + { + return fromNSString([_logger getPrefix]); + } + + id + getLogger() + { + return _logger; + } + +private: + + id _logger; +}; diff --git a/Sources/IceImpl/Notifications.mm b/Sources/IceImpl/Notifications.mm new file mode 100644 index 0000000..5009f28 --- /dev/null +++ b/Sources/IceImpl/Notifications.mm @@ -0,0 +1,142 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import + +#if TARGET_OS_IPHONE != 0 + +#import +#import +#import + +#include + +#include + +using namespace std; +using namespace IceInternal; + +namespace IceInternal +{ + +bool registerForBackgroundNotification(const IncomingConnectionFactoryPtr&); +void unregisterForBackgroundNotification(const IncomingConnectionFactoryPtr&); + +} + +namespace +{ + +class Observer +{ +public: + + Observer() : _background(false) + { + _backgroundObserver = + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification + object:nil + queue:nil + usingBlock:^(NSNotification*) + { + didEnterBackground(); + }]; + + _foregroundObserver = + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification + object:nil + queue:nil + usingBlock:^(NSNotification*) + { + willEnterForeground(); + }]; + } + + ~Observer() + { + [[NSNotificationCenter defaultCenter] removeObserver:_backgroundObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_foregroundObserver]; + } + + bool + add(const IncomingConnectionFactoryPtr& factory) + { + IceUtil::Mutex::Lock sync(_mutex); + if(_background) + { + factory->stopAcceptor(); + } + else + { + factory->startAcceptor(); // Might throw + } + _factories.insert(factory); + return _background; + } + + void + remove(const IncomingConnectionFactoryPtr& factory) + { + IceUtil::Mutex::Lock sync(_mutex); + _factories.erase(factory); + } + + void + didEnterBackground() + { + IceUtil::Mutex::Lock sync(_mutex); + + // + // Notify all the incoming connection factories that we are + // entering the background mode. + // + for(set::const_iterator p = _factories.begin(); p != _factories.end(); ++p) + { + (*p)->stopAcceptor(); + } + _background = true; + } + + void + willEnterForeground() + { + IceUtil::Mutex::Lock sync(_mutex); + + // + // Notify all the incoming connection factories that we are + // entering the foreground mode. + // + _background = false; + for(set::const_iterator p = _factories.begin(); p != _factories.end(); ++p) + { + (*p)->startAcceptor(); + } + } + +private: + + IceUtil::Mutex _mutex; + bool _background; + id _backgroundObserver; + id _foregroundObserver; + set _factories; +}; + +} + +static Observer observer; + +bool +IceInternal::registerForBackgroundNotification(const IncomingConnectionFactoryPtr& factory) +{ + return observer.add(factory); +} + +void +IceInternal::unregisterForBackgroundNotification(const IncomingConnectionFactoryPtr& factory) +{ + observer.remove(factory); +} + +#endif diff --git a/Sources/IceImpl/ObjectAdapter.mm b/Sources/IceImpl/ObjectAdapter.mm new file mode 100644 index 0000000..d2a5dfe --- /dev/null +++ b/Sources/IceImpl/ObjectAdapter.mm @@ -0,0 +1,226 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Config.h" +#import "ObjectAdapter.h" +#import "Convert.h" +#import "ObjectPrx.h" +#import "Connection.h" +#import "Communicator.h" +#import "BlobjectFacade.h" + +@implementation ICEObjectAdapter + +-(std::shared_ptr) objectAdapter +{ + return std::static_pointer_cast(self.cppObject); +} + +-(NSString*) getName +{ + return toNSString(self.objectAdapter->getName()); +} + +-(ICECommunicator*) getCommunicator +{ + auto comm = self.objectAdapter->getCommunicator(); + return [ICECommunicator getHandle:comm]; +} + +-(BOOL) activate:(NSError* _Nullable * _Nullable)error +{ + try + { + self.objectAdapter->activate(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) hold +{ + try + { + self.objectAdapter->hold(); + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + // ignored + } + catch(const std::exception&) + { + // unexpected but ignored nevertheless + } +} + +-(void) waitForHold +{ + try + { + self.objectAdapter->waitForHold(); + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + // ignored, returns immediately + } + catch(const std::exception&) + { + // unexpected but ignored nevertheless + } +} + +-(void) deactivate +{ + self.objectAdapter->deactivate(); +} + +-(void) waitForDeactivate +{ + self.objectAdapter->waitForDeactivate(); +} + +-(BOOL) isDeactivated +{ + return self.objectAdapter->isDeactivated(); +} + +-(void) destroy +{ + self.objectAdapter->destroy(); +} + +-(nullable ICEObjectPrx*) createProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto prx = self.objectAdapter->createProxy(Ice::Identity{fromNSString(name), fromNSString(category)}); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable ICEObjectPrx*) createDirectProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto prx = self.objectAdapter->createDirectProxy(Ice::Identity{fromNSString(name), fromNSString(category)}); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable ICEObjectPrx*) createIndirectProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto prx = self.objectAdapter->createIndirectProxy(Ice::Identity{fromNSString(name), fromNSString(category)}); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(void) setLocator:(nullable ICEObjectPrx*) locator +{ + try + { + auto l = locator ? [locator prx] : nullptr; + self.objectAdapter->setLocator(Ice::uncheckedCast(l)); + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + // ignored + } + catch(const Ice::CommunicatorDestroyedException&) + { + // ignored + } + catch(const std::exception&) + { + // unexpected but ignored nevertheless + } +} + +-(nullable ICEObjectPrx*) getLocator +{ + auto prx = self.objectAdapter->getLocator(); + return [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(NSArray*) getEndpoints +{ + return toNSArray(self.objectAdapter->getEndpoints()); +} + +-(BOOL) refreshPublishedEndpoints:(NSError* _Nullable * _Nullable)error +{ + try + { + self.objectAdapter->refreshPublishedEndpoints(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(NSArray*) getPublishedEndpoints +{ + return toNSArray(self.objectAdapter->getPublishedEndpoints()); +} + +-(BOOL) setPublishedEndpoints:(NSArray*)newEndpoints error:(NSError* _Nullable * _Nullable)error +{ + try + { + Ice::EndpointSeq endpts; + fromNSArray(newEndpoints, endpts); + + self.objectAdapter->setPublishedEndpoints(endpts); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(dispatch_queue_t) getDispatchQueue:(NSError* _Nullable * _Nullable)error +{ + try + { + return self.objectAdapter->getDispatchQueue(); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(void) registerDefaultServant:(id)facade +{ + auto servant = std::make_shared(facade); + self.objectAdapter->addDefaultServant(servant, ""); +} + +@end diff --git a/Sources/IceImpl/ObjectPrx.mm b/Sources/IceImpl/ObjectPrx.mm new file mode 100644 index 0000000..b9557d1 --- /dev/null +++ b/Sources/IceImpl/ObjectPrx.mm @@ -0,0 +1,770 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "ObjectPrx.h" + +#import "Communicator.h" +#import "Connection.h" +#import "OutputStream.h" +#import "Convert.h" + +@implementation ICEObjectPrx + +-(ICEObjectPrx*) initWithObjectPrx:(ICEObjectPrx*)prx +{ + assert(prx); + self = [super init]; + _prx = std::shared_ptr([prx prx]); + return self; +} + +-(ICEObjectPrx*) initWithCppObjectPrx:(std::shared_ptr)prx +{ + if(!prx) + { + return nil; + } + + self = [super init]; + if(!self) + { + return nil; + } + + self->_prx = prx; + + return self; +} + +-(nonnull NSString*) ice_toString +{ + return toNSString(_prx->ice_toString()); +} + +-(ICECommunicator*) ice_getCommunicator +{ + auto comm = _prx->ice_getCommunicator(); + return [ICECommunicator getHandle:comm]; +} + +-(void) ice_getIdentity:(NSString* __strong _Nonnull * _Nonnull)name + category:(NSString* __strong _Nonnull * _Nonnull)category +{ + auto identity = _prx->ice_getIdentity(); + *name = toNSString(identity.name); + *category = toNSString(identity.category); +} + +-(instancetype) ice_identity:(NSString*)name + category:(NSString*)category + error:(NSError**)error +{ + try + { + auto prx = _prx->ice_identity(Ice::Identity{fromNSString(name), fromNSString(category)}); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(NSDictionary*) ice_getContext +{ + return toNSDictionary(_prx->ice_getContext()); +} + +-(instancetype) ice_context:(NSDictionary*)context +{ + Ice::Context ctx; + fromNSDictionary(context, ctx); + + auto prx = _prx->ice_context(ctx); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(NSString*) ice_getFacet +{ + return toNSString(_prx->ice_getFacet()); +} + +-(instancetype) ice_facet:(NSString*)facet +{ + auto prx = _prx->ice_facet(fromNSString(facet)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(NSString*) ice_getAdapterId +{ + return toNSString(_prx->ice_getAdapterId()); +} + +-(instancetype) ice_adapterId:(NSString*)id error:(NSError**)error +{ + try + { + auto prx = _prx->ice_adapterId(fromNSString(id)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(NSArray*) ice_getEndpoints +{ + return toNSArray(_prx->ice_getEndpoints()); +} + +-(instancetype) ice_endpoints:(NSArray*)endpoints error:(NSError**)error +{ + try + { + Ice::EndpointSeq endpts; + fromNSArray(endpoints, endpts); + + auto prx = _prx->ice_endpoints(endpts); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(int32_t) ice_getLocatorCacheTimeout +{ + return _prx->ice_getLocatorCacheTimeout(); +} + +-(instancetype) ice_locatorCacheTimeout:(int32_t)timeout error:(NSError**)error +{ + try + { + auto prx = _prx->ice_locatorCacheTimeout(timeout); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(int32_t) ice_getInvocationTimeout +{ + return _prx->ice_getInvocationTimeout(); +} + +-(instancetype) ice_invocationTimeout:(int32_t)timeout error:(NSError**)error +{ + try + { + auto prx = _prx->ice_invocationTimeout(timeout); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(NSString*) ice_getConnectionId +{ + return toNSString(_prx->ice_getConnectionId()); +} + +-(instancetype) ice_connectionId:(NSString*)connectionId error:(NSError**)error +{ + try + { + auto prx = _prx->ice_connectionId(fromNSString(connectionId)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(bool) ice_isConnectionCached +{ + return _prx->ice_isConnectionCached(); +} + +-(instancetype) ice_connectionCached:(bool)cached error:(NSError**)error +{ + try + { + auto prx = _prx->ice_connectionCached(cached); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(uint8_t) ice_getEndpointSelection +{ + return static_cast(_prx->ice_getEndpointSelection()); +} + +-(instancetype) ice_endpointSelection:(uint8_t)type error:(NSError**)error +{ + try + { + auto prx = _prx->ice_endpointSelection(Ice::EndpointSelectionType(type)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(instancetype) ice_encodingVersion:(uint8_t)major minor:(uint8_t)minor +{ + Ice::EncodingVersion encoding{major, minor}; + + auto prx = _prx->ice_encodingVersion(encoding); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(void) ice_getEncodingVersion:(uint8_t*)major minor:(uint8_t*)minor +{ + Ice::EncodingVersion v = _prx->ice_getEncodingVersion(); + *major = v.major; + *minor = v.minor; +} + +-(ICEObjectPrx*) ice_getRouter +{ + return [[ICEObjectPrx alloc] initWithCppObjectPrx:_prx->ice_getRouter()]; +} + +-(instancetype) ice_router:(ICEObjectPrx*)router error:(NSError**)error +{ + try + { + auto r = router ? [router prx] : nullptr; + auto prx = _prx->ice_router(Ice::uncheckedCast(r)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(ICEObjectPrx*) ice_getLocator +{ + return [[ICEObjectPrx alloc] initWithCppObjectPrx:_prx->ice_getLocator()]; +} + +-(instancetype) ice_locator:(ICEObjectPrx*)locator error:(NSError**)error +{ + try + { + auto l = locator ? [locator prx] : nullptr; + auto prx = _prx->ice_locator(Ice::uncheckedCast(l)); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(bool) ice_isSecure +{ + return _prx->ice_isSecure(); +} + +-(instancetype) ice_secure:(bool)b +{ + auto prx = _prx->ice_secure(b); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(bool) ice_isPreferSecure +{ + return _prx->ice_isPreferSecure(); +} + +-(instancetype) ice_preferSecure:(bool)b error:(NSError**)error +{ + try + { + auto prx = _prx->ice_preferSecure(b); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(bool) ice_isTwoway +{ + return _prx->ice_isTwoway(); +} + +-(nonnull instancetype) ice_twoway +{ + auto prx = _prx->ice_twoway(); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(bool) ice_isOneway +{ + return _prx->ice_isOneway(); +} + +-(nonnull instancetype) ice_oneway +{ + auto prx = _prx->ice_oneway(); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(bool) ice_isBatchOneway +{ + return _prx->ice_isBatchOneway(); +} + +-(instancetype) ice_batchOneway +{ + auto prx = _prx->ice_batchOneway(); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(bool) ice_isDatagram +{ + return _prx->ice_isDatagram(); +} + +-(instancetype) ice_datagram +{ + auto prx = _prx->ice_datagram(); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(bool) ice_isBatchDatagram +{ + return _prx->ice_isBatchDatagram(); +} + +-(instancetype) ice_batchDatagram +{ + auto prx = _prx->ice_batchDatagram(); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(nullable id) ice_getCompress +{ + auto compress = _prx->ice_getCompress(); + if(!compress.has_value()) + { + return nil; + } + return [NSNumber numberWithBool: compress.value() ? YES : NO]; +} + +-(instancetype) ice_compress:(bool)compress +{ + auto prx = _prx->ice_compress(compress); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; +} + +-(id) ice_getTimeout +{ + auto timeout = _prx->ice_getTimeout(); + if(!timeout.has_value()) + { + return nil; + } + return [NSNumber numberWithInt:timeout.value()]; +} + +-(instancetype) ice_timeout:(int32_t)timeout error:(NSError**)error +{ + try + { + auto prx = _prx->ice_timeout(timeout); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(instancetype) ice_fixed:(ICEConnection*)connection error:(NSError**)error +{ + try + { + auto prx = _prx->ice_fixed([connection connection]); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(bool) ice_isFixed +{ + return _prx->ice_isFixed(); +} + +-(id)ice_getConnection:(NSError**)error +{ + try + { + auto cppConnection = _prx->ice_getConnection(); + ICEConnection* connection = [ICEConnection getHandle:cppConnection]; + + return connection ? connection : [NSNull null]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(void) ice_getConnectionAsync:(void (^)(ICEConnection* _Nullable)) response + exception:(void (^)(NSError*))exception +{ + try + { + _prx->ice_getConnectionAsync( + [response] + (std::shared_ptr cppConnection) + { + @autoreleasepool + { + response([ICEConnection getHandle:cppConnection]); + } + }, + [exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(ICEConnection*) ice_getCachedConnection +{ + auto cppConnection = _prx->ice_getCachedConnection(); + return [ICEConnection getHandle:cppConnection]; +} + +-(BOOL) ice_flushBatchRequests:(NSError**)error +{ + try + { + _prx->ice_flushBatchRequests(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) ice_flushBatchRequestsAsync:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent +{ + try + { + _prx->ice_flushBatchRequestsAsync([exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }, + [sent](bool sentSynchronously) + { + if(sent) + { + sent(sentSynchronously); + } + }); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(bool) ice_isCollocationOptimized +{ + return _prx->ice_isCollocationOptimized(); +} + +-(instancetype) ice_collocationOptimized:(bool)collocated + error:(NSError* _Nullable * _Nullable)error +{ + try + { + auto prx = _prx->ice_collocationOptimized(collocated); + return _prx == prx ? self : [[ICEObjectPrx alloc] initWithCppObjectPrx:prx]; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + ++(id) ice_read:(NSData*)data + communicator:(ICECommunicator*)communicator + encodingMajor:(uint8_t)major + encodingMinor:(uint8_t)minor + bytesRead:(NSInteger*)bytesRead + error:(NSError**)error +{ + + std::pair p; + p.first = static_cast(data.bytes); + p.second = p.first + data.length; + + auto comm = [communicator communicator]; + + try + { + Ice::InputStream ins(comm, Ice::EncodingVersion{major, minor}, p); + + std::shared_ptr proxy; + ins.read(proxy); + + *bytesRead = ins.pos(); + if(proxy) + { + return [[ICEObjectPrx alloc] initWithCppObjectPrx:proxy]; + } + else + { + return [NSNull null]; + } + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(void) ice_write:(id)os + encodingMajor:(uint8_t)encodingMajor + encodingMinor:(uint8_t)encodingMinor +{ + // + // Marshal a proxy into a stream and return the encoded bytes. + // + auto communicator = _prx->ice_getCommunicator(); + Ice::EncodingVersion encoding { encodingMajor, encodingMinor }; + Ice::OutputStream out(communicator, encoding); + out.write(_prx); + auto p = out.finished(); + [os copy:p.first count:static_cast(p.second - p.first)]; +} + +-(BOOL) invoke:(NSString* _Nonnull)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary* _Nullable)context + response:(void (^)(bool, void*, long))response + error:(NSError**)error +{ + std::pair params(0, 0); + params.first = static_cast(inParams.bytes); + params.second = params.first + inParams.length; + + try + { + Ice::Context ctx; + if(context) + { + fromNSDictionary(context, ctx); + } + std::vector outParams; + + // We use a std::promise and invokeAsync to avoid making an extra copy of the outParam buffer + // and to avoid calling PromiseKit wait. PromiseKit issues a warning if wait() is called on the main thread. + // This is particularly an issue in command line applications which may make sync calls on the main thread. + std::promise p; + + _prx->ice_invokeAsync(fromNSString(op), static_cast(mode), params, + [response, &p](bool ok, std::pair outParams) + { + // We need an autorelease pool as the unmarshaling (in the response) can + // create autorelease objects, typically when unmarshaling proxies + @autoreleasepool + { + response(ok, const_cast(outParams.first), + static_cast(outParams.second - outParams.first)); + } + p.set_value(); + }, + [&p](std::exception_ptr e) + { + p.set_exception(e); + }, + nullptr, + context ? ctx : Ice::noExplicitContext); + + p.get_future().get(); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(BOOL) onewayInvoke:(NSString*)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary*)context + error:(NSError**)error +{ + std::pair params(0, 0); + params.first = static_cast(inParams.bytes); + params.second = params.first + inParams.length; + + try + { + Ice::Context ctx; + if(context) + { + fromNSDictionary(context, ctx); + } + + std::vector ignored; + _prx->ice_invoke(fromNSString(op), static_cast(mode), params, ignored, + context ? ctx : Ice::noExplicitContext); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void) invokeAsync:(NSString* _Nonnull)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary* _Nullable)context + response:(void (^)(bool, void*, long))response + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent +{ + std::pair params(0, 0); + params.first = static_cast(inParams.bytes); + params.second = params.first + inParams.length; + + try + { + Ice::Context ctx; + if(context) + { + fromNSDictionary(context, ctx); + } + + _prx->ice_invokeAsync(fromNSString(op), static_cast(mode), params, + [response](bool ok, std::pair outParams) + { + // We need an autorelease pool in case the unmarshaling creates auto + // release objects, and in case the application attaches a handler to + // the promise that runs on nil (= the Ice thread/dispatch queue that + // executes response) + @autoreleasepool + { + response(ok, const_cast(outParams.first), + static_cast(outParams.second - outParams.first)); + } + }, + [exception](std::exception_ptr e) + { + @autoreleasepool + { + exception(convertException(e)); + } + }, + [sent](bool sentSynchronously) + { + if(sent) + { + sent(sentSynchronously); + } + }, + context ? ctx : Ice::noExplicitContext); + } + catch(const std::exception& ex) + { + // Typically CommunicatorDestroyedException. Note that the callback is called on the + // thread making the invocation, which is fine since we only use it to fulfill the + // PromiseKit promise. + exception(convertException(ex)); + } +} + +-(bool) isEqual:(ICEObjectPrx*)other +{ + return Ice::targetEqualTo(_prx, other.prx); +} + +-(bool) proxyIdentityLess:(ICEObjectPrx*)other +{ + return Ice::proxyIdentityLess(_prx, other.prx); +} + +-(bool) proxyIdentityEqual:(ICEObjectPrx*)other +{ + return Ice::proxyIdentityEqual(_prx, other.prx); +} + +-(bool) proxyIdentityAndFacetLess:(ICEObjectPrx*)other +{ + return Ice::proxyIdentityAndFacetLess(_prx, other.prx); +} + +-(bool) proxyIdentityAndFacetEqual:(ICEObjectPrx*)other +{ + return Ice::proxyIdentityAndFacetEqual(_prx, other.prx); +} +@end diff --git a/Sources/IceImpl/Process.mm b/Sources/IceImpl/Process.mm new file mode 100644 index 0000000..f96d483 --- /dev/null +++ b/Sources/IceImpl/Process.mm @@ -0,0 +1,27 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Process.h" +#import "Convert.h" + +@implementation ICEProcess + +-(std::shared_ptr) process +{ + return std::static_pointer_cast(self.cppObject); +} + +-(void) shutdown +{ + // This fuction does not use current so we do not pass it from Swift + self.process->shutdown(Ice::Current{}); +} + +-(void) writeMessage:(NSString*)message fd:(int32_t)fd +{ + // This function does not use current so we do not pass it from Swift + self.process->writeMessage(fromNSString(message), fd, Ice::Current{}); +} + +@end diff --git a/Sources/IceImpl/Properties.mm b/Sources/IceImpl/Properties.mm new file mode 100644 index 0000000..9071b4c --- /dev/null +++ b/Sources/IceImpl/Properties.mm @@ -0,0 +1,122 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Properties.h" + +#import "Convert.h" + +@implementation ICEProperties + +-(std::shared_ptr) properties +{ + return std::static_pointer_cast(self.cppObject); +} + +-(NSString*) getProperty:(NSString*)key +{ + return toNSString(self.properties->getProperty(fromNSString(key))); +} + +-(NSString*) getPropertyWithDefault:(NSString*)key value:(NSString*)value +{ + return toNSString(self.properties->getPropertyWithDefault(fromNSString(key), fromNSString(value))); +} + +-(int32_t) getPropertyAsInt:(NSString*)key +{ + return self.properties->getPropertyAsInt(fromNSString(key)); +} + +-(int32_t) getPropertyAsIntWithDefault:(NSString*)key value:(int32_t)value +{ + return self.properties->getPropertyAsIntWithDefault(fromNSString(key), value); +} + +-(NSArray*) getPropertyAsList:(NSString*)key +{ + return toNSArray(self.properties->getPropertyAsList(fromNSString(key))); +} + +-(NSArray*) getPropertyAsListWithDefault:(NSString*)key value:(NSArray*)value +{ + std::vector s; + fromNSArray(value, s); + return toNSArray(self.properties->getPropertyAsListWithDefault(fromNSString(key), s)); +} + +-(NSDictionary*) getPropertiesForPrefix:(NSString*)prefix +{ + return toNSDictionary(self.properties->getPropertiesForPrefix(fromNSString(prefix))); +} + +-(BOOL) setProperty:(NSString*)key value:(NSString*)value error:(NSError**)error; +{ + try + { + self.properties->setProperty(fromNSString(key), fromNSString(value)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(NSArray*) getCommandLineOptions +{ + return toNSArray(self.properties->getCommandLineOptions()); +} + +-(NSArray*) parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options error:(NSError**)error; +{ + try + { + std::vector s; + fromNSArray(options, s); + return toNSArray(self.properties->parseCommandLineOptions(fromNSString(prefix), s)); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(NSArray*) parseIceCommandLineOptions:(NSArray*)options error:(NSError**)error; +{ + try + { + std::vector s; + fromNSArray(options, s); + return toNSArray(self.properties->parseIceCommandLineOptions(s)); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(BOOL) load:(NSString*)file error:(NSError**)error +{ + try + { + self.properties->load(fromNSString(file)); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(ICEProperties*) clone +{ + auto props = self.properties->clone(); + return [ICEProperties getHandle:props]; +} + +@end diff --git a/Sources/IceImpl/PropertiesAdmin.mm b/Sources/IceImpl/PropertiesAdmin.mm new file mode 100644 index 0000000..f6c73ce --- /dev/null +++ b/Sources/IceImpl/PropertiesAdmin.mm @@ -0,0 +1,77 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "PropertiesAdmin.h" +#import "Convert.h" + +@implementation ICEPropertiesAdmin + +-(std::shared_ptr) propertiesAdmin +{ + return std::static_pointer_cast(self.cppObject); +} + +-(nullable NSString*) getProperty:(NSString*)key error:(NSError**)error +{ + try + { + // This function does not use current so we do not pass it from Swift + return toNSString(self.propertiesAdmin->getProperty(fromNSString(key), Ice::Current{})); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(nullable NSDictionary*) getPropertiesForPrefix:(NSString*)prefix error:(NSError**)error +{ + try + { + // This function does not use current so we do not pass it from Swift + return toNSDictionary(self.propertiesAdmin->getPropertiesForPrefix(fromNSString(prefix), Ice::Current{})); + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return nil; + } +} + +-(BOOL) setProperties:(NSDictionary*)newProperties error:(NSError**)error +{ + try + { + // This function does not use current so we do not pass it from Swift + Ice::PropertyDict props; + fromNSDictionary(newProperties, props); + self.propertiesAdmin->setProperties(props, Ice::Current{}); + return YES; + } + catch(const std::exception& ex) + { + *error = convertException(ex); + return NO; + } +} + +-(void (^)(void)) addUpdateCallback:(void (^)(NSDictionary*))cb +{ + auto facet = std::dynamic_pointer_cast(self.propertiesAdmin); + assert(facet); + + auto removeCb = facet->addUpdateCallback([cb] (const Ice::PropertyDict& props) + { + cb(toNSDictionary(props)); + }); + + return ^ + { + removeCb(); + }; + +} + +@end diff --git a/Sources/IceImpl/TraceUtil.mm b/Sources/IceImpl/TraceUtil.mm new file mode 100644 index 0000000..e798f07 --- /dev/null +++ b/Sources/IceImpl/TraceUtil.mm @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "TraceUtil.h" + +#import +#import "LoggerWrapperI.h" + +@implementation ICETraceUtil + ++(void) traceSlicing:(NSString*)kind + typeId:(NSString*)typeId + slicingCat:(NSString*)slicingCat + logger:(id)logger +{ + auto l = std::make_shared(logger); + IceInternal::traceSlicing(fromNSString(kind).c_str(), fromNSString(typeId), fromNSString(slicingCat).c_str(), l); +} + +@end diff --git a/Sources/IceImpl/Transceiver.h b/Sources/IceImpl/Transceiver.h new file mode 100644 index 0000000..25c0785 --- /dev/null +++ b/Sources/IceImpl/Transceiver.h @@ -0,0 +1,78 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICE_IAP_TRANSCEIVER_H +#define ICE_IAP_TRANSCEIVER_H + +#include +#include +#include +#include + +#import +#import + +@class iAPTransceiverCallback; + +namespace IceObjC +{ + +class iAPTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo +{ + enum State + { + StateNeedConnect, + StateConnectPending, + StateConnected + }; + +public: + + iAPTransceiver(const IceInternal::ProtocolInstancePtr&, EASession*); + virtual ~iAPTransceiver(); + + virtual void initStreams(IceInternal::SelectorReadyCallback*); + virtual IceInternal::SocketOperation registerWithRunLoop(IceInternal::SocketOperation); + virtual IceInternal::SocketOperation unregisterFromRunLoop(IceInternal::SocketOperation, bool); + virtual void closeStreams(); + + virtual IceInternal::NativeInfoPtr getNativeInfo(); + + virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&); + + virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&); + virtual void close(); + virtual IceInternal::SocketOperation write(IceInternal::Buffer&); + virtual IceInternal::SocketOperation read(IceInternal::Buffer&); + + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const IceInternal::Buffer&); + virtual void setBufferSize(int, int); + +private: + + void checkErrorStatus(NSStream*, const char*, int); + + IceInternal::ProtocolInstancePtr _instance; + EASession* _session; + NSInputStream* _readStream; + NSOutputStream* _writeStream; + iAPTransceiverCallback* _callback; + bool _readStreamRegistered; + bool _writeStreamRegistered; + bool _opening; + + IceUtil::Mutex _mutex; + bool _error; + + State _state; + std::string _desc; +}; + +} + +#endif diff --git a/Sources/IceImpl/Transceiver.mm b/Sources/IceImpl/Transceiver.mm new file mode 100644 index 0000000..f1a7757 --- /dev/null +++ b/Sources/IceImpl/Transceiver.mm @@ -0,0 +1,481 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#if TARGET_OS_IPHONE != 0 + +#include "Transceiver.h" +#include "EndpointI.h" + +#include + +#include +#include +#include + +#import +#import +#import + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +@interface iAPTransceiverCallback : NSObject +{ +@private + + SelectorReadyCallback* callback; +} +-(id) init:(SelectorReadyCallback*)cb; +@end + +@implementation iAPTransceiverCallback +-(id) init:(SelectorReadyCallback*)cb +{ + self = [super init]; + if(!self) + { + return nil; + } + callback = cb; + return self; +} + +- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode +{ + switch(eventCode) + { + case NSStreamEventHasBytesAvailable: + callback->readyCallback(SocketOperationRead); + break; + case NSStreamEventHasSpaceAvailable: + callback->readyCallback(SocketOperationWrite); + break; + case NSStreamEventOpenCompleted: + if([[stream class] isSubclassOfClass:[NSInputStream class]]) + { + callback->readyCallback(static_cast(SocketOperationConnect | SocketOperationRead)); + } + else + { + callback->readyCallback(static_cast(SocketOperationConnect | SocketOperationWrite)); + } + break; + default: + if([[stream class] isSubclassOfClass:[NSInputStream class]]) + { + callback->readyCallback(SocketOperationRead, -1); // Error + } + else + { + callback->readyCallback(SocketOperationWrite, -1); // Error + } + } +} +@end + +void +IceObjC::iAPTransceiver::initStreams(SelectorReadyCallback* callback) +{ + _callback = [[iAPTransceiverCallback alloc] init:callback]; + [_writeStream setDelegate:_callback]; + [_readStream setDelegate:_callback]; +} + +SocketOperation +IceObjC::iAPTransceiver::registerWithRunLoop(SocketOperation op) +{ + IceUtil::Mutex::Lock sync(_mutex); + SocketOperation readyOp = SocketOperationNone; + if(op & SocketOperationConnect) + { + if([_writeStream streamStatus] != NSStreamStatusNotOpen || [_readStream streamStatus] != NSStreamStatusNotOpen) + { + return SocketOperationConnect; + } + + _opening = true; + + [_writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + + _writeStreamRegistered = true; // Note: this must be set after the schedule call + _readStreamRegistered = true; // Note: this must be set after the schedule call + + [_writeStream open]; + [_readStream open]; + } + else + { + if(op & SocketOperationWrite) + { + if([_writeStream hasSpaceAvailable]) + { + readyOp = static_cast(readyOp | SocketOperationWrite); + } + else if(!_writeStreamRegistered) + { + [_writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + _writeStreamRegistered = true; // Note: this must be set after the schedule call + if([_writeStream hasSpaceAvailable]) + { + readyOp = static_cast(readyOp | SocketOperationWrite); + } + } + } + + if(op & SocketOperationRead) + { + if([_readStream hasBytesAvailable]) + { + readyOp = static_cast(readyOp | SocketOperationRead); + } + else if(!_readStreamRegistered) + { + [_readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + _readStreamRegistered = true; // Note: this must be set after the schedule call + if([_readStream hasBytesAvailable]) + { + readyOp = static_cast(readyOp | SocketOperationRead); + } + } + } + } + return readyOp; +} + +SocketOperation +IceObjC::iAPTransceiver::unregisterFromRunLoop(SocketOperation op, bool error) +{ + IceUtil::Mutex::Lock sync(_mutex); + _error |= error; + + if(_opening) + { + // Wait for the stream to be ready for write + if(op == SocketOperationWrite) + { + _writeStreamRegistered = false; + } + + // + // We don't wait for the stream to be ready for read (even if + // it's a client connection) because there's no guarantees that + // the server might actually send data right away. If we use + // the WebSocket transport, the server actually waits for the + // client to write the HTTP upgrade request. + // + //if(op & SocketOperationRead && (_fd != INVALID_SOCKET || !(op & SocketOperationConnect))) + if(op == (SocketOperationRead | SocketOperationConnect)) + { + _readStreamRegistered = false; + } + + if(error || (!_readStreamRegistered && !_writeStreamRegistered)) + { + [_writeStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [_readStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + _opening = false; + return SocketOperationConnect; + } + else + { + return SocketOperationNone; + } + } + else + { + if(op & SocketOperationWrite && _writeStreamRegistered) + { + [_writeStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + _writeStreamRegistered = false; + } + + if(op & SocketOperationRead && _readStreamRegistered) + { + [_readStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + _readStreamRegistered = false; + } + } + return op; +} + +void +IceObjC::iAPTransceiver::closeStreams() +{ + [_writeStream setDelegate:nil]; + [_readStream setDelegate:nil]; + +#if defined(__clang__) && !__has_feature(objc_arc) + [_callback release]; +#endif + _callback = 0; + + [_writeStream close]; + [_readStream close]; +} + +IceInternal::NativeInfoPtr +IceObjC::iAPTransceiver::getNativeInfo() +{ + return this; +} + +SocketOperation +IceObjC::iAPTransceiver::initialize(Buffer& /*readBuffer*/, Buffer& /*writeBuffer*/) +{ + IceUtil::Mutex::Lock sync(_mutex); + if(_state == StateNeedConnect) + { + _state = StateConnectPending; + return SocketOperationConnect; + } + + if(_state <= StateConnectPending) + { + if(_error) + { + checkErrorStatus(_writeStream, __FILE__, __LINE__); + checkErrorStatus(_readStream, __FILE__, __LINE__); + } + _state = StateConnected; + } + assert(_state == StateConnected); + return SocketOperationNone; +} + +SocketOperation +IceObjC::iAPTransceiver::closing(bool initiator, const Ice::LocalException&) +{ + // If we are initiating the connection closure, wait for the peer + // to close the TCP/IP connection. Otherwise, close immediately. + return initiator ? SocketOperationRead : SocketOperationNone; +} + +void +IceObjC::iAPTransceiver::close() +{ +} + +SocketOperation +IceObjC::iAPTransceiver::write(Buffer& buf) +{ + // Don't hold the lock while calling on the NSStream API to avoid deadlocks in case the NSStream API calls + // the stream notification callbacks with an internal lock held. + { + IceUtil::Mutex::Lock sync(_mutex); + if(_error) + { + checkErrorStatus(_writeStream, __FILE__, __LINE__); + } + else if(_writeStreamRegistered) + { + return SocketOperationWrite; + } + } + + size_t packetSize = static_cast(buf.b.end() - buf.i); + while(buf.i != buf.b.end()) + { + if(![_writeStream hasSpaceAvailable]) + { + return SocketOperationWrite; + } + assert([_writeStream streamStatus] >= NSStreamStatusOpen); + + NSInteger ret = [_writeStream write:reinterpret_cast(&*buf.i) maxLength:packetSize]; + if(ret == SOCKET_ERROR) + { + checkErrorStatus(_writeStream, __FILE__, __LINE__); + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + } + continue; + } + + buf.i += ret; + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + + return SocketOperationNone; +} + +SocketOperation +IceObjC::iAPTransceiver::read(Buffer& buf) +{ + // Don't hold the lock while calling on the NSStream API to avoid deadlocks in case the NSStream API calls + // the stream notification callbacks with an internal lock held. + { + IceUtil::Mutex::Lock sync(_mutex); + if(_error) + { + checkErrorStatus(_readStream, __FILE__, __LINE__); + } + else if(_readStreamRegistered) + { + return SocketOperationRead; + } + } + + size_t packetSize = static_cast(buf.b.end() - buf.i); + while(buf.i != buf.b.end()) + { + if(![_readStream hasBytesAvailable] && [_readStream streamStatus] != NSStreamStatusError) + { + return SocketOperationRead; + } + assert([_readStream streamStatus] >= NSStreamStatusOpen); + + NSInteger ret = [_readStream read:reinterpret_cast(&*buf.i) maxLength:packetSize]; + if(ret == 0) + { + throw ConnectionLostException(__FILE__, __LINE__); + } + + if(ret == SOCKET_ERROR) + { + checkErrorStatus(_readStream, __FILE__, __LINE__); + if(noBuffers() && packetSize > 1024) + { + packetSize /= 2; + } + continue; + } + + buf.i += ret; + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + + return SocketOperationNone; +} + +string +IceObjC::iAPTransceiver::protocol() const +{ + return _instance->protocol(); +} + +string +IceObjC::iAPTransceiver::toString() const +{ + return _desc; +} + +string +IceObjC::iAPTransceiver::toDetailedString() const +{ + return toString(); +} + +Ice::ConnectionInfoPtr +IceObjC::iAPTransceiver::getInfo() const +{ + IceIAP::ConnectionInfoPtr info = ICE_MAKE_SHARED(IceIAP::ConnectionInfo); + info->manufacturer = [_session.accessory.manufacturer UTF8String]; + info->name = [_session.accessory.name UTF8String]; + info->modelNumber = [_session.accessory.modelNumber UTF8String]; + info->firmwareRevision = [_session.accessory.firmwareRevision UTF8String]; + info->hardwareRevision = [_session.accessory.hardwareRevision UTF8String]; + info->protocol = [_session.protocolString UTF8String]; + return info; +} + +void +IceObjC::iAPTransceiver::checkSendSize(const Buffer& /*buf*/) +{ +} + +void +IceObjC::iAPTransceiver::setBufferSize(int, int) +{ +} + +IceObjC::iAPTransceiver::iAPTransceiver(const ProtocolInstancePtr& instance, EASession* session) : + StreamNativeInfo(INVALID_SOCKET), + _instance(instance), +#if defined(__clang__) && !__has_feature(objc_arc) + _session([session retain]), +#else + _session(session), +#endif + _readStream([session inputStream]), + _writeStream([session outputStream]), + _readStreamRegistered(false), + _writeStreamRegistered(false), + _error(false), + _state(StateNeedConnect) +{ + ostringstream os; + os << "name = " << [session.accessory.name UTF8String] << "\n"; + os << "protocol = " << [session.protocolString UTF8String]; + _desc = os.str(); +} + +IceObjC::iAPTransceiver::~iAPTransceiver() +{ +#if defined(__clang__) && !__has_feature(objc_arc) + [_session release]; +#endif +} + +void +IceObjC::iAPTransceiver::checkErrorStatus(NSStream* stream, const char* file, int line) +{ + NSStreamStatus status = [stream streamStatus]; + if(status == NSStreamStatusAtEnd || status == NSStreamStatusClosed) + { + throw ConnectionLostException(file, line); + } + + assert(status == NSStreamStatusError); + NSError* err = [stream streamError]; + assert(err != nil); + + NSString* domain = [err domain]; + if([domain compare:NSPOSIXErrorDomain] == NSOrderedSame) + { + errno = static_cast([err code]); + if(interrupted() || noBuffers()) + { + return; + } + else if(connectionRefused()) + { + ConnectionRefusedException ex(file, line); + ex.error = getSocketErrno(); + throw ex; + } + else if(connectFailed()) + { + ConnectFailedException ex(file, line); + ex.error = getSocketErrno(); + throw ex; + } + else + { + SocketException ex(file, line); + ex.error = getSocketErrno(); + throw ex; + } + } + + // Otherwise throw a generic exception. + CFNetworkException ex(file, line); + ex.domain = [domain UTF8String]; + ex.error = static_cast([err code]); + throw ex; +} + +#endif diff --git a/Sources/IceImpl/UnsupportedAdminFacet.mm b/Sources/IceImpl/UnsupportedAdminFacet.mm new file mode 100644 index 0000000..d84bc10 --- /dev/null +++ b/Sources/IceImpl/UnsupportedAdminFacet.mm @@ -0,0 +1,8 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "UnsupportedAdminFacet.h" + +@implementation ICEUnsupportedAdminFacet +@end diff --git a/Sources/IceImpl/include/AdminFacetFactory.h b/Sources/IceImpl/include/AdminFacetFactory.h new file mode 100644 index 0000000..510408d --- /dev/null +++ b/Sources/IceImpl/include/AdminFacetFactory.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +@class ICECommunicator; +@class ICEProcess; +@class ICEPropertiesAdmin; +@class ICEUnsupportedAdminFacet; +@protocol ICEBlobjectFacade; + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @protocol ICEAdminFacetFactory ++(id) createProcess:(ICECommunicator*)communicator handle:(ICEProcess*)handle; ++(id) createProperties:(ICECommunicator*)communicator handle:(ICEPropertiesAdmin*)handle; ++(id) createUnsupported:(ICECommunicator*)communicator handle:(ICEUnsupportedAdminFacet*)handle; +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/BlobjectFacade.h b/Sources/IceImpl/include/BlobjectFacade.h new file mode 100644 index 0000000..7736502 --- /dev/null +++ b/Sources/IceImpl/include/BlobjectFacade.h @@ -0,0 +1,67 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Config.h" + +@class ICEConnection; +@class ICEObjectAdapter; +@class ICERuntimeException; + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^ICEBlobjectResponse) (bool, const void*, long); +typedef void (^ICEBlobjectException) (ICERuntimeException*); + +ICEIMPL_API @protocol ICEBlobjectFacade +-(void) facadeInvoke:(ICEObjectAdapter*)adapter + inEncapsBytes:(void*)inEncapsBytes + inEncapsCount:(long)inEncapsCount + con:(ICEConnection* _Nullable)con + name:(NSString*)name + category:(NSString*)category + facet:(NSString*)facet + operation:(NSString*)operation + mode:(uint8_t)mode + context:(NSDictionary*)context + requestId:(int32_t)requestId + encodingMajor:(uint8_t)encodingMajor + encodingMinor:(uint8_t)encodingMinor + response:(ICEBlobjectResponse)response + exception:(ICEBlobjectException)exception; +-(void) facadeRemoved; +@end + +#ifdef __cplusplus + +class BlobjectFacade : public Ice::BlobjectArrayAsync +{ +public: + + BlobjectFacade(id facade): _facade(facade) + { + } + + ~BlobjectFacade() + { + [_facade facadeRemoved]; + } + + virtual void + ice_invokeAsync(std::pair inEncaps, + std::function&)> response, + std::function error, + const Ice::Current& current); + + id getFacade() const + { + return _facade; + } + +private: + id _facade; +}; + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Communicator.h b/Sources/IceImpl/include/Communicator.h new file mode 100644 index 0000000..c8d7438 --- /dev/null +++ b/Sources/IceImpl/include/Communicator.h @@ -0,0 +1,68 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +@class ICEObjectPrx; +@class ICEImplicitContext; +@class ICEProperties; +@class ICEObjectAdapter; +@protocol ICELoggerProtocol; +@protocol ICEBlobjectFacade; + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICECommunicator : ICELocalObject +-(void) destroy; +-(void) shutdown; +-(void) waitForShutdown; +-(bool) isShutdown; +-(nullable id) stringToProxy:(NSString*)str error:(NSError**)error NS_SWIFT_NAME(stringToProxy(str:));; +-(nullable id) propertyToProxy:(NSString*)property error:(NSError**)error NS_SWIFT_NAME(propertyToProxy(property:)); +-(nullable NSDictionary*) proxyToProperty:(ICEObjectPrx*)prx property:(NSString*)property error:(NSError**)error NS_SWIFT_NAME(proxyToProperty(prx:property:));; +-(nullable ICEObjectAdapter*) createObjectAdapter:(NSString*)name error:(NSError**)error; +-(nullable ICEObjectAdapter*) createObjectAdapterWithEndpoints:(NSString*)name endpoints:(NSString*)endpoints error:(NSError**)error NS_SWIFT_NAME(createObjectAdapterWithEndpoints(name:endpoints:));; +-(nullable ICEObjectAdapter*) createObjectAdapterWithRouter:(NSString*)name router:(ICEObjectPrx*)router error:(NSError**)error NS_SWIFT_NAME(createObjectAdapterWithRouter(name:router:)); +-(ICEImplicitContext*) getImplicitContext; +-(id) getLogger; +-(nullable ICEObjectPrx*) getDefaultRouter; +-(BOOL) setDefaultRouter:(ICEObjectPrx* _Nullable)router error:(NSError* _Nullable * _Nullable)error; +-(nullable ICEObjectPrx*) getDefaultLocator; +-(BOOL) setDefaultLocator:(ICEObjectPrx* _Nullable)locator error:(NSError* _Nullable * _Nullable)error; +-(BOOL) flushBatchRequests:(uint8_t)compress error:(NSError* _Nullable * _Nullable)error; +-(void) flushBatchRequestsAsync:(uint8_t)compress + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent; +-(nullable ICEObjectPrx*) createAdmin:(ICEObjectAdapter* _Nullable)adminAdapter + name:(NSString*)name + category:(NSString*)category + error:(NSError**)error; +-(nullable id) getAdmin:(NSError**)error; +-(BOOL) addAdminFacet:(id)servant facet:(NSString*)facet error:(NSError**)error; +-(nullable id) removeAdminFacet:(NSString*)facet error:(NSError* _Nullable * _Nullable)error; +-(nullable id) findAdminFacet:(NSString*)facet error:(NSError* _Nullable * _Nullable)error; +-(nullable NSDictionary>*) findAllAdminFacets:(NSError* _Nullable * _Nullable)error; +-(ICEProperties*) getProperties; +-(nullable dispatch_queue_t) getClientDispatchQueue:(NSError* _Nullable * _Nullable)error; +-(nullable dispatch_queue_t) getServerDispatchQueue:(NSError* _Nullable * _Nullable)error; + +// DefaultsAndOverrides +-(void) getDefaultEncoding:(uint8_t*)major minor:(uint8_t*)minor + NS_SWIFT_NAME(getDefaultEncoding(major:minor:)); +-(uint8_t) getDefaultFormat; + +-(void) setSslCertificateVerifier:(nullable bool (^)(id))verifier; +-(void) setSslPasswordPrompt:(nullable NSString* (^)())prompt; +-(BOOL) initializePlugins: (NSError**)error; +@end + +#ifdef __cplusplus + +@interface ICECommunicator() +@property (nonatomic, readonly) std::shared_ptr communicator; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Config.h b/Sources/IceImpl/include/Config.h new file mode 100644 index 0000000..80dc674 --- /dev/null +++ b/Sources/IceImpl/include/Config.h @@ -0,0 +1,22 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import + +#ifndef ICEIMPL_API +# define ICEIMPL_API __attribute__((visibility ("default"))) +#endif + +#ifdef __cplusplus + +#include +#include + +#if TARGET_OS_IPHONE +# include +#endif + +#endif + +# define ICE_SWIFT_UNAVAILABLE(msg) __attribute__((unavailable(msg))) diff --git a/Sources/IceImpl/include/Connection.h b/Sources/IceImpl/include/Connection.h new file mode 100644 index 0000000..36ff118 --- /dev/null +++ b/Sources/IceImpl/include/Connection.h @@ -0,0 +1,117 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +@class ICEObjectPrx; +@class ICEEndpoint; +@class ICEObjectAdapter; + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEConnection : ICELocalObject +-(void) close:(uint8_t)mode; +-(nullable ICEObjectPrx*) createProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error; +-(BOOL) setAdapter:(ICEObjectAdapter* _Nullable)oa error:(NSError* _Nullable * _Nullable)error; +-(nullable ICEObjectAdapter*) getAdapter; +-(ICEEndpoint*) getEndpoint; +-(BOOL) flushBatchRequests:(uint8_t)compress error:(NSError* _Nullable * _Nullable)error; +-(void) flushBatchRequestsAsync:(uint8_t)compress + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent; +-(BOOL) setCloseCallback:(nullable void (^)(ICEConnection*))callback error:(NSError* _Nullable * _Nullable)error; +-(void) setHeartbeatCallback:(nullable void (^)(ICEConnection*))callback; +-(BOOL) heartbeat:(NSError* _Nullable * _Nullable)error; +-(void) heartbeatAsync:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent + NS_SWIFT_NAME(heartbeatAsync(exception:sent:)); +-(void) setACM:(NSNumber* _Nullable)timeout close:(NSNumber* _Nullable)close heartbeat:(NSNumber* _Nullable)heartbeat; +-(void) getACM:(int32_t*)timeout close:(uint8_t*)close heartbeat:(uint8_t*)heartbeat; +-(NSString*) type; +-(int32_t) timeout; +-(NSString*) toString; +-(nullable id) getInfo:(NSError* _Nullable * _Nullable)error; +-(BOOL) setBufferSize:(int32_t)rcvSize sndSize:(int32_t)sndSize error:(NSError* _Nullable * _Nullable)error; +-(BOOL) throwException:(NSError* _Nullable * _Nullable)error; +@end + +ICEIMPL_API @interface ICEConnectionInfo: NSObject +@end + +ICEIMPL_API @protocol ICEConnectionInfoFactory ++(id) createIPConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + localAddress:(NSString*)localAddress + localPort:(int32_t)localPort + remoteAddress:(NSString*)remoteAddress + remotePort:(int32_t)remotePort; + ++(id) createTCPConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + localAddress:(NSString*)localAddress + localPort:(int32_t)localPort + remoteAddress:(NSString*)remoteAddress + remotePort:(int32_t)remotePort + rcvSize:(int32_t)rcvSize + sndSize:(int32_t)sndSize; + ++(id) createUDPConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + localAddress:(NSString*)localAddress + localPort:(int32_t)localPort + remoteAddress:(NSString*)remoteAddress + remotePort:(int32_t)remotePort + mcastAddress:(NSString*)mcastAddress + mcastPort:(int32_t)mcastPort + rcvSize:(int32_t)rcvSize + sndSize:(int32_t)sndSize; + ++(id) createWSConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + headers:(NSDictionary*)headers; + ++(id) createSSLConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + cipher:(NSString*)cipher + certs:(NSArray*)certs + verified:(BOOL)verified; + +#if TARGET_OS_IPHONE + ++(id) createIAPConnectionInfo:(id)underlying + incoming:(BOOL)incoming + adapterName:(NSString*)adapterName + connectionId:(NSString*)connectionId + name:(NSString*)name + manufacturer:(NSString*)manufacturer + modelNumber:(NSString*)modelNumber + firmwareRevision:(NSString*)firmwareRevision + hardwareRevision:(NSString*)hardwareRevision + protocol:(NSString*)protocol; + +#endif + +@end + +#ifdef __cplusplus + +id createConnectionInfo(std::shared_ptr); + +@interface ICEConnection() +@property (nonatomic, readonly) std::shared_ptr connection; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Endpoint.h b/Sources/IceImpl/include/Endpoint.h new file mode 100644 index 0000000..6ca6fe3 --- /dev/null +++ b/Sources/IceImpl/include/Endpoint.h @@ -0,0 +1,87 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEEndpoint: ICELocalObject +-(NSString*) toString; +-(id) getInfo; +-(bool) isEqual:(ICEEndpoint* _Nullable)endpoint; +@end + +ICEIMPL_API @interface ICEEndpointInfo: ICELocalObject +-(int16_t) getType; +-(BOOL) getDatagram; +-(BOOL) getSecure; +@end + +ICEIMPL_API @protocol ICEEndpointInfoFactory ++(id) createTCPEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress + host:(NSString*)host + port:(int32_t)port + sourceAddress:(NSString*)sourceAddress; + ++(id) createUDPEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress + host:(NSString*)host + port:(int32_t)port + sourceAddress:(NSString*)sourceAddress + mcastInterface:(NSString*)mcastInterface + mcastTtl:(int32_t)mcastTtl; + ++(id) createWSEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress + resource:(NSString*)resource; + ++(id) createOpaqueEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress + encodingMajor:(UInt8)encodingMajor + encodingMinor:(UInt8)encodingMinor + rawBytes:(NSData*)rawBytes; + ++(id) createSSLEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress; + +#if TARGET_OS_IPHONE + ++(id) createIAPEndpointInfo:(ICEEndpointInfo*)handle + underlying:(id)underlying + timeout:(int32_t)timeout + compress:(BOOL)compress + manufacturer:(NSString*)manufacturer + modelNumber:(NSString*)modelNumber + name:(NSString*)name + protocol:(NSString*)protocol; + +#endif + +@end + +#ifdef __cplusplus + +@interface ICEEndpoint() +@property (nonatomic, readonly) std::shared_ptr endpoint; ++(nullable ICEEndpointInfo*) createEndpointInfo:(std::shared_ptr)infoPtr NS_RETURNS_RETAINED; +@end + +@interface ICEEndpointInfo() +@property (nonatomic, readonly) std::shared_ptr info; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Exception.h b/Sources/IceImpl/include/Exception.h new file mode 100644 index 0000000..9df6276 --- /dev/null +++ b/Sources/IceImpl/include/Exception.h @@ -0,0 +1,130 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import +#import "Config.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @protocol ICEExceptionFactory ++(NSError*) initializationException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) pluginInitializationException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) collocationOptimizationException:(NSString*)file line:(size_t)line; ++(NSError*) alreadyRegisteredException:(NSString*)kindOfObject id:(NSString*)id file:(NSString*)file line:(size_t)line; ++(NSError*) notRegisteredException:(NSString*)kindOfObject id:(NSString*)id file:(NSString*)file line:(size_t)line; ++(NSError*) twowayOnlyException:(NSString*)operation file:(NSString*)file line:(size_t)line; ++(NSError*) cloneNotImplementedException:(NSString*)file line:(size_t)line; ++(NSError*) versionMismatchException:(NSString*)file line:(size_t)line; ++(NSError*) communicatorDestroyedException:(NSString*)file line:(size_t)line; ++(NSError*) objectAdapterDeactivatedException:(NSString*)name file:(NSString*)file line:(size_t)line; ++(NSError*) objectAdapterIdInUseException:(NSString*)id file:(NSString*)file line:(size_t)line NS_SWIFT_NAME(objectAdapterIdInUseException(_:file:line:)); ++(NSError*) noEndpointException:(NSString*)proxy file:(NSString*)file line:(size_t)line; ++(NSError*) endpointParseException:(NSString*)str file:(NSString*)file line:(size_t)line; ++(NSError*) endpointSelectionTypeParseException:(NSString*)str file:(NSString*)file line:(size_t)line; ++(NSError*) versionParseException:(NSString*)str file:(NSString*)file line:(size_t)line; ++(NSError*) identityParseException:(NSString*)str file:(NSString*)file line:(size_t)line; ++(NSError*) proxyParseException:(NSString*)str file:(NSString*)file line:(size_t)line; ++(NSError*) illegalIdentityException:(NSString*)name category:(NSString*)category file:(NSString*)file line:(size_t)line; ++(NSError*) illegalServantException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) dNSException:(int32_t)error host:(NSString*)host file:(NSString*)file line:(size_t)line; ++(NSError*) operationInterruptedException:(NSString*)file line:(size_t)line; ++(NSError*) invocationCanceledException:(NSString*)file line:(size_t)line; ++(NSError*) featureNotSupportedException:(NSString*)unsupportedFeature file:(NSString*)file line:(size_t)line; ++(NSError*) fixedProxyException:(NSString*)file line:(size_t)line; ++(NSError*) responseSentException:(NSString*)file line:(size_t)line; ++(NSError*) securityException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) localException:(NSString*)file line:(size_t)line; + +// UnknownException ++(NSError*) unknownLocalException:(NSString*)unknown file:(NSString*)file line:(size_t)line; ++(NSError*) unknownUserException:(NSString*)unknown file:(NSString*)file line:(size_t)line; ++(NSError*) unknownException:(NSString*)unknown file:(NSString*)file line:(size_t)line; + +// RequestFailedException ++(NSError*) objectNotExistException:(NSString*)name category:(NSString*)category facet:(NSString*)facet operation:(NSString*)operation file:(NSString*)file line:(size_t)line; ++(NSError*) facetNotExistException:(NSString*)name category:(NSString*)category facet:(NSString*)facet operation:(NSString*)operation file:(NSString*)file line:(size_t)line; ++(NSError*) operationNotExistException:(NSString*)name category:(NSString*)category facet:(NSString*)facet operation:(NSString*)operation file:(NSString*)file line:(size_t)line; ++(NSError*) requestFailedException:(NSString*)name category:(NSString*)category facet:(NSString*)facet operation:(NSString*)operation file:(NSString*)file line:(size_t)line; + +// SyscallException ++(NSError*) connectionRefusedException:(int32_t)error file:(NSString*)file line:(size_t)line; // ConnectFailedException: SyscallException ++(NSError*) fileException:(int32_t)error path:(NSString*)path file:(NSString*)file line:(size_t)line; ++(NSError*) connectFailedException:(int32_t)error file:(NSString*)file line:(size_t)line; ++(NSError*) connectionLostException:(int32_t)error file:(NSString*)file line:(size_t)line; ++(NSError*) socketException:(int32_t)error file:(NSString*)file line:(size_t)line; ++(NSError*) syscallException:(int32_t)error file:(NSString*)file line:(size_t)line; + +// TimeoutException ++(NSError*) connectTimeoutException:(NSString*)file line:(size_t)line; ++(NSError*) closeTimeoutException:(NSString*)file line:(size_t)line; ++(NSError*) connectionTimeoutException:(NSString*)file line:(size_t)line; ++(NSError*) invocationTimeoutException:(NSString*)file line:(size_t)line; ++(NSError*) timeoutException:(NSString*)file line:(size_t)line; + +// ProtocolException ++(NSError*) badMagicException:(NSString*)reason badMagic:(NSData*)badMagic file:(NSString*)file line:(size_t)line; ++(NSError*) unsupportedProtocolException:(NSString*)reason badMajor:(uint8_t)badMajor badMinor:(uint8_t)badMinor supportedMajor:(uint8_t)supportedMajor supportedMinor:(uint8_t)supportedMinor file:(NSString*)file line:(size_t)line; ++(NSError*) unsupportedEncodingException:(NSString*)reason badMajor:(uint8_t)badMajor badMinor:(uint8_t)badMinor supportedMajor:(uint8_t)supportedMajor supportedMinor:(uint8_t)supportedMinor file:(NSString*)file line:(size_t)line; ++(NSError*) unknownMessageException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) connectionNotValidatedException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) unknownRequestIdException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) unknownReplyStatusException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) closeConnectionException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) connectionManuallyClosedException:(BOOL)graceful file:(NSString*)file line:(size_t)line; ++(NSError*) illegalMessageSizeException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) compressionException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) datagramLimitException:(NSString*)reason file:(NSString*)file line:(size_t)line; +// ProtocolException/MarshalException ++(NSError*) proxyUnmarshalException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) unmarshalOutOfBoundsException:(NSString*)reason file:(NSString*)file line:(size_t)line NS_SWIFT_NAME(unmarshalOutofBoundsException(_:file:line:)); ++(NSError*) noValueFactoryException:(NSString*)reason type:(NSString*)type file:(NSString*)file line:(size_t)line; ++(NSError*) unexpectedObjectException:(NSString*)reason type:(NSString*)type expectedType:(NSString*)expectedType file:(NSString*)file line:(size_t)line; ++(NSError*) memoryLimitException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) stringConversionException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) encapsulationException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) marshalException:(NSString*)reason file:(NSString*)file line:(size_t)line; ++(NSError*) protocolException:(NSString*)reason file:(NSString*)file line:(size_t)line; + +// For generic std::exception ++(NSError*) runtimeError:(NSString*)message; +@end + +ICEIMPL_API @interface ICERuntimeException : NSObject +@property NSString* file; +@property int line; +@end + +// +// Request Failed exceptions +// +ICEIMPL_API @interface ICERequestFailedException : ICERuntimeException +@property (nonatomic) NSString* name; +@property (nonatomic) NSString* category; +@property (nonatomic) NSString* facet; +@property (nonatomic) NSString* operation; +@end + +ICEIMPL_API @interface ICEObjectNotExistException : ICERequestFailedException +@end + +ICEIMPL_API @interface ICEFacetNotExistException : ICERequestFailedException +@end + +ICEIMPL_API @interface ICEOperationNotExistException : ICERequestFailedException +@end + +// +// Unknown exceptions +// +ICEIMPL_API @interface ICEUnknownException : ICERuntimeException +@property (nonatomic) NSString* unknown; +@end + +ICEIMPL_API @interface ICEUnknownLocalException : ICEUnknownException +@end + +ICEIMPL_API @interface ICEUnknownUserException : ICEUnknownException +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/IceImpl.h b/Sources/IceImpl/include/IceImpl.h new file mode 100644 index 0000000..c4b3712 --- /dev/null +++ b/Sources/IceImpl/include/IceImpl.h @@ -0,0 +1,19 @@ +#import "AdminFacetFactory.h" +#import "BlobjectFacade.h" +#import "Communicator.h" +#import "Config.h" +#import "Connection.h" +#import "Endpoint.h" +#import "Exception.h" +#import "IceUtil.h" +#import "ImplicitContext.h" +#import "LocalObject.h" +#import "Logger.h" +#import "ObjectAdapter.h" +#import "ObjectPrx.h" +#import "OutputStream.h" +#import "Process.h" +#import "Properties.h" +#import "PropertiesAdmin.h" +#import "TraceUtil.h" +#import "UnsupportedAdminFacet.h" diff --git a/Sources/IceImpl/include/IceUtil.h b/Sources/IceImpl/include/IceUtil.h new file mode 100644 index 0000000..a528fd4 --- /dev/null +++ b/Sources/IceImpl/include/IceUtil.h @@ -0,0 +1,67 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Communicator.h" +#import "Connection.h" +#import "Endpoint.h" +#import "Exception.h" +#import "Logger.h" +#import "Properties.h" +#import "AdminFacetFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +// +// Utility methods +// +ICEIMPL_API @interface ICEUtil: NSObject +@property (class, nonatomic, readonly) Class exceptionFactory; +@property (class, nonatomic, readonly) Class connectionInfoFactory; +@property (class, nonatomic, readonly) Class endpointInfoFactory; +@property (class, nonatomic, readonly) Class adminFacetFactory; + +//This method should only be called once to guarenteed thread safety ++(BOOL) registerFactories:(Class)exception + connectionInfo:(Class)connectionInfo + endpointInfo:(Class)endpointInfo + adminFacet:(Class)adminFacet +NS_SWIFT_NAME(registerFactories(exception:connectionInfo:endpointInfo:adminFacet:)); + ++(nullable ICECommunicator*) initialize:(NSArray*)swiftArgs + properties:(ICEProperties*)properties + withConfigFile:(BOOL)withConfiFile + logger:(id _Nullable)logger + remArgs:(NSArray* _Null_unspecified * _Null_unspecified)remArgs + error:(NSError* _Nullable * _Nullable)error; + ++(ICEProperties*) createProperties; + ++(nullable ICEProperties*) createProperties:(NSArray* _Nullable)swiftArgs + defaults:(ICEProperties* _Nullable)defaults + remArgs:(NSArray* _Null_unspecified * _Null_unspecified)remArgs + error:(NSError* _Nullable * _Nullable)error; ++(BOOL) stringToIdentity:(NSString*)str + name:(NSString* __strong _Nonnull * _Nonnull)name + category:(NSString* __strong _Nonnull * _Nonnull)category + error:(NSError* _Nullable * _Nullable)error NS_SWIFT_NAME(stringToIdentity(str:name:category:)); + ++(NSString*) identityToString:(NSString*)name + category:(NSString*)category + mode:(uint8_t)mode + NS_SWIFT_NAME(identityToString(name:category:mode:)); + ++(NSString*) encodingVersionToString:(UInt8)major + minor:(UInt8)minor NS_SWIFT_NAME(encodingVersionToString(major:minor:)); + ++(nullable NSString*) escapeString:(NSString*)string + special:(NSString*)special + communicator:(ICECommunicator*)communicator + error:(NSError* _Nullable * _Nullable)error + NS_SWIFT_NAME(escapeString(string:special:communicator:)); + ++(NSString*) errorToString:(int32_t)error NS_SWIFT_NAME(errorToString(_:)); ++(NSString*) errorToStringDNS:(int32_t)error NS_SWIFT_NAME(errorToStringDNS(_:)); +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/ImplicitContext.h b/Sources/IceImpl/include/ImplicitContext.h new file mode 100644 index 0000000..90732cc --- /dev/null +++ b/Sources/IceImpl/include/ImplicitContext.h @@ -0,0 +1,26 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEImplicitContext: ICELocalObject +-(NSDictionary*) getContext; +-(void) setContext:(NSDictionary*)context; +-(bool) containsKey:(NSString*)string; +-(NSString*) get:(NSString*)key; +-(NSString*) put:(NSString*)key value:(NSString*)value; +-(NSString*) remove:(NSString*)key; +@end + +#ifdef __cplusplus + +@interface ICEImplicitContext() +@property (nonatomic, readonly) std::shared_ptr implicitContext; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/LocalObject.h b/Sources/IceImpl/include/LocalObject.h new file mode 100644 index 0000000..aebf4bf --- /dev/null +++ b/Sources/IceImpl/include/LocalObject.h @@ -0,0 +1,27 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Config.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICELocalObject : NSObject +// +// We hold a weak referece to the (possile) Swift object which has a handle to +// this ICELocalObject. That way we can recover the Swift object later. +// +@property (weak, atomic, nullable) id swiftRef; +-(instancetype) init ICE_SWIFT_UNAVAILABLE(""); +@end + +#ifdef __cplusplus + +@interface ICELocalObject () +@property (nonatomic, readonly) std::shared_ptr cppObject; ++(nullable instancetype) getHandle:(std::shared_ptr)cppObject NS_RETURNS_RETAINED; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Logger.h b/Sources/IceImpl/include/Logger.h new file mode 100644 index 0000000..aa75cac --- /dev/null +++ b/Sources/IceImpl/include/Logger.h @@ -0,0 +1,35 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @protocol ICELoggerProtocol +-(void) print:(NSString*)message NS_SWIFT_NAME(print(_:)); +-(void) trace:(NSString*)category message:(NSString*)message NS_SWIFT_NAME(trace(category:message:)); +-(void) warning:(NSString*)message NS_SWIFT_NAME(warning(_:)); +-(void) error:(NSString*)message NS_SWIFT_NAME(error(_:)); +-(NSString*) getPrefix; +-(id) cloneWithPrefix:(NSString*)prefix NS_SWIFT_NAME(cloneWithPrefix(_:)); +@end + +ICEIMPL_API @interface ICELogger: ICELocalObject +-(void) print:(NSString*)message; +-(void) trace:(NSString*)category message:(NSString*)message; +-(void) warning:(NSString*)message; +-(void) error:(NSString*)message; +-(NSString*) getPrefix; +-(id) cloneWithPrefix:(NSString*)prefix; +@end + +#ifdef __cplusplus + +@interface ICELogger() +@property (nonatomic, readonly) std::shared_ptr logger; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/ObjectAdapter.h b/Sources/IceImpl/include/ObjectAdapter.h new file mode 100644 index 0000000..a8c96ec --- /dev/null +++ b/Sources/IceImpl/include/ObjectAdapter.h @@ -0,0 +1,48 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +@class ICECommunicator; +@class ICEObjectPrx; +@class ICEEndpoint; +@class ICEConnection; +@class ICERuntimeException; +@protocol ICEBlobjectFacade; + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEObjectAdapter: ICELocalObject +-(NSString*) getName; +-(ICECommunicator*) getCommunicator; +-(BOOL) activate:(NSError* _Nullable * _Nullable)error; +-(void) hold; +-(void) waitForHold; +-(void) deactivate; +-(void) waitForDeactivate; +-(BOOL) isDeactivated; +-(void) destroy; +-(nullable ICEObjectPrx*) createProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error NS_SWIFT_NAME(createProxy(name:category:)); +-(nullable ICEObjectPrx*) createDirectProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error NS_SWIFT_NAME(createDirectProxy(name:category:)); +-(nullable ICEObjectPrx*) createIndirectProxy:(NSString*)name category:(NSString*)category error:(NSError* _Nullable * _Nullable)error NS_SWIFT_NAME(createIndirectProxy(name:category:)); +-(void) setLocator:(ICEObjectPrx* _Nullable)locator; +-(nullable ICEObjectPrx*) getLocator; +-(NSArray*) getEndpoints; +-(BOOL) refreshPublishedEndpoints:(NSError* _Nullable * _Nullable)error; +-(NSArray*) getPublishedEndpoints; +-(BOOL) setPublishedEndpoints:(NSArray*)newEndpoints error:(NSError* _Nullable * _Nullable)error; +-(nullable dispatch_queue_t) getDispatchQueue:(NSError* _Nullable * _Nullable)error; + +-(void) registerDefaultServant:(id)facade NS_SWIFT_NAME(registerDefaultServant(_:)); +@end + +#ifdef __cplusplus + +@interface ICEObjectAdapter() +@property (nonatomic, readonly) std::shared_ptr objectAdapter; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/ObjectPrx.h b/Sources/IceImpl/include/ObjectPrx.h new file mode 100644 index 0000000..88003ce --- /dev/null +++ b/Sources/IceImpl/include/ObjectPrx.h @@ -0,0 +1,138 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Config.h" + +@class ICEObjectPrx; +@class ICEImplicitContext; +@class ICEProperties; +@class ICEEndpoint; +@class ICEConnection; +@class ICEInputStream; +@class ICECommunicator; +@protocol ICELoggerProtocol; +@protocol ICEOutputStreamHelper; + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEObjectPrx : NSObject +-(nonnull ICEObjectPrx*) initWithObjectPrx:(ICEObjectPrx*)prx; +-(nonnull NSString*) ice_toString; +-(nonnull ICECommunicator*) ice_getCommunicator; +-(void) ice_getIdentity:(NSString* __strong _Nonnull * _Nonnull)name + category:(NSString* __strong _Nonnull * _Nonnull)category; +-(nullable instancetype) ice_identity:(NSString*)name + category:(NSString*)category + error:(NSError* _Nullable * _Nullable)error; +-(nonnull NSDictionary*) ice_getContext; +-(nonnull instancetype) ice_context:(NSDictionary*)context; +-(nonnull NSString*) ice_getFacet; +-(nonnull instancetype) ice_facet:(NSString*)facet; +-(nonnull NSString*) ice_getAdapterId; +-(nullable instancetype) ice_adapterId:(NSString*)id error:(NSError* _Nullable * _Nullable)error; +-(nonnull NSArray*) ice_getEndpoints; +-(nullable instancetype) ice_endpoints:(NSArray*)endpoints error:(NSError* _Nullable * _Nullable)error; +-(int32_t) ice_getLocatorCacheTimeout; +-(nullable instancetype) ice_locatorCacheTimeout:(int32_t)timeout error:(NSError* _Nullable * _Nullable)error; +-(int32_t) ice_getInvocationTimeout; +-(nullable instancetype) ice_invocationTimeout:(int32_t)timeout error:(NSError* _Nullable * _Nullable)error; +-(nonnull NSString*) ice_getConnectionId; +-(nullable instancetype) ice_connectionId:(NSString*)connectionId error:(NSError* _Nullable * _Nullable)error; +-(bool) ice_isConnectionCached; +-(nullable instancetype) ice_connectionCached:(bool)cached error:(NSError* _Nullable * _Nullable)error; +-(uint8_t) ice_getEndpointSelection; +-(nullable instancetype) ice_endpointSelection:(uint8_t)type error:(NSError* _Nullable * _Nullable)error; +-(nonnull instancetype) ice_encodingVersion:(uint8_t)major minor:(uint8_t)minor; +-(void) ice_getEncodingVersion:(uint8_t*)major minor:(uint8_t*)minor; +-(nullable ICEObjectPrx*) ice_getRouter; +-(nullable instancetype) ice_router:(ICEObjectPrx* _Nullable)router error:(NSError* _Nullable * _Nullable)error; +-(nullable ICEObjectPrx*) ice_getLocator; +-(nullable instancetype) ice_locator:(ICEObjectPrx* _Nullable)locator error:(NSError* _Nullable * _Nullable)error; +-(bool) ice_isSecure; +-(nonnull instancetype) ice_secure:(bool)b; +-(bool) ice_isPreferSecure; +-(nullable instancetype) ice_preferSecure:(bool)b error:(NSError* _Nullable * _Nullable)error; +-(bool) ice_isTwoway; +-(nonnull instancetype) ice_twoway; +-(bool) ice_isOneway; +-(nonnull instancetype) ice_oneway; +-(bool) ice_isBatchOneway; +-(nonnull instancetype) ice_batchOneway; +-(bool) ice_isDatagram; +-(nonnull instancetype) ice_datagram; +-(bool) ice_isBatchDatagram; +-(nonnull instancetype) ice_batchDatagram; +// id represents Any in Swift which we use as an Optional int32_t +-(nullable id) ice_getCompress; +-(nonnull instancetype) ice_compress:(bool)compress; +// id represents Any in Swift which we use as an Optional int32_t +-(nullable id) ice_getTimeout; +-(nullable instancetype) ice_timeout:(int32_t)timeout error:(NSError* _Nullable * _Nullable)error; +-(nullable instancetype) ice_fixed:(ICEConnection*)connection error:(NSError* _Nullable * _Nullable)error; +-(bool) ice_isFixed; +-(nullable id) ice_getConnection:(NSError* _Nullable * _Nullable)error; //Either NSNull or ICEConnection +-(void) ice_getConnectionAsync:(void (^)(ICEConnection* _Nullable)) response + exception:(void (^)(NSError*))exception; +-(nullable ICEConnection*) ice_getCachedConnection; +-(BOOL) ice_flushBatchRequests:(NSError* _Nullable * _Nullable)error; +-(void) ice_flushBatchRequestsAsync:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent + NS_SWIFT_NAME(ice_flushBatchRequestsAsync(exception:sent:)); +-(bool) ice_isCollocationOptimized; +-(nullable instancetype) ice_collocationOptimized:(bool)collocated + error:(NSError* _Nullable * _Nullable)error; + +// Either ICEObjectPrx or NSNull ++(nullable id) ice_read:(NSData*)data + communicator:(ICECommunicator*)communicator + encodingMajor:(uint8_t)major + encodingMinor:(uint8_t)minor + bytesRead:(NSInteger*)bytesRead + error:(NSError* _Nullable * _Nullable)error; + +-(void) ice_write:(id)os + encodingMajor:(uint8_t)encodingMajor + encodingMinor:(uint8_t)encodingMinor; + +-(BOOL) invoke:(NSString* _Nonnull)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary* _Nullable)context + response:(void (^)(bool, void*, long))response + error:(NSError* _Nullable * _Nullable)error; + +// Sync invocation on oneway proxy +-(BOOL) onewayInvoke:(NSString* _Nonnull)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary* _Nullable)context + error:(NSError* _Nullable * _Nullable)error; + +-(void) invokeAsync:(NSString* _Nonnull)op + mode:(uint8_t)mode + inParams:(NSData*)inParams + context:(NSDictionary* _Nullable)context + response:(void (^)(bool, void*, long))response + exception:(void (^)(NSError*))exception + sent:(void (^_Nullable)(bool))sent; + +-(bool) isEqual:(ICEObjectPrx* _Nullable)prx; + +-(bool) proxyIdentityLess:(ICEObjectPrx* _Nullable)prx; +-(bool) proxyIdentityEqual:(ICEObjectPrx* _Nullable)prx; + +-(bool) proxyIdentityAndFacetLess:(ICEObjectPrx* _Nullable)prx; +-(bool) proxyIdentityAndFacetEqual:(ICEObjectPrx* _Nullable)prx; +@end + +#ifdef __cplusplus + +@interface ICEObjectPrx() +@property (nonatomic, readonly) std::shared_ptr prx; +-(nullable instancetype) initWithCppObjectPrx:(std::shared_ptr)prx; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/OutputStream.h b/Sources/IceImpl/include/OutputStream.h new file mode 100644 index 0000000..214ad85 --- /dev/null +++ b/Sources/IceImpl/include/OutputStream.h @@ -0,0 +1,14 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @protocol ICEOutputStreamHelper +-(void) copy:(const void*)bytes + count:(long)count; +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Process.h b/Sources/IceImpl/include/Process.h new file mode 100644 index 0000000..3be831c --- /dev/null +++ b/Sources/IceImpl/include/Process.h @@ -0,0 +1,22 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEProcess : ICELocalObject +-(void) shutdown; +-(void) writeMessage:(NSString*)message fd:(int32_t)fd; +@end + +#ifdef __cplusplus + +@interface ICEProcess() +@property (nonatomic, readonly) std::shared_ptr process; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/Properties.h b/Sources/IceImpl/include/Properties.h new file mode 100644 index 0000000..2ba28d8 --- /dev/null +++ b/Sources/IceImpl/include/Properties.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEProperties : ICELocalObject +-(nonnull NSString*) getProperty:(NSString*)key; +-(nonnull NSString*) getPropertyWithDefault:(NSString*)key value:(NSString*)value; +-(int32_t) getPropertyAsInt:(NSString*)key; +-(int32_t) getPropertyAsIntWithDefault:(NSString*)key value:(int32_t)value NS_SWIFT_NAME(getPropertyAsIntWithDefault(key:value:)); +-(nonnull NSArray*) getPropertyAsList:(NSString* _Nonnull)key; +-(nonnull NSArray*) getPropertyAsListWithDefault:(NSString* _Nonnull)key value:(NSArray* _Nonnull)value NS_SWIFT_NAME(getPropertyAsListWithDefault(key:value:)); +-(nonnull NSDictionary*) getPropertiesForPrefix:(NSString* _Nonnull)prefix NS_SWIFT_NAME(getPropertiesForPrefix(_:)); +-(BOOL) setProperty:(NSString*)key value:(NSString*)value error:(NSError**)error; +-(nonnull NSArray*) getCommandLineOptions; +-(nullable NSArray*) parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options error:(NSError* _Nullable * _Nullable)error; +-(nullable NSArray*) parseIceCommandLineOptions:(NSArray*)options error:(NSError**)error; +-(BOOL) load:(NSString*)file error:(NSError* _Nullable * _Nullable)error; +-(nonnull ICEProperties*) clone; +@end + +#ifdef __cplusplus + +@interface ICEProperties() +@property (nonatomic, readonly) std::shared_ptr properties; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/PropertiesAdmin.h b/Sources/IceImpl/include/PropertiesAdmin.h new file mode 100644 index 0000000..3da7817 --- /dev/null +++ b/Sources/IceImpl/include/PropertiesAdmin.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEPropertiesAdmin: ICELocalObject +-(nullable NSString*) getProperty:(NSString*)key error:(NSError**)error; +-(nullable NSDictionary*) getPropertiesForPrefix:(NSString*)prefix error:(NSError**)error; +-(BOOL) setProperties:(NSDictionary*)newProperties error:(NSError**)error; +-(void (^)(void)) addUpdateCallback:(void (^)(NSDictionary*))cb; +@end + +#ifdef __cplusplus + +@interface ICEPropertiesAdmin() +@property (nonatomic, readonly) std::shared_ptr propertiesAdmin; +@end + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/TraceUtil.h b/Sources/IceImpl/include/TraceUtil.h new file mode 100644 index 0000000..b32a058 --- /dev/null +++ b/Sources/IceImpl/include/TraceUtil.h @@ -0,0 +1,18 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "Logger.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICETraceUtil : NSObject + ++(void) traceSlicing:(NSString*)kind + typeId:(NSString*)typeId + slicingCat:(NSString*)slicingCat + logger:(id)logger NS_SWIFT_NAME(traceSlicing(kind:typeId:slicingCat:logger:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceImpl/include/UnsupportedAdminFacet.h b/Sources/IceImpl/include/UnsupportedAdminFacet.h new file mode 100644 index 0000000..927febd --- /dev/null +++ b/Sources/IceImpl/include/UnsupportedAdminFacet.h @@ -0,0 +1,12 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#import "LocalObject.h" + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @interface ICEUnsupportedAdminFacet: ICELocalObject +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/IceLocatorDiscoveryCpp/IceLocatorDiscovery.cpp b/Sources/IceLocatorDiscoveryCpp/IceLocatorDiscovery.cpp new file mode 100644 index 0000000..d0e4732 --- /dev/null +++ b/Sources/IceLocatorDiscoveryCpp/IceLocatorDiscovery.cpp @@ -0,0 +1,730 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `IceLocatorDiscovery.ice' +// +// Warning: do not edit this file. +// +// +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +const ::std::string iceC_IceLocatorDiscovery_LookupReply_ids[2] = +{ + "::Ice::Object", + "::IceLocatorDiscovery::LookupReply" +}; +const ::std::string iceC_IceLocatorDiscovery_LookupReply_ops[] = +{ + "foundLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_IceLocatorDiscovery_LookupReply_foundLocator_name = "foundLocator"; + +const ::std::string iceC_IceLocatorDiscovery_Lookup_ids[2] = +{ + "::Ice::Object", + "::IceLocatorDiscovery::Lookup" +}; +const ::std::string iceC_IceLocatorDiscovery_Lookup_ops[] = +{ + "findLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; +const ::std::string iceC_IceLocatorDiscovery_Lookup_findLocator_name = "findLocator"; + +} + +bool +IceLocatorDiscovery::LookupReply::ice_isA(::std::string s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceLocatorDiscovery_LookupReply_ids, iceC_IceLocatorDiscovery_LookupReply_ids + 2, s); +} + +::std::vector<::std::string> +IceLocatorDiscovery::LookupReply::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector<::std::string>(&iceC_IceLocatorDiscovery_LookupReply_ids[0], &iceC_IceLocatorDiscovery_LookupReply_ids[2]); +} + +::std::string +IceLocatorDiscovery::LookupReply::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceLocatorDiscovery::LookupReply::ice_staticId() +{ + static const ::std::string typeId = "::IceLocatorDiscovery::LookupReply"; + return typeId; +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::LookupReply::_iceD_foundLocator(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Normal, current.mode); + auto istr = inS.startReadParams(); + ::std::shared_ptr<::Ice::LocatorPrx> iceP_prx; + istr->readAll(iceP_prx); + inS.endReadParams(); + this->foundLocator(::std::move(iceP_prx), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceLocatorDiscovery::LookupReply::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceLocatorDiscovery_LookupReply_ops, iceC_IceLocatorDiscovery_LookupReply_ops + 5, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceLocatorDiscovery_LookupReply_ops) + { + case 0: + { + return _iceD_foundLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +bool +IceLocatorDiscovery::Lookup::ice_isA(::std::string s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceLocatorDiscovery_Lookup_ids, iceC_IceLocatorDiscovery_Lookup_ids + 2, s); +} + +::std::vector<::std::string> +IceLocatorDiscovery::Lookup::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector<::std::string>(&iceC_IceLocatorDiscovery_Lookup_ids[0], &iceC_IceLocatorDiscovery_Lookup_ids[2]); +} + +::std::string +IceLocatorDiscovery::Lookup::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceLocatorDiscovery::Lookup::ice_staticId() +{ + static const ::std::string typeId = "::IceLocatorDiscovery::Lookup"; + return typeId; +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::Lookup::_iceD_findLocator(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::OperationMode::Idempotent, current.mode); + auto istr = inS.startReadParams(); + ::std::string iceP_instanceName; + ::std::shared_ptr iceP_reply; + istr->readAll(iceP_instanceName, iceP_reply); + inS.endReadParams(); + this->findLocator(::std::move(iceP_instanceName), ::std::move(iceP_reply), current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +/// \cond INTERNAL +bool +IceLocatorDiscovery::Lookup::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceLocatorDiscovery_Lookup_ops, iceC_IceLocatorDiscovery_Lookup_ops + 5, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceLocatorDiscovery_Lookup_ops) + { + case 0: + { + return _iceD_findLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond INTERNAL +void +IceLocatorDiscovery::LookupReplyPrx::_iceI_foundLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::shared_ptr<::Ice::LocatorPrx>& iceP_prx, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceLocatorDiscovery_LookupReply_foundLocator_name, ::Ice::OperationMode::Normal, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_prx); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +IceLocatorDiscovery::LookupReplyPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +IceLocatorDiscovery::LookupReplyPrx::ice_staticId() +{ + return LookupReply::ice_staticId(); +} + +/// \cond INTERNAL +void +IceLocatorDiscovery::LookupPrx::_iceI_findLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>& outAsync, const ::std::string& iceP_instanceName, const ::std::shared_ptr& iceP_reply, const ::Ice::Context& context) +{ + outAsync->invoke(iceC_IceLocatorDiscovery_Lookup_findLocator_name, ::Ice::OperationMode::Idempotent, ::Ice::FormatType::DefaultFormat, context, + [&](::Ice::OutputStream* ostr) + { + ostr->writeAll(iceP_instanceName, iceP_reply); + }, + nullptr); +} +/// \endcond + +/// \cond INTERNAL +::std::shared_ptr<::Ice::ObjectPrx> +IceLocatorDiscovery::LookupPrx::_newInstance() const +{ + return ::IceInternal::createProxy(); +} +/// \endcond + +const ::std::string& +IceLocatorDiscovery::LookupPrx::ice_staticId() +{ + return Lookup::ice_staticId(); +} + +#else // C++98 mapping + +namespace +{ + +const ::std::string iceC_IceLocatorDiscovery_LookupReply_foundLocator_name = "foundLocator"; + +const ::std::string iceC_IceLocatorDiscovery_Lookup_findLocator_name = "findLocator"; + +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* ::IceProxy::IceLocatorDiscovery::upCast(LookupReply* p) { return p; } + +void +::IceProxy::IceLocatorDiscovery::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< LookupReply>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new LookupReply; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::IceLocatorDiscovery::LookupReply::_iceI_begin_foundLocator(const ::Ice::LocatorPrx& iceP_prx, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceLocatorDiscovery_LookupReply_foundLocator_name, del, cookie, sync); + try + { + result->prepare(iceC_IceLocatorDiscovery_LookupReply_foundLocator_name, ::Ice::Normal, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_prx); + result->endWriteParams(); + result->invoke(iceC_IceLocatorDiscovery_LookupReply_foundLocator_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceLocatorDiscovery::LookupReply::end_foundLocator(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceLocatorDiscovery_LookupReply_foundLocator_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceLocatorDiscovery::LookupReply::_newInstance() const +{ + return new LookupReply; +} +/// \endcond + +const ::std::string& +IceProxy::IceLocatorDiscovery::LookupReply::ice_staticId() +{ + return ::IceLocatorDiscovery::LookupReply::ice_staticId(); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* ::IceProxy::IceLocatorDiscovery::upCast(Lookup* p) { return p; } + +void +::IceProxy::IceLocatorDiscovery::_readProxy(::Ice::InputStream* istr, ::IceInternal::ProxyHandle< Lookup>& v) +{ + ::Ice::ObjectPrx proxy; + istr->read(proxy); + if(!proxy) + { + v = 0; + } + else + { + v = new Lookup; + v->_copyFrom(proxy); + } +} +/// \endcond + +::Ice::AsyncResultPtr +IceProxy::IceLocatorDiscovery::Lookup::_iceI_begin_findLocator(const ::std::string& iceP_instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& iceP_reply, const ::Ice::Context& context, const ::IceInternal::CallbackBasePtr& del, const ::Ice::LocalObjectPtr& cookie, bool sync) +{ + ::IceInternal::OutgoingAsyncPtr result = new ::IceInternal::CallbackOutgoing(this, iceC_IceLocatorDiscovery_Lookup_findLocator_name, del, cookie, sync); + try + { + result->prepare(iceC_IceLocatorDiscovery_Lookup_findLocator_name, ::Ice::Idempotent, context); + ::Ice::OutputStream* ostr = result->startWriteParams(::Ice::DefaultFormat); + ostr->write(iceP_instanceName); + ostr->write(iceP_reply); + result->endWriteParams(); + result->invoke(iceC_IceLocatorDiscovery_Lookup_findLocator_name); + } + catch(const ::Ice::Exception& ex) + { + result->abort(ex); + } + return result; +} + +void +IceProxy::IceLocatorDiscovery::Lookup::end_findLocator(const ::Ice::AsyncResultPtr& result) +{ + _end(result, iceC_IceLocatorDiscovery_Lookup_findLocator_name); +} + +/// \cond INTERNAL +::IceProxy::Ice::Object* +IceProxy::IceLocatorDiscovery::Lookup::_newInstance() const +{ + return new Lookup; +} +/// \endcond + +const ::std::string& +IceProxy::IceLocatorDiscovery::Lookup::ice_staticId() +{ + return ::IceLocatorDiscovery::Lookup::ice_staticId(); +} + +IceLocatorDiscovery::LookupReply::~LookupReply() +{ +} + +/// \cond INTERNAL +::Ice::Object* IceLocatorDiscovery::upCast(LookupReply* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_IceLocatorDiscovery_LookupReply_ids[2] = +{ + "::Ice::Object", + "::IceLocatorDiscovery::LookupReply" +}; + +} + +bool +IceLocatorDiscovery::LookupReply::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceLocatorDiscovery_LookupReply_ids, iceC_IceLocatorDiscovery_LookupReply_ids + 2, s); +} + +::std::vector< ::std::string> +IceLocatorDiscovery::LookupReply::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceLocatorDiscovery_LookupReply_ids[0], &iceC_IceLocatorDiscovery_LookupReply_ids[2]); +} + +const ::std::string& +IceLocatorDiscovery::LookupReply::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceLocatorDiscovery::LookupReply::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceLocatorDiscovery::LookupReply"; + return typeId; +#else + return iceC_IceLocatorDiscovery_LookupReply_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::LookupReply::_iceD_foundLocator(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Normal, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::Ice::LocatorPrx iceP_prx; + istr->read(iceP_prx); + inS.endReadParams(); + this->foundLocator(iceP_prx, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_IceLocatorDiscovery_LookupReply_all[] = +{ + "foundLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::LookupReply::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceLocatorDiscovery_LookupReply_all, iceC_IceLocatorDiscovery_LookupReply_all + 5, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceLocatorDiscovery_LookupReply_all) + { + case 0: + { + return _iceD_foundLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +IceLocatorDiscovery::LookupReply::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< LookupReply, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceLocatorDiscovery::LookupReply::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< LookupReply, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +IceLocatorDiscovery::_icePatchObjectPtr(LookupReplyPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = LookupReplyPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(LookupReply::ice_staticId(), v); + } +} +/// \endcond + +IceLocatorDiscovery::Lookup::~Lookup() +{ +} + +/// \cond INTERNAL +::Ice::Object* IceLocatorDiscovery::upCast(Lookup* p) { return p; } + +/// \endcond + +namespace +{ +const ::std::string iceC_IceLocatorDiscovery_Lookup_ids[2] = +{ + "::Ice::Object", + "::IceLocatorDiscovery::Lookup" +}; + +} + +bool +IceLocatorDiscovery::Lookup::ice_isA(const ::std::string& s, const ::Ice::Current&) const +{ + return ::std::binary_search(iceC_IceLocatorDiscovery_Lookup_ids, iceC_IceLocatorDiscovery_Lookup_ids + 2, s); +} + +::std::vector< ::std::string> +IceLocatorDiscovery::Lookup::ice_ids(const ::Ice::Current&) const +{ + return ::std::vector< ::std::string>(&iceC_IceLocatorDiscovery_Lookup_ids[0], &iceC_IceLocatorDiscovery_Lookup_ids[2]); +} + +const ::std::string& +IceLocatorDiscovery::Lookup::ice_id(const ::Ice::Current&) const +{ + return ice_staticId(); +} + +const ::std::string& +IceLocatorDiscovery::Lookup::ice_staticId() +{ +#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC + static const ::std::string typeId = "::IceLocatorDiscovery::Lookup"; + return typeId; +#else + return iceC_IceLocatorDiscovery_Lookup_ids[1]; +#endif +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::Lookup::_iceD_findLocator(::IceInternal::Incoming& inS, const ::Ice::Current& current) +{ + _iceCheckMode(::Ice::Idempotent, current.mode); + ::Ice::InputStream* istr = inS.startReadParams(); + ::std::string iceP_instanceName; + LookupReplyPrx iceP_reply; + istr->read(iceP_instanceName); + istr->read(iceP_reply); + inS.endReadParams(); + this->findLocator(iceP_instanceName, iceP_reply, current); + inS.writeEmptyParams(); + return true; +} +/// \endcond + +namespace +{ +const ::std::string iceC_IceLocatorDiscovery_Lookup_all[] = +{ + "findLocator", + "ice_id", + "ice_ids", + "ice_isA", + "ice_ping" +}; + +} + +/// \cond INTERNAL +bool +IceLocatorDiscovery::Lookup::_iceDispatch(::IceInternal::Incoming& in, const ::Ice::Current& current) +{ + ::std::pair r = ::std::equal_range(iceC_IceLocatorDiscovery_Lookup_all, iceC_IceLocatorDiscovery_Lookup_all + 5, current.operation); + if(r.first == r.second) + { + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + + switch(r.first - iceC_IceLocatorDiscovery_Lookup_all) + { + case 0: + { + return _iceD_findLocator(in, current); + } + case 1: + { + return _iceD_ice_id(in, current); + } + case 2: + { + return _iceD_ice_ids(in, current); + } + case 3: + { + return _iceD_ice_isA(in, current); + } + case 4: + { + return _iceD_ice_ping(in, current); + } + default: + { + assert(false); + throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } + } +} +/// \endcond + +/// \cond STREAM +void +IceLocatorDiscovery::Lookup::_iceWriteImpl(::Ice::OutputStream* ostr) const +{ + ostr->startSlice(ice_staticId(), -1, true); + ::Ice::StreamWriter< Lookup, ::Ice::OutputStream>::write(ostr, *this); + ostr->endSlice(); +} + +void +IceLocatorDiscovery::Lookup::_iceReadImpl(::Ice::InputStream* istr) +{ + istr->startSlice(); + ::Ice::StreamReader< Lookup, ::Ice::InputStream>::read(istr, *this); + istr->endSlice(); +} +/// \endcond + +/// \cond INTERNAL +void +IceLocatorDiscovery::_icePatchObjectPtr(LookupPtr& handle, const ::Ice::ObjectPtr& v) +{ + handle = LookupPtr::dynamicCast(v); + if(v && !handle) + { + IceInternal::Ex::throwUOE(Lookup::ice_staticId(), v); + } +} +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceLocatorDiscoveryCpp/PluginI.cpp b/Sources/IceLocatorDiscoveryCpp/PluginI.cpp new file mode 100644 index 0000000..2b89630 --- /dev/null +++ b/Sources/IceLocatorDiscoveryCpp/PluginI.cpp @@ -0,0 +1,1048 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include // For getInterfacesForMulticast +#include + +#include +#include + +using namespace std; +using namespace IceLocatorDiscovery; + +namespace +{ + +class LocatorI; // Forward declaration + +#ifdef ICE_CPP11_MAPPING +typedef std::pair&)>, + function> AMDCallback; +#else +typedef Ice::AMD_Object_ice_invokePtr AMDCallback; +#endif + +class Request : +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public virtual IceUtil::Shared +#endif +{ +public: + + Request(LocatorI* locator, + const string& operation, + Ice::OperationMode mode, + const pair& inParams, + const Ice::Context& ctx, + const AMDCallback& amdCB) : + _locator(locator), + _operation(operation), + _mode(mode), + _context(ctx), + _inParams(inParams.first, inParams.second), + _amdCB(amdCB) + { + } + + void invoke(const Ice::LocatorPrxPtr&); + void response(bool, const pair&); + void exception(const Ice::Exception&); + +protected: + + LocatorI* _locator; + const string _operation; + const Ice::OperationMode _mode; + const Ice::Context _context; + const Ice::ByteSeq _inParams; + AMDCallback _amdCB; +#ifdef ICE_CPP11_MAPPING + exception_ptr _exception; +#else + IceInternal::UniquePtr _exception; +#endif + + Ice::LocatorPrxPtr _locatorPrx; +}; +ICE_DEFINE_PTR(RequestPtr, Request); + +class LocatorI : public Ice::BlobjectArrayAsync, + public IceUtil::TimerTask, + private IceUtil::Monitor +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + LocatorI(const string&, const LookupPrxPtr&, const Ice::PropertiesPtr&, const string&, const Ice::LocatorPrxPtr&); + void setLookupReply(const LookupReplyPrxPtr&); + +#ifdef ICE_CPP11_MAPPING + virtual void ice_invokeAsync(pair, + function&)>, + function, + const Ice::Current&); +#else + virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, const pair&, + const Ice::Current&); +#endif + + void foundLocator(const Ice::LocatorPrxPtr&); + void invoke(const Ice::LocatorPrxPtr&, const RequestPtr&); + + vector getLocators(const string&, const IceUtil::Time&); + + void exception(const Ice::LocalException&); + +private: + + virtual void runTimerTask(); + + LookupPrxPtr _lookup; + vector > _lookups; + IceUtil::Time _timeout; + int _retryCount; + IceUtil::Time _retryDelay; + const IceUtil::TimerPtr _timer; + const int _traceLevel; + + string _instanceName; + bool _warned; + Ice::LocatorPrxPtr _locator; + map _locators; + Ice::LocatorPrxPtr _voidLocator; + + IceUtil::Time _nextRetry; + bool _pending; + int _pendingRetryCount; + size_t _failureCount; + bool _warnOnce; + vector _pendingRequests; +}; +ICE_DEFINE_PTR(LocatorIPtr, LocatorI); + +class LookupReplyI : public LookupReply +{ +public: + + LookupReplyI(const LocatorIPtr& locator) : _locator(locator) + { + } + + virtual void foundLocator(ICE_IN(Ice::LocatorPrxPtr), const Ice::Current&); + +private: + + const LocatorIPtr _locator; +}; + +// +// The void locator implementation below is used when no locator is found. +// +class VoidLocatorI : public Ice::Locator +{ +public: + +#ifdef ICE_CPP11_MAPPING + virtual void + findObjectByIdAsync(::Ice::Identity, + function&)> response, + function, + const Ice::Current&) const + { + response(nullptr); + } + + virtual void + findAdapterByIdAsync(string, + function&)> response, + function, + const Ice::Current&) const + { + response(nullptr); + } +#else + virtual void + findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& amdCB, + const Ice::Identity&, + const Ice::Current&) const + { + amdCB->ice_response(0); + } + + virtual void + findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& amdCB, + const string&, + const Ice::Current&) const + { + amdCB->ice_response(0); + } +#endif + + virtual Ice::LocatorRegistryPrxPtr + getRegistry(const Ice::Current&) const + { + return ICE_NULLPTR; + } +}; + +class PluginI : public Plugin +{ +public: + + PluginI(const std::string&, const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual void destroy(); + virtual vector getLocators(const string&, const IceUtil::Time&) const; + +private: + + const string _name; + const Ice::CommunicatorPtr _communicator; + Ice::ObjectAdapterPtr _locatorAdapter; + Ice::ObjectAdapterPtr _replyAdapter; + LocatorIPtr _locator; + Ice::LocatorPrxPtr _locatorPrx; + Ice::LocatorPrxPtr _defaultLocator; +}; + +#ifndef ICE_CPP11_MAPPING + +class CallbackI : public IceUtil::Shared +{ +public: + + CallbackI(const LocatorIPtr& locator) : _locator(locator) + { + } + + void + completed(const Ice::AsyncResultPtr& result) + { + try + { + result->throwLocalException(); + } + catch(const Ice::LocalException& ex) + { + _locator->exception(ex); + } + } + +private: + + LocatorIPtr _locator; +}; + +#endif + +} + +// +// Plugin factory function. +// +extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin* +createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string& name, const Ice::StringSeq&) +{ + return new PluginI(name, communicator); +} + +namespace Ice +{ + +ICE_LOCATOR_DISCOVERY_API void +registerIceLocatorDiscovery(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, loadOnInitialize); + +#ifdef ICE_STATIC_LIBS + // + // Also register the UDP plugin with static builds to ensure the UDP transport is loaded. + // + registerIceUDP(true); +#endif +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_LOCATOR_DISCOVERY_API void +ICEregisterIceLocatorDiscovery(bool loadOnInitialize) +{ + Ice::registerIceLocatorDiscovery(loadOnInitialize); +} + +PluginI::PluginI(const string& name, const Ice::CommunicatorPtr& communicator) : + _name(name), _communicator(communicator) +{ +} + +void +PluginI::initialize() +{ + Ice::PropertiesPtr properties = _communicator->getProperties(); + + bool ipv4 = properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; + bool preferIPv6 = properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0; + string address; + if(ipv4 && !preferIPv6) + { + address = properties->getPropertyWithDefault(_name + ".Address", "239.255.0.1"); + } + else + { + address = properties->getPropertyWithDefault(_name + ".Address", "ff15::1"); + } + int port = properties->getPropertyAsIntWithDefault(_name + ".Port", 4061); + string intf = properties->getProperty(_name + ".Interface"); + + string lookupEndpoints = properties->getProperty(_name + ".Lookup"); + if(lookupEndpoints.empty()) + { + // + // If no lookup endpoints are specified, we get all the network interfaces and create + // an endpoint for each of them. We'll send UDP multicast packages on each interface. + // + IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6; + vector interfaces = IceInternal::getInterfacesForMulticast(intf, protocol); + ostringstream lookup; + for(vector::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) + { + if(p != interfaces.begin()) + { + lookup << ":"; + } + lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\""; + } + lookupEndpoints = lookup.str(); + } + + if(properties->getProperty(_name + ".Reply.Endpoints").empty()) + { + properties->setProperty(_name + ".Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\"")); + } + + if(properties->getProperty(_name + ".Locator.Endpoints").empty()) + { + properties->setProperty(_name + ".Locator.AdapterId", Ice::generateUUID()); // Collocated adapter + } + + _replyAdapter = _communicator->createObjectAdapter(_name + ".Reply"); + _locatorAdapter = _communicator->createObjectAdapter(_name + ".Locator"); + + // We don't want those adapters to be registered with the locator so clear their locator. + _replyAdapter->setLocator(0); + _locatorAdapter->setLocator(0); + + Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints); + // No collocation optimization for the multicast proxy! + lookupPrx = lookupPrx->ice_collocationOptimized(false)->ice_router(ICE_NULLPTR); + + Ice::LocatorPrxPtr voidLocator = ICE_UNCHECKED_CAST(Ice::LocatorPrx, + _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(VoidLocatorI))); + + string instanceName = properties->getProperty(_name + ".InstanceName"); + Ice::Identity id; + id.name = "Locator"; + id.category = !instanceName.empty() ? instanceName : Ice::generateUUID(); + _locator = ICE_MAKE_SHARED(LocatorI, _name, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties, instanceName, + voidLocator); + _defaultLocator = _communicator->getDefaultLocator(); + _locatorPrx = ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->add(_locator, id)); + _communicator->setDefaultLocator(_locatorPrx); + + Ice::ObjectPrxPtr lookupReply = _replyAdapter->addWithUUID(ICE_MAKE_SHARED(LookupReplyI, _locator))->ice_datagram(); + _locator->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, lookupReply)); + + _replyAdapter->activate(); + _locatorAdapter->activate(); +} + +vector +PluginI::getLocators(const string& instanceName, const IceUtil::Time& waitTime) const +{ + return _locator->getLocators(instanceName, waitTime); +} + +void +PluginI::destroy() +{ + if(_replyAdapter) + { + _replyAdapter->destroy(); + } + if(_locatorAdapter) + { + _locatorAdapter->destroy(); + } + if(_communicator->getDefaultLocator() == _locatorPrx) + { + // Restore original default locator proxy, if the user didn't change it in the meantime + _communicator->setDefaultLocator(_defaultLocator); + } +} + +void +Request::invoke(const Ice::LocatorPrxPtr& l) +{ +#ifdef ICE_CPP11_MAPPING + if(l != _locatorPrx) + { + _locatorPrx = l; + try + { + auto self = shared_from_this(); + l->ice_invokeAsync(_operation, _mode, _inParams, + [self](bool ok, vector outParams) + { + pair outPair; + if(outParams.empty()) + { + outPair.first = outPair.second = 0; + } + else + { + outPair.first = &outParams[0]; + outPair.second = outPair.first + outParams.size(); + } + self->response(ok, outPair); + }, + [self](exception_ptr e) + { + try + { + rethrow_exception(e); + } + catch(const Ice::Exception& ex) + { + self->exception(ex); + } + }, + nullptr, + _context); + } + catch(const Ice::LocalException& ex) + { + exception(ex); + } + } + else + { + assert(_exception); // Don't retry if the proxy didn't change + _amdCB.second(_exception); + } + +#else + if(l != _locatorPrx) + { + _locatorPrx = l; + try + { + l->begin_ice_invoke(_operation, _mode, _inParams, _context, + Ice::newCallback_Object_ice_invoke(this, &Request::response, &Request::exception)); + } + catch(const Ice::LocalException& ex) + { + exception(ex); + } + } + else + { + assert(_exception.get()); // Don't retry if the proxy didn't change + _amdCB->ice_exception(*_exception.get()); + } +#endif +} + +void +Request::response(bool ok, const pair& outParams) +{ +#ifdef ICE_CPP11_MAPPING + _amdCB.first(ok, outParams); +#else + _amdCB->ice_response(ok, outParams); +#endif +} + +void +Request::exception(const Ice::Exception& ex) +{ +#ifdef ICE_CPP11_MAPPING + try + { + ex.ice_throw(); + } + catch(const Ice::RequestFailedException&) + { + _amdCB.second(current_exception()); + } + catch(const Ice::UnknownException&) + { + _amdCB.second(current_exception()); + } + catch(const Ice::NoEndpointException&) + { + try + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + catch(...) + { + _amdCB.second(current_exception()); + } + } + catch(const Ice::CommunicatorDestroyedException&) + { + try + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + catch(...) + { + _amdCB.second(current_exception()); + } + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + try + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + catch(...) + { + _amdCB.second(current_exception()); + } + } + catch(const Ice::Exception&) + { + _exception = current_exception(); + _locator->invoke(_locatorPrx, shared_from_this()); // Retry with new locator proxy + } +#else + try + { + ex.ice_throw(); + } + catch(const Ice::RequestFailedException&) + { + _amdCB->ice_exception(ex); + } + catch(const Ice::UnknownException&) + { + _amdCB->ice_exception(ex); + } + catch(const Ice::NoEndpointException&) + { + _amdCB->ice_exception(Ice::ObjectNotExistException(__FILE__, __LINE__)); + } + catch(const Ice::CommunicatorDestroyedException&) + { + _amdCB->ice_exception(Ice::ObjectNotExistException(__FILE__, __LINE__)); + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + _amdCB->ice_exception(Ice::ObjectNotExistException(__FILE__, __LINE__)); + } + catch(const Ice::Exception&) + { + _exception.reset(ex.ice_clone()); + _locator->invoke(_locatorPrx, this); // Retry with new locator proxy + } +#endif +} + +LocatorI::LocatorI(const string& name, + const LookupPrxPtr& lookup, + const Ice::PropertiesPtr& p, + const string& instanceName, + const Ice::LocatorPrxPtr& voidLocator) : + _lookup(lookup), + _timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".Timeout", 300))), + _retryCount(p->getPropertyAsIntWithDefault(name + ".RetryCount", 3)), + _retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".RetryDelay", 2000))), + _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())), + _traceLevel(p->getPropertyAsInt(name + ".Trace.Lookup")), + _instanceName(instanceName), + _warned(false), + _locator(lookup->ice_getCommunicator()->getDefaultLocator()), + _voidLocator(voidLocator), + _pending(false), + _pendingRetryCount(0), + _failureCount(0), + _warnOnce(true) +{ + if(_timeout < IceUtil::Time::milliSeconds(0)) + { + _timeout = IceUtil::Time::milliSeconds(300); + } + if(_retryCount < 0) + { + _retryCount = 0; + } + if(_retryDelay < IceUtil::Time::milliSeconds(0)) + { + _retryDelay = IceUtil::Time::milliSeconds(0); + } + + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + Ice::EndpointSeq endpoints = lookup->ice_getEndpoints(); + for(vector::const_iterator q = endpoints.begin(); q != endpoints.end(); ++q) + { + Ice::EndpointSeq single; + single.push_back(*q); + _lookups.push_back(make_pair(lookup->ice_endpoints(single), LookupReplyPrxPtr())); + } + assert(!_lookups.empty()); +} + +void +LocatorI::setLookupReply(const LookupReplyPrxPtr& lookupReply) +{ + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + for(vector >::iterator p = _lookups.begin(); p != _lookups.end(); ++p) + { + Ice::UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(Ice::UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo()); + if(info && !info->mcastInterface.empty()) + { + Ice::EndpointSeq endpts = lookupReply->ice_getEndpoints(); + for(Ice::EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q) + { + Ice::IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, (*q)->getInfo()); + if(r && r->host == info->mcastInterface) + { + Ice::EndpointSeq single; + single.push_back(*q); + p->second = lookupReply->ice_endpoints(single); + } + } + } + + if(!p->second) + { + p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found. + } + } +} + +#ifdef ICE_CPP11_MAPPING +void +LocatorI::ice_invokeAsync(pair inParams, + function&)> responseCB, + function exceptionCB, + const Ice::Current& current) +{ + invoke(nullptr, make_shared(this, current.operation, current.mode, inParams, current.ctx, + make_pair(std::move(responseCB), std::move(exceptionCB)))); +} +#else +void +LocatorI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCB, + const pair& inParams, + const Ice::Current& current) +{ + invoke(0, new Request(this, current.operation, current.mode, inParams, current.ctx, amdCB)); +} +#endif + +vector +LocatorI::getLocators(const string& instanceName, const IceUtil::Time& waitTime) +{ + // + // Clear locators from previous search + // + { + Lock sync(*this); + _locators.clear(); + } + + // + // Find a locator + // + invoke(ICE_NULLPTR, ICE_NULLPTR); + + // + // Wait for responses + // + if(instanceName.empty()) + { + IceUtil::ThreadControl::sleep(waitTime); + } + else + { + Lock sync(*this); + while(_locators.find(instanceName) == _locators.end() && _pending) + { + timedWait(waitTime); + } + } + + // + // Return found locators + // + Lock sync(*this); + vector locators; + for(map::const_iterator p = _locators.begin(); p != _locators.end(); ++p) + { + locators.push_back(p->second); + } + return locators; +} + +void +LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator) +{ + Lock sync(*this); + + if(!locator) + { + if(_traceLevel > 2) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "ignoring locator reply: (null locator)"; + } + return; + } + + if(!_instanceName.empty() && locator->ice_getIdentity().category != _instanceName) + { + if(_traceLevel > 2) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "ignoring locator reply: instance name doesn't match\n"; + out << "expected = " << _instanceName; + out << "received = " << locator->ice_getIdentity().category; + } + return; + } + + // + // If we already have a locator assigned, ensure the given locator + // has the same identity, otherwise ignore it. + // + if(!_pendingRequests.empty() && + _locator && locator->ice_getIdentity().category != _locator->ice_getIdentity().category) + { + if(!_warned) + { + _warned = true; // Only warn once. + + Ice::Warning out(locator->ice_getCommunicator()->getLogger()); + out << "received Ice locator with different instance name:\n"; + out << "using = `" << _locator->ice_getIdentity().category << "'\n"; + out << "received = `" << locator->ice_getIdentity().category << "'\n"; + out << "This is typically the case if multiple Ice locators with different"; + out << "instance names are deployed and the property `IceLocatorDiscovery.InstanceName' "; + out << "is not set."; + } + return; + } + + if(_pending) // No need to continue, we found a locator. + { + _timer->cancel(ICE_SHARED_FROM_THIS); + _pendingRetryCount = 0; + _pending = false; + } + + if(_traceLevel > 0) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "locator lookup succeeded:\nlocator = " << locator; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + } + + Ice::LocatorPrxPtr l = _pendingRequests.empty() ? _locators[locator->ice_getIdentity().category] : _locator; + if(l) + { + // + // We found another locator replica, append its endpoints to the + // current locator proxy endpoints. + // + Ice::EndpointSeq newEndpoints = l->ice_getEndpoints(); + Ice::EndpointSeq endpts = locator->ice_getEndpoints(); + for(Ice::EndpointSeq::const_iterator p = endpts.begin(); p != endpts.end(); ++p) + { + // + // Only add endpoints if not already in the locator proxy endpoints + // + bool found = false; + for(Ice::EndpointSeq::const_iterator q = newEndpoints.begin(); q != newEndpoints.end(); ++q) + { + if(*p == *q) + { + found = true; + break; + } + } + if(!found) + { + newEndpoints.push_back(*p); + } + } + l = l->ice_endpoints(newEndpoints); + } + else + { + l = locator; + } + + if(_pendingRequests.empty()) + { + _locators[locator->ice_getIdentity().category] = l; + notify(); + } + else + { + _locator = l; + if(_instanceName.empty()) + { + _instanceName = _locator->ice_getIdentity().category; // Stick to the first discovered locator. + } + + // + // Send pending requests if any. + // + for(vector::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_locator); + } + _pendingRequests.clear(); + } +} + +void +LocatorI::invoke(const Ice::LocatorPrxPtr& locator, const RequestPtr& request) +{ + Lock sync(*this); + if(request && _locator && _locator != locator) + { + request->invoke(_locator); + } + else if(request && IceUtil::Time::now() < _nextRetry) + { + request->invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires + } + else + { + _locator = 0; + + if(request) + { + _pendingRequests.push_back(request); + } + + if(!_pending) // No request in progress + { + _pending = true; + _failureCount = 0; + _pendingRetryCount = _retryCount; + try + { + if(_traceLevel > 1) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "looking up locator:\nlookup = " << _lookup; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + } + for(vector >::const_iterator l = _lookups.begin(); + l != _lookups.end(); ++l) + { +#ifdef ICE_CPP11_MAPPING + auto self = shared_from_this(); + l->first->findLocatorAsync(_instanceName, l->second, nullptr, [self](exception_ptr ex) + { + try + { + rethrow_exception(ex); + } + catch(const Ice::LocalException& e) + { + self->exception(e); + } + }); +#else + l->first->begin_findLocator(_instanceName, l->second, Ice::newCallback(new CallbackI(this), + &CallbackI::completed)); +#endif + } + _timer->schedule(ICE_SHARED_FROM_THIS, _timeout); + } + catch(const Ice::LocalException& ex) + { + if(_traceLevel > 0) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "locator lookup failed:\nlookup = " << _lookup; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + out << "\n" << ex; + } + + for(vector::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_voidLocator); + } + _pendingRequests.clear(); + _pending = false; + _pendingRetryCount = 0; + } + } + } +} + +void +LocatorI::exception(const Ice::LocalException& ex) +{ + Lock sync(*this); + if(++_failureCount == _lookups.size() && _pending) + { + // + // All the lookup calls failed, cancel the timer and propagate the error to the requests. + // + _timer->cancel(ICE_SHARED_FROM_THIS); + _pendingRetryCount = 0; + _pending = false; + + if(_warnOnce) + { + Ice::Warning warn(_lookup->ice_getCommunicator()->getLogger()); + warn << "failed to lookup locator with lookup proxy `" << _lookup << "':\n" << ex; + _warnOnce = false; + } + + if(_traceLevel > 0) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "locator lookup failed:\nlookup = " << _lookup; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + out << "\n" << ex; + } + + if(_pendingRequests.empty()) + { + notify(); + } + else + { + for(vector::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_voidLocator); + } + _pendingRequests.clear(); + } + } +} + +void +LocatorI::runTimerTask() +{ + Lock sync(*this); + if(!_pending) + { + assert(_pendingRequests.empty()); + return; // The request failed + } + + if(_pendingRetryCount > 0) + { + --_pendingRetryCount; + try + { + if(_traceLevel > 1) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "retrying locator lookup:\nlookup = " << _lookup << "\nretry count = " << _pendingRetryCount; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + } + _failureCount = 0; + for(vector >::const_iterator l = _lookups.begin(); + l != _lookups.end(); ++l) + { +#ifdef ICE_CPP11_MAPPING + auto self = shared_from_this(); + l->first->findLocatorAsync(_instanceName, l->second, nullptr, [self](exception_ptr ex) + { + try + { + rethrow_exception(ex); + } + catch(const Ice::LocalException& e) + { + self->exception(e); + } + }); +#else + l->first->begin_findLocator(_instanceName, l->second, Ice::newCallback(new CallbackI(this), + &CallbackI::completed)); +#endif + } + _timer->schedule(ICE_SHARED_FROM_THIS, _timeout); + return; + } + catch(const Ice::LocalException&) + { + } + _pendingRetryCount = 0; + } + + assert(_pendingRetryCount == 0); + _pending = false; + + if(_traceLevel > 0) + { + Ice::Trace out(_lookup->ice_getCommunicator()->getLogger(), "Lookup"); + out << "locator lookup timed out:\nlookup = " << _lookup; + if(!_instanceName.empty()) + { + out << "\ninstance name = " << _instanceName; + } + } + + if(_pendingRequests.empty()) + { + notify(); + } + else + { + for(vector::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_voidLocator); // Send pending requests on void locator. + } + _pendingRequests.clear(); + } + _nextRetry = IceUtil::Time::now() + _retryDelay; // Only retry when the retry delay expires +} + +void +LookupReplyI::foundLocator(ICE_IN(Ice::LocatorPrxPtr) locator, const Ice::Current&) +{ + _locator->foundLocator(locator); +} diff --git a/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/IceLocatorDiscovery.h b/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/IceLocatorDiscovery.h new file mode 100644 index 0000000..9da5472 --- /dev/null +++ b/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/IceLocatorDiscovery.h @@ -0,0 +1,1197 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `IceLocatorDiscovery.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceLocatorDiscovery_IceLocatorDiscovery_h__ +#define __IceLocatorDiscovery_IceLocatorDiscovery_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceLocatorDiscovery +{ + +class LookupReply; +class LookupReplyPrx; +class Lookup; +class LookupPrx; + +} + +namespace IceLocatorDiscovery +{ + +/** + * The Ice lookup reply interface must be implemented by clients which + * are searching for Ice locators. Ice locator implementations invoke + * on this interface to provide their locator proxy. + * @see Lookup + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class LookupReply : public virtual ::Ice::Object +{ +public: + + using ProxyType = LookupReplyPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const ::Ice::Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const ::Ice::Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param current The Current object for the invocation. + */ + virtual void foundLocator(::std::shared_ptr<::Ice::LocatorPrx> prx, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_foundLocator(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override; + /// \endcond +}; + +/** + * The Ice lookup interface is implemented by Ice locator + * implementations and can be used by clients to find available Ice + * locators on the network. + * + * Ice locator implementations provide a well-known `Ice/LocatorLookup' + * object accessible through UDP multicast. Clients typically make a + * multicast findLocator request to find the locator proxy. + * @see LookupReply + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class Lookup : public virtual ::Ice::Object +{ +public: + + using ProxyType = LookupPrx; + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(::std::string id, const ::Ice::Current& current) const override; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector<::std::string> ice_ids(const ::Ice::Current& current) const override; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual ::std::string ice_id(const ::Ice::Current& current) const override; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param current The Current object for the invocation. + */ + virtual void findLocator(::std::string instanceName, ::std::shared_ptr reply, const ::Ice::Current& current) = 0; + /// \cond INTERNAL + bool _iceD_findLocator(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&) override; + /// \endcond +}; + +} + +namespace IceLocatorDiscovery +{ + +/** + * The Ice lookup reply interface must be implemented by clients which + * are searching for Ice locators. Ice locator implementations invoke + * on this interface to provide their locator proxy. + * @see Lookup + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class LookupReplyPrx : public virtual ::Ice::Proxy +{ +public: + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + */ + void foundLocator(const ::std::shared_ptr<::Ice::LocatorPrx>& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupReplyPrx::_iceI_foundLocator, prx, context).get(); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto foundLocatorAsync(const ::std::shared_ptr<::Ice::LocatorPrx>& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupReplyPrx::_iceI_foundLocator, prx, context); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + foundLocatorAsync(const ::std::shared_ptr<::Ice::LocatorPrx>& prx, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceLocatorDiscovery::LookupReplyPrx::_iceI_foundLocator, prx, context); + } + + /// \cond INTERNAL + void _iceI_foundLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::shared_ptr<::Ice::LocatorPrx>&, const ::Ice::Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LookupReplyPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override; + /// \endcond +}; + +/** + * The Ice lookup interface is implemented by Ice locator + * implementations and can be used by clients to find available Ice + * locators on the network. + * + * Ice locator implementations provide a well-known `Ice/LocatorLookup' + * object accessible through UDP multicast. Clients typically make a + * multicast findLocator request to find the locator proxy. + * @see LookupReply + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class LookupPrx : public virtual ::Ice::Proxy +{ +public: + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + */ + void findLocator(const ::std::string& instanceName, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + _makePromiseOutgoing(true, this, &LookupPrx::_iceI_findLocator, instanceName, reply, context).get(); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + * @return The future object for the invocation. + */ + template class P = ::std::promise> + auto findLocatorAsync(const ::std::string& instanceName, const ::std::shared_ptr& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + -> decltype(::std::declval>().get_future()) + { + return _makePromiseOutgoing(false, this, &LookupPrx::_iceI_findLocator, instanceName, reply, context); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param response The response callback. + * @param ex The exception callback. + * @param sent The sent callback. + * @param context The Context map to send with the invocation. + * @return A function that can be called to cancel the invocation locally. + */ + ::std::function + findLocatorAsync(const ::std::string& instanceName, const ::std::shared_ptr& reply, + ::std::function response, + ::std::function ex = nullptr, + ::std::function sent = nullptr, + const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _makeLamdaOutgoing(std::move(response), std::move(ex), std::move(sent), this, &IceLocatorDiscovery::LookupPrx::_iceI_findLocator, instanceName, reply, context); + } + + /// \cond INTERNAL + void _iceI_findLocator(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT>&, const ::std::string&, const ::std::shared_ptr&, const ::Ice::Context&); + /// \endcond + + /** + * Obtains the Slice type ID of this interface. + * @return The fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + + /// \cond INTERNAL + LookupPrx() = default; + friend ::std::shared_ptr IceInternal::createProxy(); + + virtual ::std::shared_ptr<::Ice::ObjectPrx> _newInstance() const override; + /// \endcond +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceLocatorDiscovery +{ + +using LookupReplyPtr = ::std::shared_ptr; +using LookupReplyPrxPtr = ::std::shared_ptr; + +using LookupPtr = ::std::shared_ptr; +using LookupPrxPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceProxy +{ + +namespace IceLocatorDiscovery +{ + +class LookupReply; +/// \cond INTERNAL +void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< LookupReply>&); +::IceProxy::Ice::Object* upCast(LookupReply*); +/// \endcond + +class Lookup; +/// \cond INTERNAL +void _readProxy(::Ice::InputStream*, ::IceInternal::ProxyHandle< Lookup>&); +::IceProxy::Ice::Object* upCast(Lookup*); +/// \endcond + +} + +} + +namespace IceLocatorDiscovery +{ + +class LookupReply; +/// \cond INTERNAL +::Ice::Object* upCast(LookupReply*); +/// \endcond +typedef ::IceInternal::Handle< LookupReply> LookupReplyPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceLocatorDiscovery::LookupReply> LookupReplyPrx; +typedef LookupReplyPrx LookupReplyPrxPtr; +/// \cond INTERNAL +void _icePatchObjectPtr(LookupReplyPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +class Lookup; +/// \cond INTERNAL +::Ice::Object* upCast(Lookup*); +/// \endcond +typedef ::IceInternal::Handle< Lookup> LookupPtr; +typedef ::IceInternal::ProxyHandle< ::IceProxy::IceLocatorDiscovery::Lookup> LookupPrx; +typedef LookupPrx LookupPrxPtr; +/// \cond INTERNAL +void _icePatchObjectPtr(LookupPtr&, const ::Ice::ObjectPtr&); +/// \endcond + +} + +/// \cond INTERNAL +namespace IceAsync +{ + +} +/// \endcond + +namespace IceLocatorDiscovery +{ + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_LookupReply_foundLocator. + */ +class Callback_LookupReply_foundLocator_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_LookupReply_foundLocator_Base> Callback_LookupReply_foundLocatorPtr; + +/** + * Base class for asynchronous callback wrapper classes used for calls to + * IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_Lookup_findLocator. + */ +class Callback_Lookup_findLocator_Base : public virtual ::IceInternal::CallbackBase { }; +typedef ::IceUtil::Handle< Callback_Lookup_findLocator_Base> Callback_Lookup_findLocatorPtr; + +} + +namespace IceProxy +{ + +namespace IceLocatorDiscovery +{ + +class LookupReply : public virtual ::Ice::Proxy +{ +public: + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + */ + void foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_foundLocator(_iceI_begin_foundLocator(prx, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_foundLocator(prx, context, ::IceInternal::dummyCallback, 0); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundLocator(prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundLocator(prx, context, cb, cookie); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundLocator(const ::Ice::LocatorPrx& prx, const ::IceLocatorDiscovery::Callback_LookupReply_foundLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundLocator(prx, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::Context& context, const ::IceLocatorDiscovery::Callback_LookupReply_foundLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_foundLocator(prx, context, cb, cookie); + } + + /** + * Completes an invocation of begin_foundLocator. + * @param result The asynchronous result object for the invocation. + */ + void end_foundLocator(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_foundLocator(const ::Ice::LocatorPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +class Lookup : public virtual ::Ice::Proxy +{ +public: + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + */ + void findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + end_findLocator(_iceI_begin_findLocator(instanceName, reply, context, ::IceInternal::dummyCallback, 0, true)); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context = ::Ice::noExplicitContext) + { + return _iceI_begin_findLocator(instanceName, reply, context, ::IceInternal::dummyCallback, 0); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findLocator(instanceName, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::Ice::CallbackPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findLocator(instanceName, reply, context, cb, cookie); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::IceLocatorDiscovery::Callback_Lookup_findLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findLocator(instanceName, reply, ::Ice::noExplicitContext, cb, cookie); + } + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param context The Context map to send with the invocation. + * @param cb Asynchronous callback object. + * @param cookie User-defined data to associate with the invocation. + * @return The asynchronous result object for the invocation. + */ + ::Ice::AsyncResultPtr begin_findLocator(const ::std::string& instanceName, const ::IceLocatorDiscovery::LookupReplyPrx& reply, const ::Ice::Context& context, const ::IceLocatorDiscovery::Callback_Lookup_findLocatorPtr& cb, const ::Ice::LocalObjectPtr& cookie = 0) + { + return _iceI_begin_findLocator(instanceName, reply, context, cb, cookie); + } + + /** + * Completes an invocation of begin_findLocator. + * @param result The asynchronous result object for the invocation. + */ + void end_findLocator(const ::Ice::AsyncResultPtr& result); + +private: + + ::Ice::AsyncResultPtr _iceI_begin_findLocator(const ::std::string&, const ::IceLocatorDiscovery::LookupReplyPrx&, const ::Ice::Context&, const ::IceInternal::CallbackBasePtr&, const ::Ice::LocalObjectPtr& cookie = 0, bool sync = false); + +public: + + /** + * Obtains the Slice type ID corresponding to this interface. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + +protected: + /// \cond INTERNAL + + virtual ::IceProxy::Ice::Object* _newInstance() const; + /// \endcond +}; + +} + +} + +namespace IceLocatorDiscovery +{ + +/** + * The Ice lookup reply interface must be implemented by clients which + * are searching for Ice locators. Ice locator implementations invoke + * on this interface to provide their locator proxy. + * @see Lookup + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class LookupReply : public virtual ::Ice::Object +{ +public: + + typedef LookupReplyPrx ProxyType; + typedef LookupReplyPtr PointerType; + + virtual ~LookupReply(); + +#ifdef ICE_CPP11_COMPILER + LookupReply() = default; + LookupReply(const LookupReply&) = default; + LookupReply& operator=(const LookupReply&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * This method is called by the implementation of the Lookup + * interface to reply to a findLocator request. + * @param prx The proxy of the locator. + * @param current The Current object for the invocation. + */ + virtual void foundLocator(const ::Ice::LocatorPrx& prx, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_foundLocator(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const LookupReply& lhs, const LookupReply& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const LookupReply& lhs, const LookupReply& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +/** + * The Ice lookup interface is implemented by Ice locator + * implementations and can be used by clients to find available Ice + * locators on the network. + * + * Ice locator implementations provide a well-known `Ice/LocatorLookup' + * object accessible through UDP multicast. Clients typically make a + * multicast findLocator request to find the locator proxy. + * @see LookupReply + * \headerfile IceLocatorDiscovery/IceLocatorDiscovery.h + */ +class Lookup : public virtual ::Ice::Object +{ +public: + + typedef LookupPrx ProxyType; + typedef LookupPtr PointerType; + + virtual ~Lookup(); + +#ifdef ICE_CPP11_COMPILER + Lookup() = default; + Lookup(const Lookup&) = default; + Lookup& operator=(const Lookup&) = default; +#endif + + /** + * Determines whether this object supports an interface with the given Slice type ID. + * @param id The fully-scoped Slice type ID. + * @param current The Current object for the invocation. + * @return True if this object supports the interface, false, otherwise. + */ + virtual bool ice_isA(const ::std::string& id, const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a list of the Slice type IDs representing the interfaces supported by this object. + * @param current The Current object for the invocation. + * @return A list of fully-scoped type IDs. + */ + virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains a Slice type ID representing the most-derived interface supported by this object. + * @param current The Current object for the invocation. + * @return A fully-scoped type ID. + */ + virtual const ::std::string& ice_id(const ::Ice::Current& current = ::Ice::emptyCurrent) const; + + /** + * Obtains the Slice type ID corresponding to this class. + * @return A fully-scoped type ID. + */ + static const ::std::string& ice_staticId(); + + /** + * Find a locator proxy with the given instance name. + * @param instanceName Restrict the search to Ice registries + * configured with the given instance name. If empty, all the + * available registries will reply. + * @param reply The reply object to use to send the reply. + * @param current The Current object for the invocation. + */ + virtual void findLocator(const ::std::string& instanceName, const LookupReplyPrx& reply, const ::Ice::Current& current = ::Ice::emptyCurrent) = 0; + /// \cond INTERNAL + bool _iceD_findLocator(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + + /// \cond INTERNAL + virtual bool _iceDispatch(::IceInternal::Incoming&, const ::Ice::Current&); + /// \endcond + +protected: + + /// \cond STREAM + virtual void _iceWriteImpl(::Ice::OutputStream*) const; + virtual void _iceReadImpl(::Ice::InputStream*); + /// \endcond +}; + +/// \cond INTERNAL +inline bool operator==(const Lookup& lhs, const Lookup& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const Lookup& lhs, const Lookup& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +namespace IceLocatorDiscovery +{ + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_LookupReply_foundLocator. + */ +template +class CallbackNC_LookupReply_foundLocator : public Callback_LookupReply_foundLocator_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_LookupReply_foundLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundLocator(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_LookupReply_foundLocator(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_LookupReply_foundLocator. + */ +template +class Callback_LookupReply_foundLocator : public Callback_LookupReply_foundLocator_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_LookupReply_foundLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundLocator(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::LookupReply::begin_foundLocator. + */ +template Callback_LookupReply_foundLocatorPtr +newCallback_LookupReply_foundLocator(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_LookupReply_foundLocator(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class used for calls to + * IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_Lookup_findLocator. + */ +template +class CallbackNC_Lookup_findLocator : public Callback_Lookup_findLocator_Base, public ::IceInternal::OnewayCallbackNC +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception&); + typedef void (T::*Sent)(bool); + typedef void (T::*Response)(); + + CallbackNC_Lookup_findLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallbackNC(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(const IceUtil::Handle& instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findLocator(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(T* instance, void (T::*cb)(), void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(T* instance, void (T::*excb)(const ::Ice::Exception&), void (T::*sentcb)(bool) = 0) +{ + return new CallbackNC_Lookup_findLocator(instance, 0, excb, sentcb); +} + +/** + * Type-safe asynchronous callback wrapper class with cookie support used for calls to + * IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + * Create a wrapper instance by calling ::IceLocatorDiscovery::newCallback_Lookup_findLocator. + */ +template +class Callback_Lookup_findLocator : public Callback_Lookup_findLocator_Base, public ::IceInternal::OnewayCallback +{ +public: + + typedef IceUtil::Handle TPtr; + + typedef void (T::*Exception)(const ::Ice::Exception& , const CT&); + typedef void (T::*Sent)(bool , const CT&); + typedef void (T::*Response)(const CT&); + + Callback_Lookup_findLocator(const TPtr& obj, Response cb, Exception excb, Sent sentcb) + : ::IceInternal::OnewayCallback(obj, cb, excb, sentcb) + { + } +}; + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(const IceUtil::Handle& instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(const IceUtil::Handle& instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findLocator(instance, 0, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param cb The success method of the callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(T* instance, void (T::*cb)(const CT&), void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findLocator(instance, cb, excb, sentcb); +} + +/** + * Creates a callback wrapper instance that delegates to your object. + * Use this overload when your callback methods receive a cookie value. + * @param instance The callback object. + * @param excb The exception method of the callback object. + * @param sentcb The sent method of the callback object. + * @return An object that can be passed to an asynchronous invocation of IceProxy::IceLocatorDiscovery::Lookup::begin_findLocator. + */ +template Callback_Lookup_findLocatorPtr +newCallback_Lookup_findLocator(T* instance, void (T::*excb)(const ::Ice::Exception&, const CT&), void (T::*sentcb)(bool, const CT&) = 0) +{ + return new Callback_Lookup_findLocator(instance, 0, excb, sentcb); +} + +} + +#endif + +#include +#endif diff --git a/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/Plugin.h b/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/Plugin.h new file mode 100644 index 0000000..8699755 --- /dev/null +++ b/Sources/IceLocatorDiscoveryCpp/include/IceLocatorDiscovery/Plugin.h @@ -0,0 +1,47 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef LOCATOR_DISCOVERY_PLUGIN_I_H +#define LOCATOR_DISCOVERY_PLUGIN_I_H + +#include +#include +#include +#include + +// +// Automatically link IceLocatorDiscovery[D|++11|++11D].lib with Visual C++ +// +#if !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY) && defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS) +# define ICE_BUILDING_ICE_LOCATOR_DISCOVERY +#endif + +#if defined(_MSC_VER) && !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY) +# pragma comment(lib, ICE_LIBNAME("IceLocatorDiscovery")) +#endif + +#ifndef ICE_LOCATOR_DISCOVERY_API +# if defined(ICE_STATIC_LIBS) +# define ICE_LOCATOR_DISCOVERY_API /**/ +# elif defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS) +# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_EXPORT +# else +# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_IMPORT +# endif +#endif + +namespace IceLocatorDiscovery +{ + +class ICE_LOCATOR_DISCOVERY_API Plugin : public Ice::Plugin +{ +public: + + virtual std::vector getLocators(const std::string&, const IceUtil::Time&) const = 0; +}; +ICE_DEFINE_PTR(PluginPtr, Plugin); + +}; + +#endif diff --git a/Sources/IceSSLCpp/AcceptorI.cpp b/Sources/IceSSLCpp/AcceptorI.cpp new file mode 100644 index 0000000..78e1f11 --- /dev/null +++ b/Sources/IceSSLCpp/AcceptorI.cpp @@ -0,0 +1,105 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +IceUtil::Shared* IceSSL::upCast(AcceptorI* p) { return p; } + +IceInternal::NativeInfoPtr +IceSSL::AcceptorI::getNativeInfo() +{ + return _delegate->getNativeInfo(); +} + +#if defined(ICE_USE_IOCP) +IceInternal::AsyncInfo* +IceSSL::AcceptorI::getAsyncInfo(IceInternal::SocketOperation status) +{ + return _delegate->getNativeInfo()->getAsyncInfo(status); +} +#endif + +void +IceSSL::AcceptorI::close() +{ + _delegate->close(); +} + +IceInternal::EndpointIPtr +IceSSL::AcceptorI::listen() +{ + _endpoint = _endpoint->endpoint(_delegate->listen()); + return _endpoint; +} + +#if defined(ICE_USE_IOCP) +void +IceSSL::AcceptorI::startAccept() +{ + _delegate->startAccept(); + +} + +void +IceSSL::AcceptorI::finishAccept() +{ + _delegate->finishAccept(); +} +#endif + +IceInternal::TransceiverPtr +IceSSL::AcceptorI::accept() +{ + // + // The plug-in may not be initialized. + // + if(!_instance->initialized()) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: plug-in is not initialized"); + } + + return _instance->engine()->createTransceiver(_instance, _delegate->accept(), _adapterName, true); +} + +string +IceSSL::AcceptorI::protocol() const +{ + return _delegate->protocol(); +} + +string +IceSSL::AcceptorI::toString() const +{ + return _delegate->toString(); +} + +string +IceSSL::AcceptorI::toDetailedString() const +{ + return _delegate->toDetailedString(); +} + +IceSSL::AcceptorI::AcceptorI(const EndpointIPtr& endpoint, const InstancePtr& instance, + const IceInternal::AcceptorPtr& del, const string& adapterName) : + _endpoint(endpoint), + _instance(instance), + _delegate(del), + _adapterName(adapterName) +{ +} + +IceSSL::AcceptorI::~AcceptorI() +{ +} diff --git a/Sources/IceSSLCpp/CertificateI.cpp b/Sources/IceSSLCpp/CertificateI.cpp new file mode 100644 index 0000000..3f7c4ae --- /dev/null +++ b/Sources/IceSSLCpp/CertificateI.cpp @@ -0,0 +1,301 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceSSL; + +// +// Map a certificate OID to its alias +// +const CertificateOID IceSSL::certificateOIDS[] = +{ + {"2.5.4.3", "CN"}, + {"2.5.4.4", "SN"}, + {"2.5.4.5", "DeviceSerialNumber"}, + {"2.5.4.6", "C"}, + {"2.5.4.7", "L"}, + {"2.5.4.8", "ST"}, + {"2.5.4.9", "STREET"}, + {"2.5.4.10", "O"}, + {"2.5.4.11", "OU"}, + {"2.5.4.12", "T"}, + {"2.5.4.42", "G"}, + {"2.5.4.43", "I"}, + {"1.2.840.113549.1.9.8", "unstructuredAddress"}, + {"1.2.840.113549.1.9.2", "unstructuredName"}, + {"1.2.840.113549.1.9.1", "emailAddress"}, + {"0.9.2342.19200300.100.1.25", "DC"} +}; +const int IceSSL::certificateOIDSSize = sizeof(IceSSL::certificateOIDS) / sizeof(CertificateOID); + +CertificateReadException::CertificateReadException(const char* file, int line, const string& r) : + IceUtil::ExceptionHelper(file, line), + reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +CertificateReadException::~CertificateReadException() throw() +{ +} +#endif + +string +CertificateReadException::ice_id() const +{ + return "::IceSSL::CertificateReadException"; +} + +#ifndef ICE_CPP11_MAPPING +CertificateReadException* +CertificateReadException::ice_clone() const +{ + return new CertificateReadException(*this); +} +#endif + +CertificateEncodingException::CertificateEncodingException(const char* file, int line, const string& r) : + IceUtil::ExceptionHelper(file, line), + reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +CertificateEncodingException::~CertificateEncodingException() throw() +{ +} +#endif + +string +CertificateEncodingException::ice_id() const +{ + return "::IceSSL::CertificateEncodingException"; +} + +#ifndef ICE_CPP11_MAPPING +CertificateEncodingException* +CertificateEncodingException::ice_clone() const +{ + return new CertificateEncodingException(*this); +} +#endif + +ParseException::ParseException(const char* file, int line, const string& r) : + IceUtil::ExceptionHelper(file, line), + reason(r) +{ +} + +#ifndef ICE_CPP11_COMPILER +ParseException::~ParseException() throw() +{ +} +#endif + +string +ParseException::ice_id() const +{ + return "::IceSSL::ParseException"; +} + +#ifndef ICE_CPP11_MAPPING +ParseException* +ParseException::ice_clone() const +{ + return new ParseException(*this); +} +#endif + +DistinguishedName::DistinguishedName(const string& dn) : _rdns(RFC2253::parseStrict(dn)) +{ + unescape(); +} + +DistinguishedName::DistinguishedName(const list >& rdns) : _rdns(rdns) +{ + unescape(); +} + +namespace IceSSL +{ + +bool +operator==(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return lhs._unescaped == rhs._unescaped; +} + +bool +operator<(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return lhs._unescaped < rhs._unescaped; +} + +} + +bool +DistinguishedName::match(const DistinguishedName& other) const +{ + for(list< pair >::const_iterator p = other._unescaped.begin(); p != other._unescaped.end(); ++p) + { + bool found = false; + for(list< pair >::const_iterator q = _unescaped.begin(); q != _unescaped.end(); ++q) + { + if(p->first == q->first) + { + found = true; + if(p->second != q->second) + { + return false; + } + } + } + if(!found) + { + return false; + } + } + return true; +} + +bool +DistinguishedName::match(const string& other) const +{ + return match(DistinguishedName(other)); +} + +// +// This always produces the same output as the input DN -- the type of +// escaping is not changed. +// +DistinguishedName::operator string() const +{ + ostringstream os; + bool first = true; + for(list< pair >::const_iterator p = _rdns.begin(); p != _rdns.end(); ++p) + { + if(!first) + { + os << ","; + } + first = false; + os << p->first << "=" << p->second; + } + return os.str(); +} + +void +DistinguishedName::unescape() +{ + for(list< pair >::const_iterator q = _rdns.begin(); q != _rdns.end(); ++q) + { + pair rdn = *q; + rdn.second = RFC2253::unescape(rdn.second); + _unescaped.push_back(rdn); + } +} + +bool +CertificateI::operator!=(const IceSSL::Certificate& other) const +{ + return !operator==(other); +} + +vector +CertificateI::getX509Extensions() const +{ + loadX509Extensions(); // Lazzy initialize the extensions + return _extensions; +} + +X509ExtensionPtr +CertificateI::getX509Extension(const string& oid) const +{ + loadX509Extensions(); // Lazzy initialize the extensions + X509ExtensionPtr ext; + for(vector::const_iterator i = _extensions.begin(); i != _extensions.end(); ++i) + { + if((*i)->getOID() == oid) + { + ext = *i; + break; + } + } + return ext; +} + +void +CertificateI::loadX509Extensions() const +{ + throw FeatureNotSupportedException(__FILE__, __LINE__); +} + +bool +CertificateI::checkValidity() const +{ +# ifdef ICE_CPP11_MAPPING + auto now = chrono::system_clock::now(); +# else + IceUtil::Time now = IceUtil::Time::now(); +# endif + return now > getNotBefore() && now <= getNotAfter(); +} + +bool +# ifdef ICE_CPP11_MAPPING +CertificateI::checkValidity(const chrono::system_clock::time_point& now) const +# else +CertificateI::checkValidity(const IceUtil::Time& now) const +# endif +{ + return now > getNotBefore() && now <= getNotAfter(); +} + +string +CertificateI::toString() const +{ + ostringstream os; + os << "serial: " << getSerialNumber() << "\n"; + os << "issuer: " << string(getIssuerDN()) << "\n"; + os << "subject: " << string(getSubjectDN()) << "\n"; + return os.str(); +} + +unsigned int +Certificate::getKeyUsage() const +{ + const CertificateExtendedInfo* impl = dynamic_cast(this); + if(impl) + { + return impl->getKeyUsage(); + } + return 0; +} + +unsigned int +Certificate::getExtendedKeyUsage() const +{ + const CertificateExtendedInfo* impl = dynamic_cast(this); + if(impl) + { + return impl->getExtendedKeyUsage(); + } + return 0; +} diff --git a/Sources/IceSSLCpp/ConnectionInfo.cpp b/Sources/IceSSLCpp/ConnectionInfo.cpp new file mode 100644 index 0000000..971bc2f --- /dev/null +++ b/Sources/IceSSLCpp/ConnectionInfo.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICESSL_API_EXPORTS +# define ICESSL_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +IceSSL::ConnectionInfo::~ConnectionInfo() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +IceSSL::ConnectionInfo::~ConnectionInfo() +{ +} + +/// \cond INTERNAL +ICESSL_API ::Ice::LocalObject* IceSSL::upCast(ConnectionInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceSSLCpp/ConnectionInfoF.cpp b/Sources/IceSSLCpp/ConnectionInfoF.cpp new file mode 100644 index 0000000..692d58d --- /dev/null +++ b/Sources/IceSSLCpp/ConnectionInfoF.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfoF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICESSL_API_EXPORTS +# define ICESSL_API_EXPORTS +#endif +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +#else // C++98 mapping + +namespace +{ + +} + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceSSLCpp/ConnectorI.cpp b/Sources/IceSSLCpp/ConnectorI.cpp new file mode 100644 index 0000000..1b5c2d5 --- /dev/null +++ b/Sources/IceSSLCpp/ConnectorI.cpp @@ -0,0 +1,102 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +IceInternal::TransceiverPtr +IceSSL::ConnectorI::connect() +{ + // + // The plug-in may not be initialized. + // + if(!_instance->initialized()) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: plug-in is not initialized"); + } + + return _instance->engine()->createTransceiver(_instance, _delegate->connect(), _host, false); +} + +Short +IceSSL::ConnectorI::type() const +{ + return _delegate->type(); +} + +string +IceSSL::ConnectorI::toString() const +{ + return _delegate->toString(); +} + +bool +IceSSL::ConnectorI::operator==(const IceInternal::Connector& r) const +{ + const ConnectorI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(_delegate != p->_delegate) + { + return false; + } + + return true; +} + +bool +IceSSL::ConnectorI::operator<(const IceInternal::Connector& r) const +{ + const ConnectorI* p = dynamic_cast(&r); + if(!p) + { + return type() < r.type(); + } + + if(this == p) + { + return false; + } + + if(_delegate < p->_delegate) + { + return true; + } + else if(p->_delegate < _delegate) + { + return false; + } + + return false; +} + +IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const IceInternal::ConnectorPtr& del, const string& h) : + _instance(instance), _delegate(del), _host(h) +{ +} + +IceSSL::ConnectorI::~ConnectorI() +{ +} diff --git a/Sources/IceSSLCpp/EndpointI.cpp b/Sources/IceSSLCpp/EndpointI.cpp new file mode 100644 index 0000000..f028aef --- /dev/null +++ b/Sources/IceSSLCpp/EndpointI.cpp @@ -0,0 +1,372 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +namespace +{ + +Ice::IPEndpointInfoPtr +getIPEndpointInfo(const Ice::EndpointInfoPtr& info) +{ + for(Ice::EndpointInfoPtr p = info; p; p = p->underlying) + { + Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p); + if(ipInfo) + { + return ipInfo; + } + } + return ICE_NULLPTR; +} + +} + +#ifndef ICE_CPP11_MAPPING +IceUtil::Shared* IceSSL::upCast(EndpointI* p) { return p; } +#endif + +IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del) : + _instance(instance), _delegate(del) +{ +} + +void +IceSSL::EndpointI::streamWriteImpl(Ice::OutputStream* stream) const +{ + _delegate->streamWriteImpl(stream); +} + +Ice::EndpointInfoPtr +IceSSL::EndpointI::getInfo() const ICE_NOEXCEPT +{ + EndpointInfoPtr info = ICE_MAKE_SHARED(IceInternal::InfoI, ICE_SHARED_FROM_CONST_THIS(EndpointI)); + info->underlying = _delegate->getInfo(); + info->compress = info->underlying->compress; + info->timeout = info->underlying->timeout; + return info; +} + +Ice::Short +IceSSL::EndpointI::type() const +{ + return _delegate->type(); +} + +const std::string& +IceSSL::EndpointI::protocol() const +{ + return _delegate->protocol(); +} + +Int +IceSSL::EndpointI::timeout() const +{ + return _delegate->timeout(); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointI::timeout(Int timeout) const +{ + if(timeout == _delegate->timeout()) + { + return ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->timeout(timeout)); + } +} + +const string& +IceSSL::EndpointI::connectionId() const +{ + return _delegate->connectionId(); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointI::connectionId(const string& connectionId) const +{ + if(connectionId == _delegate->connectionId()) + { + return ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->connectionId(connectionId)); + } +} + +bool +IceSSL::EndpointI::compress() const +{ + return _delegate->compress(); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointI::compress(bool compress) const +{ + if(compress == _delegate->compress()) + { + return ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->compress(compress)); + } +} + +bool +IceSSL::EndpointI::datagram() const +{ + return _delegate->datagram(); +} + +bool +IceSSL::EndpointI::secure() const +{ + return _delegate->secure(); +} + +IceInternal::TransceiverPtr +IceSSL::EndpointI::transceiver() const +{ + return 0; +} + +void +IceSSL::EndpointI::connectors_async(Ice::EndpointSelectionType selType, + const IceInternal::EndpointI_connectorsPtr& callback) const +{ + class CallbackI : public IceInternal::EndpointI_connectors + { + public: + + CallbackI(const IceInternal::EndpointI_connectorsPtr& callback, const InstancePtr& instance, + const string& host) : + _callback(callback), _instance(instance), _host(host) + { + } + + virtual void connectors(const vector& c) + { + vector connectors = c; + for(vector::iterator p = connectors.begin(); p != connectors.end(); ++p) + { + *p = new ConnectorI(_instance, *p, _host); + } + _callback->connectors(connectors); + } + + virtual void exception(const Ice::LocalException& ex) + { + _callback->exception(ex); + } + + private: + + const IceInternal::EndpointI_connectorsPtr _callback; + const InstancePtr _instance; + const string _host; + }; + + IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo()); + _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, info ? info->host : string())); +} + +IceInternal::AcceptorPtr +IceSSL::EndpointI::acceptor(const string& adapterName) const +{ + return new AcceptorI(ICE_SHARED_FROM_CONST_THIS(EndpointI), _instance, _delegate->acceptor(adapterName), adapterName); +} + +EndpointIPtr +IceSSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const +{ + if(delEndp.get() == _delegate.get()) + { + return ICE_DYNAMIC_CAST(EndpointI, ICE_SHARED_FROM_CONST_THIS(EndpointI)); + } + else + { + return ICE_MAKE_SHARED(EndpointI, _instance, delEndp); + } +} + +vector +IceSSL::EndpointI::expandIfWildcard() const +{ + vector endps = _delegate->expandIfWildcard(); + for(vector::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + *p = ICE_MAKE_SHARED(EndpointI, _instance, *p); + } + } + return endps; +} + +vector +IceSSL::EndpointI::expandHost(IceInternal::EndpointIPtr& publish) const +{ + vector endps = _delegate->expandHost(publish); + if(publish.get() == _delegate.get()) + { + publish = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else if(publish.get()) + { + publish = ICE_MAKE_SHARED(EndpointI, _instance, publish); + } + for(vector::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + *p = ICE_MAKE_SHARED(EndpointI, _instance, *p); + } + } + return endps; +} + +bool +IceSSL::EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const +{ + const EndpointI* endpointI = dynamic_cast(endpoint.get()); + if(!endpointI) + { + return false; + } + return _delegate->equivalent(endpointI->_delegate); +} + +Ice::Int +IceSSL::EndpointI::hash() const +{ + return _delegate->hash(); +} + +string +IceSSL::EndpointI::options() const +{ + return _delegate->options(); +} + +bool +#ifdef ICE_CPP11_MAPPING +IceSSL::EndpointI::operator==(const Ice::Endpoint& r) const +#else +IceSSL::EndpointI::operator==(const Ice::LocalObject& r) const +#endif +{ + const EndpointI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + if(!Ice::targetEqualTo(_delegate, p->_delegate)) + { + return false; + } + + return true; +} + +bool +#ifdef ICE_CPP11_MAPPING +IceSSL::EndpointI::operator<(const Ice::Endpoint& r) const +#else +IceSSL::EndpointI::operator<(const Ice::LocalObject& r) const +#endif +{ + const EndpointI* p = dynamic_cast(&r); + if(!p) + { + const IceInternal::EndpointI* e = dynamic_cast(&r); + if(!e) + { + return false; + } + return type() < e->type(); + } + + if(this == p) + { + return false; + } + + if(Ice::targetLess(_delegate, p->_delegate)) + { + return true; + } + else if (Ice::targetLess(p->_delegate, _delegate)) + { + return false; + } + + return false; +} + +bool +IceSSL::EndpointI::checkOption(const string& /*option*/, const string& /*argument*/, const string& /*endpoint*/) +{ + return false; +} + +IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance, Short type) : + IceInternal::EndpointFactoryWithUnderlying(instance, type), _sslInstance(instance.get()) +{ +} + +void +IceSSL::EndpointFactoryI::destroy() +{ + _sslInstance = 0; +} + +IceInternal::EndpointFactoryPtr +IceSSL::EndpointFactoryI::cloneWithUnderlying(const IceInternal::ProtocolInstancePtr& instance, Short underlying) const +{ + return new EndpointFactoryI(new Instance(_sslInstance->engine(), instance->type(), instance->protocol()), underlying); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointFactoryI::createWithUnderlying(const IceInternal::EndpointIPtr& underlying, vector&, bool) const +{ + return ICE_MAKE_SHARED(EndpointI, _sslInstance, underlying); +} + +IceInternal::EndpointIPtr +IceSSL::EndpointFactoryI::readWithUnderlying(const IceInternal::EndpointIPtr& underlying, Ice::InputStream*) const +{ + return ICE_MAKE_SHARED(EndpointI, _sslInstance, underlying); +} diff --git a/Sources/IceSSLCpp/EndpointInfo.cpp b/Sources/IceSSLCpp/EndpointInfo.cpp new file mode 100644 index 0000000..9f47398 --- /dev/null +++ b/Sources/IceSSLCpp/EndpointInfo.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef ICESSL_API_EXPORTS +# define ICESSL_API_EXPORTS +#endif +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of ... hides class member +#elif defined(__clang__) +# pragma clang diagnostic ignored "-Wshadow" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wshadow" +#endif + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace +{ + +} + +IceSSL::EndpointInfo::~EndpointInfo() +{ +} + +#else // C++98 mapping + +namespace +{ + +} + +IceSSL::EndpointInfo::~EndpointInfo() +{ +} + +/// \cond INTERNAL +ICESSL_API ::Ice::LocalObject* IceSSL::upCast(EndpointInfo* p) { return p; } +/// \endcond + +namespace Ice +{ +} + +#endif diff --git a/Sources/IceSSLCpp/Instance.cpp b/Sources/IceSSLCpp/Instance.cpp new file mode 100644 index 0000000..eedb94a --- /dev/null +++ b/Sources/IceSSLCpp/Instance.cpp @@ -0,0 +1,28 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +IceUtil::Shared* IceSSL::upCast(IceSSL::Instance* p) { return p; } + +IceSSL::Instance::Instance(const SSLEnginePtr& engine, Short type, const string& protocol) : + ProtocolInstance(engine->communicator(), type, protocol, true), + _engine(engine) +{ +} + +IceSSL::Instance::~Instance() +{ +} + +bool +IceSSL::Instance::initialized() const +{ + return _engine->initialized(); +} diff --git a/Sources/IceSSLCpp/PluginI.cpp b/Sources/IceSSLCpp/PluginI.cpp new file mode 100644 index 0000000..e5993b1 --- /dev/null +++ b/Sources/IceSSLCpp/PluginI.cpp @@ -0,0 +1,246 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceSSL; + +#ifndef ICE_CPP11_MAPPING +CertificateVerifier::~CertificateVerifier() +{ + // Out of line to avoid weak vtable +} + +PasswordPrompt::~PasswordPrompt() +{ + // Out of line to avoid weak vtable +} +#endif + +IceSSL::Plugin::~Plugin() +{ + // Out of line to avoid weak vtable +} + +// +// Plugin implementation. +// +PluginI::PluginI(const Ice::CommunicatorPtr& com, const SSLEnginePtr& engine) : + _engine(engine) +{ + // + // Register the endpoint factory. We have to do this now, rather + // than in initialize, because the communicator may need to + // interpret proxies before the plug-in is fully initialized. + // + InstancePtr instance = new Instance(_engine, SSLEndpointType, "ssl"); // SSL based on TCP + IceInternal::getProtocolPluginFacade(com)->addEndpointFactory(new EndpointFactoryI(instance, TCPEndpointType)); +} + +void +PluginI::initialize() +{ + _engine->initialize(); +} + +void +PluginI::destroy() +{ + _engine->destroy(); + _engine = 0; +} + +#ifdef ICE_CPP11_MAPPING +void +PluginI::setCertificateVerifier(std::function&)> verifier) +{ + if(verifier) + { + _engine->setCertificateVerifier(make_shared(std::move(verifier))); + } + else + { + _engine->setCertificateVerifier(nullptr); + } +} +#else +void +PluginI::setCertificateVerifier(const CertificateVerifierPtr& verifier) +{ + _engine->setCertificateVerifier(verifier); +} +#endif + +#ifdef ICE_CPP11_MAPPING +void +PluginI::setPasswordPrompt(std::function prompt) +{ + if(prompt) + { + _engine->setPasswordPrompt(make_shared(std::move(prompt))); + } + else + { + _engine->setPasswordPrompt(nullptr); + } +} +#else +void +PluginI::setPasswordPrompt(const PasswordPromptPtr& prompt) +{ + _engine->setPasswordPrompt(prompt); +} +#endif + +extern "C" +{ + +ICESSL_API Ice::Plugin* +createIceSSL(const CommunicatorPtr&, const string&, const StringSeq&); + +} + +namespace Ice +{ + +ICESSL_API void +registerIceSSL(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceSSL", createIceSSL, loadOnInitialize); +} + +} + +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICESSL_API void +ICEregisterIceSSL(bool loadOnInitialize) +{ + Ice::registerIceSSL(loadOnInitialize); +} + +IceSSL::TrustError +IceSSL::getTrustError(const IceSSL::ConnectionInfoPtr& info) +{ + ExtendedConnectionInfoPtr extendedInfo = ICE_DYNAMIC_CAST(ExtendedConnectionInfo, info); + if (extendedInfo) + { + return extendedInfo->errorCode; + } + return info->verified ? IceSSL::ICE_ENUM(TrustError, NoError) : IceSSL::ICE_ENUM(TrustError, UnknownTrustFailure); +} + +std::string +IceSSL::getTrustErrorDescription(TrustError error) +{ + switch(error) + { + case IceSSL::ICE_ENUM(TrustError, NoError): + { + return "no error"; + } + case IceSSL::ICE_ENUM(TrustError, ChainTooLong): + { + return "the certificate chain length is greater than the specified maximum depth"; + } + case IceSSL::ICE_ENUM(TrustError, HasExcludedNameConstraint): + { + return "the X509 chain is invalid because a certificate has excluded a name constraint"; + } + case IceSSL::ICE_ENUM(TrustError, HasNonDefinedNameConstraint): + { + return "the certificate has an undefined name constraint"; + } + case IceSSL::ICE_ENUM(TrustError, HasNonPermittedNameConstraint): + { + return "the certificate has a non permitted name constrain"; + } + case IceSSL::ICE_ENUM(TrustError, HasNonSupportedCriticalExtension): + { + return "the certificate does not support a critical extension"; + } + case IceSSL::ICE_ENUM(TrustError, HasNonSupportedNameConstraint): + { + return "the certificate does not have a supported name constraint or has a name constraint that " + "is unsupported"; + } + case IceSSL::ICE_ENUM(TrustError, HostNameMismatch): + { + return "a host name mismatch has occurred"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidBasicConstraints): + { + return "the X509 chain is invalid due to invalid basic constraints"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidExtension): + { + return "the X509 chain is invalid due to an invalid extension"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidNameConstraints): + { + return "the X509 chain is invalid due to invalid name constraints"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidPolicyConstraints): + { + return "the X509 chain is invalid due to invalid policy constraints"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidPurpose): + { + return "the supplied certificate cannot be used for the specified purpose"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidSignature): + { + return "the X509 chain is invalid due to an invalid certificate signature"; + } + case IceSSL::ICE_ENUM(TrustError, InvalidTime): + { + return "the X509 chain is not valid due to an invalid time value, such as a value that indicates an " + "expired certificate"; + } + case IceSSL::ICE_ENUM(TrustError, NotTrusted): + { + return "the certificate is explicitly distrusted"; + } + case IceSSL::ICE_ENUM(TrustError, PartialChain): + { + return "the X509 chain could not be built up to the root certificate"; + } + case IceSSL::ICE_ENUM(TrustError, RevocationStatusUnknown): + { + return "it is not possible to determine whether the certificate has been revoked"; + } + case IceSSL::ICE_ENUM(TrustError, Revoked): + { + return "the X509 chain is invalid due to a revoked certificate"; + } + case IceSSL::ICE_ENUM(TrustError, UntrustedRoot): + { + return "the X509 chain is invalid due to an untrusted root certificate"; + } + case IceSSL::ICE_ENUM(TrustError, UnknownTrustFailure): + { + return "unknown failure"; + } + } + assert(false); + return "unknown failure"; +} + +std::string +IceSSL::getHost(const IceSSL::ConnectionInfoPtr& info) +{ + ExtendedConnectionInfoPtr extendedInfo = ICE_DYNAMIC_CAST(ExtendedConnectionInfo, info); + return extendedInfo ? extendedInfo->host : ""; +} diff --git a/Sources/IceSSLCpp/RFC2253.cpp b/Sources/IceSSLCpp/RFC2253.cpp new file mode 100644 index 0000000..2c3e6a2 --- /dev/null +++ b/Sources/IceSSLCpp/RFC2253.cpp @@ -0,0 +1,490 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include +#include + +using namespace std; +using namespace IceSSL; + +namespace +{ + +// +// See RFC 2253 and RFC 1779. +// + +string special = ",=+<>#;"; +string hexvalid = "0123456789abcdefABCDEF"; + +} + +static char unescapeHex(const string&, size_t); +static pair parseNameComponent(const string&, size_t&); +static pair parseAttributeTypeAndValue(const string&, size_t&); +static string parseAttributeType(const string&, size_t&); +static string parseAttributeValue(const string&, size_t&); +static string parsePair(const string&, size_t&); +static string parseHexPair(const string&, size_t&, bool); +static void eatWhite(const string&, size_t&); + +RFC2253::RDNEntrySeq +RFC2253::parse(const string& data) +{ + RDNEntrySeq results; + RDNEntry current; + current.negate = false; + size_t pos = 0; + while(pos < data.size()) + { + eatWhite(data, pos); + if(pos < data.size() && data[pos] == '!') + { + if(!current.rdn.empty()) + { + throw ParseException(__FILE__, __LINE__, "negation symbol '!' must appear at start of list"); + } + ++pos; + current.negate = true; + } + current.rdn.push_back(parseNameComponent(data, pos)); + eatWhite(data, pos); + if(pos < data.size() && data[pos] == ',') + { + ++pos; + } + else if(pos < data.size() && data[pos] == ';') + { + ++pos; + results.push_back(current); + current.rdn.clear(); + current.negate = false; + } + else if(pos < data.size()) + { + throw ParseException(__FILE__, __LINE__, "expected ',' or ';' at `" + data.substr(pos) + "'"); + } + } + if(!current.rdn.empty()) + { + results.push_back(current); + } + + return results; +} + +RFC2253::RDNSeq +RFC2253::parseStrict(const string& data) +{ + RDNSeq results; + size_t pos = 0; + while(pos < data.size()) + { + results.push_back(parseNameComponent(data, pos)); + eatWhite(data, pos); + if(pos < data.size() && (data[pos] == ',' || data[pos] == ';')) + { + ++pos; + } + else if(pos < data.size()) + { + throw ParseException(__FILE__, __LINE__, "expected ',' or ';' at `" + data.substr(pos) + "'"); + } + } + return results; +} + +string +RFC2253::unescape(const string& data) +{ + if(data.size() == 0) + { + return data; + } + + if(data[0] == '"') + { + if(data[data.size() - 1] != '"') + { + throw ParseException(__FILE__, __LINE__, "unescape: missing \""); + } + + // + // Return the string without quotes. + // + return data.substr(1, data.size() - 2); + } + + // + // Unescape the entire string. + // + string result; + if(data[0] == '#') + { + size_t pos = 1; + while(pos < data.size()) + { + result += unescapeHex(data, pos); + pos += 2; + } + } + else + { + size_t pos = 0; + while(pos < data.size()) + { + if(data[pos] != '\\') + { + result += data[pos]; + ++pos; + } + else + { + ++pos; + if(pos >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "unescape: invalid escape sequence"); + } + if(special.find(data[pos]) != string::npos || data[pos] != '\\' || data[pos] != '"') + { + result += data[pos]; + ++pos; + } + else + { + result += unescapeHex(data, pos); + pos += 2; + } + } + } + } + + return result; +} + +static int +hexToInt(char v) +{ + if(v >= '0' && v <= '9') + { + return v - '0'; + } + if(v >= 'a' && v <= 'f') + { + return 10 + (v - 'a'); + } + if(v >= 'A' && v <= 'F') + { + return 10 + (v - 'A'); + } + throw ParseException(__FILE__, __LINE__, "unescape: invalid hex pair"); +} + +static char +unescapeHex(const string& data, size_t pos) +{ + assert(pos < data.size()); + if(pos + 2 >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "unescape: invalid hex pair"); + } + return static_cast(hexToInt(data[pos]) * 16 + hexToInt(data[pos + 1])); +} + +static pair +parseNameComponent(const string& data, size_t& pos) +{ + pair final = parseAttributeTypeAndValue(data, pos); + while(pos < data.size()) + { + eatWhite(data, pos); + if(pos < data.size() && data[pos] == '+') + { + ++pos; + } + else + { + break; + } + pair p = parseAttributeTypeAndValue(data, pos); + final.second += "+"; + final.second += p.first; + final.second += '='; + final.second += p.second; + } + return final; +} + +static pair +parseAttributeTypeAndValue(const string& data, size_t& pos) +{ + pair p; + p.first = parseAttributeType(data, pos); + eatWhite(data, pos); + + if(pos >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "invalid attribute type/value pair (unexpected end of data)"); + } + if(data[pos] != '=') + { + throw ParseException(__FILE__, __LINE__, "invalid attribute type/value pair (missing =)"); + } + ++pos; + p.second = parseAttributeValue(data, pos); + return p; +} + +static string +parseAttributeType(const string& data, size_t& pos) +{ + eatWhite(data, pos); + if(pos >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "invalid attribute type (expected end of data)"); + } + + string result; + + // + // RFC 1779. + // ::= 1*( ) | "OID." | "oid." + // ::= | "." + // RFC 2253: + // attributeType = (ALPHA 1*keychar) | oid + // keychar = ALPHA | DIGIT | "-" + // oid = 1*DIGIT *("." 1*DIGIT) + // + // In section 4 of RFC 2253 the document says: + // Implementations MUST allow an oid in the attribute type to be + // prefixed by one of the character strings "oid." or "OID.". + // + // Here we must also check for "oid." and "OID." before parsing + // according to the ALPHA KEYCHAR* rule. + // + // First the OID case. + // + if(IceUtilInternal::isDigit(data[pos]) || + (data.size() - pos >= 4 && (data.substr(pos, 4) == "oid." || data.substr(pos, 4) == "OID."))) + { + if(!IceUtilInternal::isDigit(data[pos])) + { + result += data.substr(pos, 4); + pos += 4; + } + + while(true) + { + // 1*DIGIT + while(pos < data.size() && IceUtilInternal::isDigit(data[pos])) + { + result += data[pos]; + ++pos; + } + // "." 1*DIGIT + if(pos < data.size() && data[pos] == '.') + { + result += data[pos]; + ++pos; + // 1*DIGIT must follow "." + if(pos < data.size() && !IceUtilInternal::isDigit(data[pos])) + { + throw ParseException(__FILE__, __LINE__, "invalid attribute type (expected end of data)"); + } + } + else + { + break; + } + } + } + else if(IceUtilInternal::isAlpha(data[pos])) + { + // + // The grammar is wrong in this case. It should be ALPHA + // KEYCHAR* otherwise it will not accept "O" as a valid + // attribute type. + // + result += data[pos]; + ++pos; + // 1* KEYCHAR + while(pos < data.size() && + (IceUtilInternal::isAlpha(data[pos]) || IceUtilInternal::isDigit(data[pos]) || data[pos] == '-')) + { + result += data[pos]; + ++pos; + } + } + else + { + throw ParseException(__FILE__, __LINE__, "invalid attribute type"); + } + return result; +} + +static string +parseAttributeValue(const string& data, size_t& pos) +{ + eatWhite(data, pos); + string result; + if(pos >= data.size()) + { + return result; + } + + // + // RFC 2253 + // # hexstring + // + if(data[pos] == '#') + { + result += data[pos]; + ++pos; + while(true) + { + string h = parseHexPair(data, pos, true); + if(h.size() == 0) + { + break; + } + result += h; + } + } + // + // RFC 2253 + // QUOTATION *( quotechar | pair ) QUOTATION ; only from v2 + // quotechar = + // + else if(data[pos] == '"') + { + result += data[pos]; + ++pos; + while(true) + { + if(pos >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "invalid attribute value (unexpected end of data)"); + } + // final terminating " + if(data[pos] == '"') + { + result += data[pos]; + ++pos; + break; + } + // any character except '\' + else if(data[pos] != '\\') + { + result += data[pos]; + ++pos; + } + // pair '\' + else + { + result += parsePair(data, pos); + } + } + } + // + // RFC 2253 + // * (stringchar | pair) + // stringchar = + // + else + { + while(pos < data.size()) + { + if(data[pos] == '\\') + { + result += parsePair(data, pos); + } + else if(special.find(data[pos]) == string::npos && data[pos] != '"') + { + result += data[pos]; + ++pos; + } + else + { + break; + } + } + } + return result; +} + +// +// RFC2253: +// pair = "\" ( special | "\" | QUOTATION | hexpair ) +// +static string +parsePair(const string& data, size_t& pos) +{ + string result; + + assert(data[pos] == '\\'); + result += data[pos]; + ++pos; + + if(pos >= data.size()) + { + throw ParseException(__FILE__, __LINE__, "invalid escape format (unexpected end of data)"); + } + + if(special.find(data[pos]) != string::npos || data[pos] != '\\' || data[pos] != '"') + { + result += data[pos]; + ++pos; + return result; + } + return parseHexPair(data, pos, false); +} + +// +// RFC 2253 +// hexpair = hexchar hexchar +// +static string +parseHexPair(const string& data, size_t& pos, bool allowEmpty) +{ + string result; + if(pos < data.size() && hexvalid.find(data[pos]) != string::npos) + { + result += data[pos]; + ++pos; + } + if(pos < data.size() && hexvalid.find(data[pos]) != string::npos) + { + result += data[pos]; + ++pos; + } + if(result.size() != 2) + { + if(allowEmpty && result.size() == 0) + { + return result; + } + throw ParseException(__FILE__, __LINE__, "invalid hex format"); + } + return result; +} + +// +// RFC 2253: +// +// Implementations MUST allow for space (' ' ASCII 32) characters to be +// present between name-component and ',', between attributeTypeAndValue +// and '+', between attributeType and '=', and between '=' and +// attributeValue. These space characters are ignored when parsing. +// +static void +eatWhite(const string& data, size_t& pos) +{ + while(pos < data.size() && data[pos] == ' ') + { + ++pos; + } +} diff --git a/Sources/IceSSLCpp/SSLEngine.cpp b/Sources/IceSSLCpp/SSLEngine.cpp new file mode 100644 index 0000000..6a04294 --- /dev/null +++ b/Sources/IceSSLCpp/SSLEngine.cpp @@ -0,0 +1,313 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using namespace Ice; +using namespace IceUtil; +using namespace IceSSL; + +IceUtil::Shared* IceSSL::upCast(IceSSL::SSLEngine* p) { return p; } + +IceSSL::SSLEngine::SSLEngine(const Ice::CommunicatorPtr& communicator) : + _initialized(false), + _communicator(communicator), + _logger(communicator->getLogger()), + _trustManager(new TrustManager(communicator)), + _revocationCheckCacheOnly(false), + _revocationCheck(0) +{ +} + +IceSSL::CertificateVerifierPtr +IceSSL::SSLEngine::getCertificateVerifier() const +{ + return _verifier; +} + +void +IceSSL::SSLEngine::setCertificateVerifier(const IceSSL::CertificateVerifierPtr& verifier) +{ + _verifier = verifier; +} + +IceSSL::PasswordPromptPtr +IceSSL::SSLEngine::getPasswordPrompt() const +{ + return _prompt; +} + +void +IceSSL::SSLEngine::setPasswordPrompt(const IceSSL::PasswordPromptPtr& prompt) +{ + _prompt = prompt; +} + +string +IceSSL::SSLEngine::password(bool /*encrypting*/) +{ + if(_prompt) + { + try + { + return _prompt->getPassword(); + } + catch(...) + { + // + // Don't allow exceptions to cross an OpenSSL boundary. + // + return string(); + } + } + else + { + return _password; + } +} + +bool +IceSSL::SSLEngine::initialized() const +{ + Mutex::Lock lock(_mutex); + return _initialized; +} + +string +IceSSL::SSLEngine::getPassword() const +{ + return _password; +} + +void +IceSSL::SSLEngine::setPassword(const std::string& password) +{ + _password = password; +} + +void +IceSSL::SSLEngine::initialize() +{ + const string propPrefix = "IceSSL."; + const PropertiesPtr properties = communicator()->getProperties(); + + // + // CheckCertName determines whether we compare the name in a peer's + // certificate against its hostname. + // + _checkCertName = properties->getPropertyAsIntWithDefault(propPrefix + "CheckCertName", 0) > 0; + + // + // CheckCertName > 1 enables SNI, the SNI extension applies to client connections, + // indicating the hostname to the server (must be DNS hostname, not an IP address). + // + _serverNameIndication = properties->getPropertyAsIntWithDefault(propPrefix + "CheckCertName", 0) > 1; + + // + // VerifyDepthMax establishes the maximum length of a peer's certificate + // chain, including the peer's certificate. A value of 0 means there is + // no maximum. + // + _verifyDepthMax = properties->getPropertyAsIntWithDefault(propPrefix + "VerifyDepthMax", 3); + + // + // VerifyPeer determines whether certificate validation failures abort a connection. + // + _verifyPeer = properties->getPropertyAsIntWithDefault(propPrefix + "VerifyPeer", 2); + + if(_verifyPeer < 0 || _verifyPeer > 2) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value for " + propPrefix + + "VerifyPeer"); + } + + _securityTraceLevel = properties->getPropertyAsInt("IceSSL.Trace.Security"); + _securityTraceCategory = "Security"; + + const_cast(_revocationCheckCacheOnly) = + properties->getPropertyAsIntWithDefault("IceSSL.RevocationCheckCacheOnly", 1) > 0; + const_cast(_revocationCheck) = + properties->getPropertyAsIntWithDefault("IceSSL.RevocationCheck", 0); +} + +void +IceSSL::SSLEngine::verifyPeerCertName(const string& address, const ConnectionInfoPtr& info) +{ + // + // For an outgoing connection, we compare the proxy address (if any) against + // fields in the server's certificate (if any). + // + if(_checkCertName && !info->certs.empty() && !address.empty()) + { + const CertificatePtr cert = info->certs[0]; + + // + // Extract the IP addresses and the DNS names from the subject + // alternative names. + // + vector > subjectAltNames = cert->getSubjectAlternativeNames(); + vector ipAddresses; + vector dnsNames; + for(vector >::const_iterator p = subjectAltNames.begin(); p != subjectAltNames.end(); ++p) + { + if(p->first == AltNAmeIP) + { + ipAddresses.push_back(IceUtilInternal::toLower(p->second)); + } + else if(p->first == AltNameDNS) + { + dnsNames.push_back(IceUtilInternal::toLower(p->second)); + } + } + + bool certNameOK = false; + string addrLower = IceUtilInternal::toLower(address); + bool isIpAddress = IceInternal::isIpAddress(address); + + // + // If address is an IP address, compare it to the subject alternative names IP adddress + // + if(isIpAddress) + { + certNameOK = find(ipAddresses.begin(), ipAddresses.end(), addrLower) != ipAddresses.end(); + } + else + { + // + // If subjectAlt is empty compare it ot the subject CN, othewise + // compare it to the to the subject alt name dnsNames + // + if(dnsNames.empty()) + { + DistinguishedName d = cert->getSubjectDN(); + string dn = IceUtilInternal::toLower(string(d)); + string cn = "cn=" + addrLower; + string::size_type pos = dn.find(cn); + if(pos != string::npos) + { + // + // Ensure we match the entire common name. + // + certNameOK = (pos + cn.size() == dn.size()) || (dn[pos + cn.size()] == ','); + } + } + else + { + certNameOK = find(dnsNames.begin(), dnsNames.end(), addrLower) != dnsNames.end(); + } + } + + if(!certNameOK) + { + ostringstream ostr; + ostr << "IceSSL: "; + if(_verifyPeer > 0) + { + ostr << "ignoring "; + } + ostr << "certificate verification failure " << (isIpAddress ? "IP address mismatch" : "Hostname mismatch"); + string msg = ostr.str(); + if(_securityTraceLevel >= 1) + { + Trace out(_logger, _securityTraceCategory); + out << msg; + } + throw SecurityException(__FILE__, __LINE__, msg); + } + } +} + +void +IceSSL::SSLEngine::verifyPeer(const string& /*address*/, const ConnectionInfoPtr& info, const string& desc) +{ + const CertificateVerifierPtr verifier = getCertificateVerifier(); + if(_verifyDepthMax > 0 && static_cast(info->certs.size()) > _verifyDepthMax) + { + ostringstream ostr; + ostr << (info->incoming ? "incoming" : "outgoing") << " connection rejected:\n" + << "length of peer's certificate chain (" << info->certs.size() << ") exceeds maximum of " + << _verifyDepthMax; + string msg = ostr.str(); + if(_securityTraceLevel >= 1) + { + _logger->trace(_securityTraceCategory, msg + "\n" + desc); + } + throw SecurityException(__FILE__, __LINE__, msg); + } + + if(!_trustManager->verify(info, desc)) + { + string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by trust manager"; + if(_securityTraceLevel >= 1) + { + _logger->trace(_securityTraceCategory, msg + "\n" + desc); + } + throw SecurityException(__FILE__, __LINE__, msg); + } + + if(verifier && !verifier->verify(info)) + { + string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier"; + if(_securityTraceLevel >= 1) + { + _logger->trace(_securityTraceCategory, msg + "\n" + desc); + } + throw SecurityException(__FILE__, __LINE__, msg); + } +} + +bool +IceSSL::SSLEngine::getCheckCertName() const +{ + return _checkCertName; +} + +bool +IceSSL::SSLEngine::getServerNameIndication() const +{ + return _serverNameIndication; +} + +int +IceSSL::SSLEngine::getVerifyPeer() const +{ + return _verifyPeer; +} + +int +IceSSL::SSLEngine::securityTraceLevel() const +{ + return _securityTraceLevel; +} + +std::string +IceSSL::SSLEngine::securityTraceCategory() const +{ + return _securityTraceCategory; +} + +bool +IceSSL::SSLEngine::getRevocationCheckCacheOnly() const +{ + return _revocationCheckCacheOnly; +} + +int +IceSSL::SSLEngine::getRevocationCheck() const +{ + return _revocationCheck; +} diff --git a/Sources/IceSSLCpp/SecureTransportCertificateI.cpp b/Sources/IceSSLCpp/SecureTransportCertificateI.cpp new file mode 100644 index 0000000..7d3cd6c --- /dev/null +++ b/Sources/IceSSLCpp/SecureTransportCertificateI.cpp @@ -0,0 +1,999 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +// +// Disable deprecation warnings for SecCertificateCopyNormalizedIssuerContent and +// SecCertificateCopyNormalizedSubjectContent +// +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace Ice; +using namespace IceInternal; +using namespace IceSSL; +using namespace IceSSL::SecureTransport; + +using namespace std; + +namespace +{ + +static unsigned char _ekuAnyKeyUsage[4] = {0x55, 0x1d, 0x25, 0x00}; +static unsigned char _ekuServerAuthentication[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01}; +static unsigned char _ekuClientAuthentication[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02}; +static unsigned char _ekuCodeSigning[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03}; +static unsigned char _ekuEmailProtection[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04}; +static unsigned char _ekuTimeStamping[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08}; +static unsigned char _ekuOCSPSigning[8] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09}; + +static CFDataRef ekuAnyKeyUsage = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuAnyKeyUsage, 4, kCFAllocatorNull); +static CFDataRef ekuServerAuthentication = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuServerAuthentication, 8, kCFAllocatorNull); +static CFDataRef ekuClientAuthentication = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuClientAuthentication, 8, kCFAllocatorNull); +static CFDataRef ekuCodeSigning = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuCodeSigning, 8, kCFAllocatorNull); +static CFDataRef ekuEmailProtection = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuEmailProtection, 8, kCFAllocatorNull); +static CFDataRef ekuTimeStamping = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuTimeStamping, 8, kCFAllocatorNull); +static CFDataRef ekuOCSPSigning = + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ekuOCSPSigning, 8, kCFAllocatorNull); + +string +certificateOIDAlias(const string& name) +{ + for(int i = 0; i < certificateOIDSSize; ++i) + { + const CertificateOID* certificateOID = &certificateOIDS[i]; + assert(certificateOID); + if(name == certificateOID->name) + { + return certificateOID->alias; + } + } + return name; +} + +string +escapeX509Name(const string& name) +{ + ostringstream os; + for(string::const_iterator i = name.begin(); i != name.end(); ++i) + { + switch(*i) + { + case ',': + case '=': + case '+': + case '<': + case '>': + case '#': + case ';': + { + os << '\\'; + } + default: + { + break; + } + } + os << *i; + } + return os.str(); +} + +#ifdef ICE_USE_SECURE_TRANSPORT_IOS +// +// ASN1Parser to pase the subject/issuer ASN.1 DER encoded attributes on iOS. +// +class ASN1Parser +{ +public: + + ASN1Parser(CFDataRef data) : + _data(CFDataGetBytePtr(data)), + _length(static_cast(CFDataGetLength(data))), + _p(_data), + _next(0) + { + } + + list > + parse() + { + list > rdns; + while(_p < _data + _length) + { + switch(parseByte()) + { + case 0x06: // OID + { + _rdn.first = parseOID(); + break; + } + case 0x12: // NumericString + case 0x13: // PrintableString + case 0x0C: // UTF8String + case 0x16: // IA5String + { + _rdn.second = escapeX509Name(parseUTF8String()); + break; + } + case 0x30: // SEQUENCE + case 0x31: // SET + { + int length = parseLength(0); + _next = _p + length; + if(_next > _data + _length) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + break; + } + default: + { + // Unsupported tag, skip the SET. + if(!_next) + { + return rdns; + } + _p = _next; + _next = 0; + break; + } + } + if(_p == _next) + { + rdns.push_back(_rdn); + } + } + return rdns; + } + + string + parseOID() + { + int length = parseLength(1); + ostringstream oid; + unsigned char c = parseByte(); + oid << c / 40 << "." << c % 40; + while(--length > 0) + { + if((*_p & 0x80) == 0) + { + oid << "." << static_cast(parseByte()); + } + else + { + uint64_t result = (uint64_t)(*_p & 127); + while(parseByte() & 128) + { + result = (result << 7) | (uint64_t)(*_p & 127); + --length; + } + oid << "." << result; + } + } + return certificateOIDAlias(oid.str()); + } + + string + parseUTF8String() + { + int length = parseLength(0); + string v(reinterpret_cast(_p), static_cast(length)); + _p += length; + return v; + } + + int + parseLength(int required) + { + int length = 0; + if((*_p & 0x80) == 0) + { + length = static_cast(parseByte()); + } + else + { + int nbytes = static_cast(parseByte()); + for(int i = 0; i < nbytes; ++i) + { + length = length * 256 + parseByte(); + } + } + if((required > 0 && length < required) || (_p + length > _data + _length)) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + return length; + } + + unsigned char + parseByte() + { + if(_p >= _data + _length) + { + throw CertificateEncodingException(__FILE__, __LINE__, "invalid length"); + } + unsigned char b = *_p++; + return b; + } + +private: + + const unsigned char* _data; + const size_t _length; + const unsigned char* _p; + const unsigned char* _next; + pair _rdn; + list > _rdns; +}; + +#endif + +class SecureTransportCertificateI ICE_FINAL : public IceSSL::SecureTransport::Certificate, + public IceSSL::CertificateI, + public IceSSL::CertificateExtendedInfo +{ +public: + + SecureTransportCertificateI(SecCertificateRef); + + virtual bool operator==(const IceSSL::Certificate&) const; + + virtual vector getAuthorityKeyIdentifier() const; + virtual vector getSubjectKeyIdentifier() const; + virtual bool verify(const IceSSL::CertificatePtr&) const; + virtual string encode() const; + +#ifdef ICE_CPP11_MAPPING + virtual chrono::system_clock::time_point getNotAfter() const; + virtual chrono::system_clock::time_point getNotBefore() const; +#else + virtual IceUtil::Time getNotAfter() const; + virtual IceUtil::Time getNotBefore() const; +#endif + + virtual string getSerialNumber() const; + virtual DistinguishedName getIssuerDN() const; + virtual vector > getIssuerAlternativeNames() const; + virtual DistinguishedName getSubjectDN() const; + virtual vector > getSubjectAlternativeNames() const; + virtual int getVersion() const; + virtual SecCertificateRef getCert() const; + virtual unsigned int getKeyUsage() const; + virtual unsigned int getExtendedKeyUsage() const; + +private: + + IceInternal::UniqueRef _cert; + +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + void initializeAttributes() const; + + mutable IceInternal::UniqueRef _subject; + mutable IceInternal::UniqueRef _issuer; + mutable std::string _serial; + mutable int _version; +#endif +}; + +#ifndef ICE_USE_SECURE_TRANSPORT_IOS + +// +// Map alternative name alias to its types. +// +const char* certificateAlternativeNameTypes[] = {"", "Email Address", "DNS Name", "", "Directory Name", "", "URI", + "IP Address"}; +const int certificateAlternativeNameTypesSize = sizeof(certificateAlternativeNameTypes) / sizeof(char*); + +int +certificateAlternativeNameType(const string& alias) +{ + if(!alias.empty()) + { + for(int i = 0; i < certificateAlternativeNameTypesSize; ++i) + { + if(alias == certificateAlternativeNameTypes[i]) + { + return i; + } + } + } + return -1; // Not supported +} + +DistinguishedName +getX509Name(SecCertificateRef cert, CFTypeRef key) +{ + assert(key == kSecOIDX509V1IssuerName || key == kSecOIDX509V1SubjectName); + list > rdnPairs; + UniqueRef property(getCertificateProperty(cert, key)); + if(property) + { + CFArrayRef dn = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + CFIndex size = CFArrayGetCount(dn); + for(CFIndex i = 0; i < size; ++i) + { + CFDictionaryRef dict = static_cast(CFArrayGetValueAtIndex(dn, i)); + rdnPairs.push_front(make_pair( + certificateOIDAlias( + fromCFString((static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyLabel))))), + escapeX509Name( + fromCFString(static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyValue)))))); + } + } + return DistinguishedName(rdnPairs); +} + +vector > +getX509AltName(SecCertificateRef cert, CFTypeRef key) +{ + assert(key == kSecOIDIssuerAltName || key == kSecOIDSubjectAltName); + UniqueRef property(getCertificateProperty(cert, key)); + + vector > pairs; + if(property) + { + CFArrayRef names = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + CFIndex size = CFArrayGetCount(names); + + for(CFIndex i = 0; i < size; ++i) + { + CFDictionaryRef dict = static_cast(CFArrayGetValueAtIndex(names, i)); + + int type = certificateAlternativeNameType( + fromCFString(static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyLabel)))); + if(type != -1) + { + CFStringRef v = static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyValue)); + CFStringRef t = static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyType)); + if(CFEqual(t, kSecPropertyTypeString) || CFEqual(t, kSecPropertyTypeTitle)) + { + pairs.push_back(make_pair(type, fromCFString(v))); + } + else if(CFEqual(t, kSecPropertyTypeURL)) + { + pairs.push_back(make_pair(type, fromCFString(CFURLGetString((CFURLRef)v)))); + } + else if(CFEqual(t, kSecPropertyTypeSection)) + { + CFArrayRef section = (CFArrayRef)v; + ostringstream os; + for(CFIndex j = 0, count = CFArrayGetCount(section); j < count;) + { + CFDictionaryRef d = (CFDictionaryRef)CFArrayGetValueAtIndex(section, j); + + CFStringRef sectionLabel = static_cast(CFDictionaryGetValue(d, kSecPropertyKeyLabel)); + CFStringRef sectionValue = static_cast(CFDictionaryGetValue(d, kSecPropertyKeyValue)); + + os << certificateOIDAlias(fromCFString(sectionLabel)) << "=" << fromCFString(sectionValue); + if(++j < count) + { + os << ","; + } + } + pairs.push_back(make_pair(type, os.str())); + } + } + } + } + return pairs; +} + +#ifdef ICE_CPP11_MAPPING +chrono::system_clock::time_point +#else +IceUtil::Time +#endif +getX509Date(SecCertificateRef cert, CFTypeRef key) +{ + assert(key == kSecOIDX509V1ValidityNotAfter || key == kSecOIDX509V1ValidityNotBefore); + UniqueRef property(getCertificateProperty(cert, key)); + CFAbsoluteTime seconds = 0; + if(property) + { + CFNumberRef date = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + CFNumberGetValue(date, kCFNumberDoubleType, &seconds); + } + + IceUtil::Time time = IceUtil::Time::secondsDouble(kCFAbsoluteTimeIntervalSince1970 + seconds); + +#ifdef ICE_CPP11_MAPPING + return chrono::system_clock::time_point(chrono::microseconds(time.toMicroSeconds())); +#else + return time; +#endif +} + +string +getX509String(SecCertificateRef cert, CFTypeRef key) +{ + assert(key == kSecOIDX509V1SerialNumber || key == kSecOIDX509V1Version); + UniqueRef property(getCertificateProperty(cert, key)); + return property ? + fromCFString(static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue))) : ""; +} +#endif + +} // end anonymous namespace + +SecureTransportCertificateI::SecureTransportCertificateI(SecCertificateRef cert) : _cert(cert) +{ + if(!_cert) + { +#ifdef ICE_CPP11_MAPPING + throw invalid_argument("Invalid certificate reference"); +#else + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Invalid certificate reference"); +#endif + } +} + +bool +SecureTransportCertificateI::operator==(const IceSSL::Certificate& r) const +{ + const SecureTransportCertificateI* p = dynamic_cast(&r); + if(!p) + { + return false; + } + return CFEqual(_cert.get(), p->_cert.get()); +} + +vector +SecureTransportCertificateI::getAuthorityKeyIdentifier() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + vector keyid; + + UniqueRef property(getCertificateProperty(_cert.get(), kSecOIDAuthorityKeyIdentifier)); + if(property) + { + CFTypeRef type = 0; + CFTypeRef value = 0; + if(CFDictionaryGetValueIfPresent(property.get(), kSecPropertyKeyType, &type)) + { + if(CFEqual(type, kSecPropertyTypeSection)) + { + if(CFDictionaryGetValueIfPresent(property.get(), kSecPropertyKeyValue, &value)) + { + if(CFArrayGetCount(static_cast(value)) >= 0) + { + value = CFArrayGetValueAtIndex(static_cast(value), 1); + type = CFDictionaryGetValue(static_cast(value), kSecPropertyKeyType); + } + } + } + + if(CFEqual(type, kSecPropertyTypeData)) + { + CFDataRef data = static_cast( + CFDictionaryGetValue(static_cast(value), kSecPropertyKeyValue)); + keyid.resize(static_cast(CFDataGetLength(data))); + memcpy(&keyid[0], CFDataGetBytePtr(data), static_cast(CFDataGetLength(data))); + } + } + } + return keyid; +#endif +} + +vector +SecureTransportCertificateI::getSubjectKeyIdentifier() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + vector keyid; + UniqueRef property(getCertificateProperty(_cert.get(), kSecOIDSubjectKeyIdentifier)); + if(property) + { + CFTypeRef type = 0; + CFTypeRef value = 0; + if(CFDictionaryGetValueIfPresent(property.get(), kSecPropertyKeyType, &type)) + { + if(CFEqual(type, kSecPropertyTypeSection)) + { + if(CFDictionaryGetValueIfPresent(property.get(), kSecPropertyKeyValue, &value)) + { + if(CFArrayGetCount(static_cast(value)) >= 0) + { + value = CFArrayGetValueAtIndex(static_cast(value), 1); + type = CFDictionaryGetValue(static_cast(value), kSecPropertyKeyType); + } + } + } + + if(CFEqual(type, kSecPropertyTypeData)) + { + CFDataRef data = static_cast( + CFDictionaryGetValue(static_cast(value), kSecPropertyKeyValue)); + keyid.resize(static_cast(CFDataGetLength(data))); + memcpy(&keyid[0], CFDataGetBytePtr(data), static_cast(CFDataGetLength(data))); + } + } + } + return keyid; +#endif +} + +bool +SecureTransportCertificateI::verify(const IceSSL::CertificatePtr& cert) const +{ + bool valid = false; + SecureTransportCertificateI* c = dynamic_cast(cert.get()); + if(c) + { + // + // We first check if the given certificate subject match our certificate + // issuer. Otherwhise when checking a certificate against itself + // SecTrustEvaluate always returns it is valid. + // +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + initializeAttributes(); + c->initializeAttributes(); + valid = CFEqual(_issuer.get(), c->_subject.get()); +#else // macOS + UniqueRef error; + UniqueRef issuer(SecCertificateCopyNormalizedIssuerContent(_cert.get(), &error.get())); + if(error) + { + throw CertificateEncodingException(__FILE__, __LINE__, "certificate error:\n" + sslErrorToString(error.get())); + } + UniqueRef subject(SecCertificateCopyNormalizedSubjectContent(c->getCert(), &error.get())); + if(error) + { + throw CertificateEncodingException(__FILE__, __LINE__, "certificate error:\n" + sslErrorToString(error.get())); + } + + // + // The certificate issuer must match the CA subject. + // + valid = CFEqual(issuer.get(), subject.get()); +#endif + if(valid) + { + UniqueRef policy(SecPolicyCreateBasicX509()); + UniqueRef trust; + OSStatus err = 0; + if((err = SecTrustCreateWithCertificates(_cert.get(), policy.get(), &trust.get()))) + { + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + + SecCertificateRef certs[1] = { c->getCert() }; + UniqueRef anchorCertificates( + CFArrayCreate(kCFAllocatorDefault, (const void**)&certs, 1, &kCFTypeArrayCallBacks)); + if((err = SecTrustSetAnchorCertificates(trust.get(), anchorCertificates.get()))) + { + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + + SecTrustResultType trustResult = kSecTrustResultInvalid; + if((err = SecTrustEvaluate(trust.get(), &trustResult))) + { + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + + valid = trustResult == kSecTrustResultUnspecified; + } + } + return valid; +} + +string +SecureTransportCertificateI::encode() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + UniqueRef cert(SecCertificateCopyData(_cert.get())); + vector data(CFDataGetBytePtr(cert.get()), CFDataGetBytePtr(cert.get()) + CFDataGetLength(cert.get())); + ostringstream os; + os << "-----BEGIN CERTIFICATE-----\n"; + os << IceInternal::Base64::encode(data); + os << "\n-----END CERTIFICATE-----\n"; + return os.str(); +#else // macOS + UniqueRef exported; + OSStatus err = SecItemExport(_cert.get(), kSecFormatPEMSequence, kSecItemPemArmour, 0, &exported.get()); + if(err != noErr) + { + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + return string(reinterpret_cast(CFDataGetBytePtr(exported.get())), + static_cast(CFDataGetLength(exported.get()))); +#endif +} + +#ifdef ICE_CPP11_MAPPING +chrono::system_clock::time_point +#else +IceUtil::Time +#endif +SecureTransportCertificateI::getNotAfter() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + return getX509Date(_cert.get(), kSecOIDX509V1ValidityNotAfter); +#endif +} + +#ifdef ICE_CPP11_MAPPING +chrono::system_clock::time_point +#else +IceUtil::Time +#endif +SecureTransportCertificateI::getNotBefore() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + return getX509Date(_cert.get(), kSecOIDX509V1ValidityNotBefore); +#endif +} + +string +SecureTransportCertificateI::getSerialNumber() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + initializeAttributes(); + return _serial; +#else // macOS + return getX509String(_cert.get(), kSecOIDX509V1SerialNumber); +#endif +} + +DistinguishedName +SecureTransportCertificateI::getIssuerDN() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + initializeAttributes(); + return _issuer ? DistinguishedName(ASN1Parser(_issuer.get()).parse()) : DistinguishedName(""); +#else // macOS + return getX509Name(_cert.get(), kSecOIDX509V1IssuerName); +#endif +} + +vector > +SecureTransportCertificateI::getIssuerAlternativeNames() const +{ +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + throw FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + return getX509AltName(_cert.get(), kSecOIDIssuerAltName); +#endif +} + +DistinguishedName +SecureTransportCertificateI::getSubjectDN() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + initializeAttributes(); + if(_subject) + { + return DistinguishedName(ASN1Parser(_subject.get()).parse()); + } + else + { + UniqueRef subjectSummary(SecCertificateCopySubjectSummary(_cert.get())); + return DistinguishedName("CN=" + fromCFString(subjectSummary.get())); + } +#else // macOS + return getX509Name(_cert.get(), kSecOIDX509V1SubjectName); +#endif +} + +vector > +SecureTransportCertificateI::getSubjectAlternativeNames() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw FeatureNotSupportedException(__FILE__, __LINE__); +#else // macOS + return getX509AltName(_cert.get(), kSecOIDSubjectAltName); +#endif +} + +int +SecureTransportCertificateI::getVersion() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + initializeAttributes(); + return _version; +#else // macOS + return atoi(getX509String(_cert.get(), kSecOIDX509V1Version).c_str()) - 1; +#endif +} + +SecCertificateRef +SecureTransportCertificateI::getCert() const +{ + return _cert.get(); +} + +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + +IceUtil::Mutex* globalMutex = 0; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +void +SecureTransportCertificateI::initializeAttributes() const +{ + // + // We need to temporarily add the certificate to the keychain in order to + // retrieve its attributes. Unfortunately kSecMatchItemList doesn't work + // on iOS. We make sure only one thread adds/removes a cert at a time here. + // + IceUtilInternal::MutexPtrLock lock(globalMutex); + + if(_subject) + { + return; + } + + UniqueRef query( + CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecValueRef, _cert.get()); + CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue); + + UniqueRef attributes(0); + OSStatus err; + if((err = SecItemAdd(query.get(), reinterpret_cast(&attributes.get()))) == errSecDuplicateItem) + { + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + err = SecItemCopyMatching(query.get(), reinterpret_cast(&attributes.get())); + } + else + { + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, _cert.get()); + err = SecItemDelete(query.get()); + } + + if(err != noErr) + { + _subject.reset(0); + _issuer.reset(0); + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + + _subject.retain(static_cast(CFDictionaryGetValue(attributes.get(), kSecAttrSubject))); + _issuer.retain(static_cast(CFDictionaryGetValue(attributes.get(), kSecAttrIssuer))); + CFDataRef serial = static_cast(CFDictionaryGetValue(attributes.get(), kSecAttrSerialNumber)); + ostringstream os; + for(int i = 0; i < CFDataGetLength(serial); ++i) + { + int c = static_cast(CFDataGetBytePtr(serial)[i]); + if(i) + { + os << ' '; + } + os.fill('0'); + os.width(2); + os << hex << c; + } + _serial = os.str(); + CFNumberRef version = static_cast(CFDictionaryGetValue(attributes.get(), kSecAttrCertificateType)); + if(!CFNumberGetValue(version, kCFNumberIntType, &_version)) + { + _version = -1; + } +} +#endif + +unsigned int +SecureTransportCertificateI::getKeyUsage() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else + unsigned int keyUsage = 0; + UniqueRef property(getCertificateProperty(_cert.get(), kSecOIDKeyUsage)); + if(property) + { + CFNumberRef value = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + if(value) + { + unsigned int usageBits = 0; + CFNumberGetValue(value, kCFNumberSInt32Type, &usageBits); + if(usageBits & kSecKeyUsageDigitalSignature) + { + keyUsage |= KEY_USAGE_DIGITAL_SIGNATURE; + } + if(usageBits & kSecKeyUsageNonRepudiation) + { + keyUsage |= KEY_USAGE_NON_REPUDIATION; + } + if(usageBits & kSecKeyUsageKeyEncipherment) + { + keyUsage |= KEY_USAGE_KEY_ENCIPHERMENT; + } + if(usageBits & kSecKeyUsageDataEncipherment) + { + keyUsage |= KEY_USAGE_DATA_ENCIPHERMENT; + } + if(usageBits & kSecKeyUsageKeyAgreement) + { + keyUsage |= KEY_USAGE_KEY_AGREEMENT; + } + if(usageBits & kSecKeyUsageKeyCertSign) + { + keyUsage |= KEY_USAGE_KEY_CERT_SIGN; + } + if(usageBits & kSecKeyUsageCRLSign) + { + keyUsage |= KEY_USAGE_CRL_SIGN; + } + if(usageBits & kSecKeyUsageEncipherOnly) + { + keyUsage |= KEY_USAGE_ENCIPHER_ONLY; + } + if(usageBits & kSecKeyUsageDecipherOnly) + { + keyUsage |= KEY_USAGE_DECIPHER_ONLY; + } + } + } + return keyUsage; +#endif +} + +unsigned int +SecureTransportCertificateI::getExtendedKeyUsage() const +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__); +#else + unsigned int extendedKeyUsage = 0; + UniqueRef property(getCertificateProperty(_cert.get(), kSecOIDExtendedKeyUsage)); + if(property) + { + CFArrayRef usages = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + if(usages) + { + long size = CFArrayGetCount(usages); + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuAnyKeyUsage)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_ANY_KEY_USAGE; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuServerAuthentication)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_SERVER_AUTH; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuClientAuthentication)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_CLIENT_AUTH; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuCodeSigning)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_CODE_SIGNING; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuEmailProtection)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_EMAIL_PROTECTION; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuTimeStamping)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_TIME_STAMPING; + } + if (CFArrayContainsValue(usages, CFRangeMake(0, size), ekuOCSPSigning)) + { + extendedKeyUsage |= EXTENDED_KEY_USAGE_OCSP_SIGNING; + } + } + } + return extendedKeyUsage; +#endif +} + +IceSSL::SecureTransport::CertificatePtr +IceSSL::SecureTransport::Certificate::create(SecCertificateRef cert) +{ + return ICE_MAKE_SHARED(SecureTransportCertificateI, cert); +} + +IceSSL::SecureTransport::CertificatePtr +IceSSL::SecureTransport::Certificate::load(const std::string& file) +{ + string resolved; + if(checkPath(file, "", false, resolved)) + { + return ICE_MAKE_SHARED(SecureTransportCertificateI, loadCertificate(resolved)); + } + else + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } +} + +IceSSL::SecureTransport::CertificatePtr +IceSSL::SecureTransport::Certificate::decode(const std::string& encoding) +{ +#ifdef ICE_USE_SECURE_TRANSPORT_IOS + string::size_type size = 0; + string::size_type startpos = 0; + startpos = encoding.find("-----BEGIN CERTIFICATE-----", 0); + if(startpos != string::npos) + { + startpos += sizeof("-----BEGIN CERTIFICATE-----"); + string::size_type endpos = encoding.find("-----END CERTIFICATE-----", startpos); + size = endpos - startpos; + } + else + { + startpos = 0; + size = encoding.size(); + } + + vector data(IceInternal::Base64::decode(string(&encoding[startpos], size))); + UniqueRef certdata(CFDataCreate(kCFAllocatorDefault, &data[0], static_cast(data.size()))); + SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get()); + if(!cert) + { + assert(false); + throw CertificateEncodingException(__FILE__, __LINE__, "certificate is not a valid PEM-encoded certificate"); + } + return ICE_MAKE_SHARED(SecureTransportCertificateI, cert); +#else // macOS + UniqueRef data( + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast(encoding.c_str()), + static_cast(encoding.size()), kCFAllocatorNull)); + + SecExternalFormat format = kSecFormatUnknown; + SecExternalItemType type = kSecItemTypeCertificate; + + SecItemImportExportKeyParameters params; + memset(¶ms, 0, sizeof(params)); + params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + + UniqueRef items; + OSStatus err = SecItemImport(data.get(), 0, &format, &type, 0, ¶ms, 0, &items.get()); + if(err) + { + throw CertificateEncodingException(__FILE__, __LINE__, sslErrorToString(err)); + } + + UniqueRef item; + item.retain(static_cast(const_cast(CFArrayGetValueAtIndex(items.get(), 0)))); + assert(SecCertificateGetTypeID() == CFGetTypeID(item.get())); + return ICE_MAKE_SHARED(SecureTransportCertificateI, reinterpret_cast(item.release())); +#endif +} diff --git a/Sources/IceSSLCpp/SecureTransportEngine.cpp b/Sources/IceSSLCpp/SecureTransportEngine.cpp new file mode 100644 index 0000000..f8515ff --- /dev/null +++ b/Sources/IceSSLCpp/SecureTransportEngine.cpp @@ -0,0 +1,1308 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// Disable deprecation warnings from SecureTransport APIs +#include + +using namespace std; +using namespace IceUtil; +using namespace Ice; +using namespace IceInternal; +using namespace IceSSL; +using namespace IceSSL::SecureTransport; + +namespace +{ + +IceUtil::Mutex* staticMutex = 0; + +class Init +{ +public: + + Init() + { + staticMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete staticMutex; + staticMutex = 0; + } +}; + +Init init; + +class RegExp : public IceUtil::Shared +{ +public: + + RegExp(const string&); + ~RegExp(); + bool match(const string&); + +private: + + regex_t _preg; +}; +typedef IceUtil::Handle RegExpPtr; + +RegExp::RegExp(const string& regexp) +{ + int err = regcomp(&_preg, regexp.c_str(), REG_EXTENDED | REG_NOSUB); + if(err) + { + throw IceUtil::SyscallException(__FILE__, __LINE__, err); + } +} + +RegExp::~RegExp() +{ + regfree(&_preg); +} + +bool +RegExp::match(const string& value) +{ + return regexec(&_preg, value.c_str(), 0, 0, 0) == 0; +} + +struct CipherExpression +{ + bool negation; + string cipher; + RegExpPtr re; +}; + +class CiphersHelper +{ +public: + + static void initialize(); + static SSLCipherSuite cipherForName(const string& name); + static string cipherName(SSLCipherSuite cipher); + static map ciphers(); + +private: + + static map _ciphers; +}; + +map CiphersHelper::_ciphers; + +// +// Initialize a dictionary with the names of ciphers +// +void +CiphersHelper::initialize() +{ + IceUtilInternal::MutexPtrLock sync(staticMutex); + if(_ciphers.empty()) + { + _ciphers["NULL_WITH_NULL_NULL"] = SSL_NULL_WITH_NULL_NULL; + _ciphers["RSA_WITH_NULL_MD5"] = SSL_RSA_WITH_NULL_MD5; + _ciphers["RSA_WITH_NULL_SHA"] = SSL_RSA_WITH_NULL_SHA; + _ciphers["RSA_EXPORT_WITH_RC4_40_MD5"] = SSL_RSA_EXPORT_WITH_RC4_40_MD5; + _ciphers["RSA_WITH_RC4_128_MD5"] = SSL_RSA_WITH_RC4_128_MD5; + _ciphers["RSA_WITH_RC4_128_SHA"] = SSL_RSA_WITH_RC4_128_SHA; + _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5; + _ciphers["RSA_WITH_IDEA_CBC_SHA"] = SSL_RSA_WITH_IDEA_CBC_SHA; + _ciphers["RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["RSA_WITH_DES_CBC_SHA"] = SSL_RSA_WITH_DES_CBC_SHA; + _ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_DSS_WITH_DES_CBC_SHA"] = SSL_DH_DSS_WITH_DES_CBC_SHA; + _ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_RSA_WITH_DES_CBC_SHA"] = SSL_DH_RSA_WITH_DES_CBC_SHA; + _ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DHE_DSS_WITH_DES_CBC_SHA"] = SSL_DHE_DSS_WITH_DES_CBC_SHA; + _ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DHE_RSA_WITH_DES_CBC_SHA"] = SSL_DHE_RSA_WITH_DES_CBC_SHA; + _ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_anon_EXPORT_WITH_RC4_40_MD5"] = SSL_DH_anon_EXPORT_WITH_RC4_40_MD5; + _ciphers["DH_anon_WITH_RC4_128_MD5"] = SSL_DH_anon_WITH_RC4_128_MD5; + _ciphers["DH_anon_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_anon_WITH_DES_CBC_SHA"] = SSL_DH_anon_WITH_DES_CBC_SHA; + _ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["FORTEZZA_DMS_WITH_NULL_SHA"] = SSL_FORTEZZA_DMS_WITH_NULL_SHA; + _ciphers["FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"] = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA; + + // + // TLS addenda using AES, per RFC 3268 + // + _ciphers["RSA_WITH_AES_128_CBC_SHA"] = TLS_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_128_CBC_SHA"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA; + _ciphers["DH_RSA_WITH_AES_128_CBC_SHA"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; + _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DH_anon_WITH_AES_128_CBC_SHA"] = TLS_DH_anon_WITH_AES_128_CBC_SHA; + _ciphers["RSA_WITH_AES_256_CBC_SHA"] = TLS_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_256_CBC_SHA"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA; + _ciphers["DH_RSA_WITH_AES_256_CBC_SHA"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; + _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DH_anon_WITH_AES_256_CBC_SHA"] = TLS_DH_anon_WITH_AES_256_CBC_SHA; + + // + // ECDSA addenda, RFC 4492 + // + _ciphers["ECDH_ECDSA_WITH_NULL_SHA"] = TLS_ECDH_ECDSA_WITH_NULL_SHA; + _ciphers["ECDH_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA; + _ciphers["ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_NULL_SHA"] = TLS_ECDHE_ECDSA_WITH_NULL_SHA; + _ciphers["ECDHE_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA; + _ciphers["ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDH_RSA_WITH_NULL_SHA"] = TLS_ECDH_RSA_WITH_NULL_SHA; + _ciphers["ECDH_RSA_WITH_RC4_128_SHA"] = TLS_ECDH_RSA_WITH_RC4_128_SHA; + _ciphers["ECDH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_NULL_SHA"] = TLS_ECDHE_RSA_WITH_NULL_SHA; + _ciphers["ECDHE_RSA_WITH_RC4_128_SHA"] = TLS_ECDHE_RSA_WITH_RC4_128_SHA; + _ciphers["ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDH_anon_WITH_NULL_SHA"] = TLS_ECDH_anon_WITH_NULL_SHA; + _ciphers["ECDH_anon_WITH_RC4_128_SHA"] = TLS_ECDH_anon_WITH_RC4_128_SHA; + _ciphers["ECDH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_anon_WITH_AES_128_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_anon_WITH_AES_256_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_256_CBC_SHA; + + // + // TLS 1.2 addenda, RFC 5246 + // + //_ciphers["NULL_WITH_NULL_NULL"] = TLS_NULL_WITH_NULL_NULL; + + // + // Server provided RSA certificate for key exchange. + // + //_ciphers["RSA_WITH_NULL_MD5"] = TLS_RSA_WITH_NULL_MD5; + //_ciphers["RSA_WITH_NULL_SHA"] = TLS_RSA_WITH_NULL_SHA; + //_ciphers["RSA_WITH_RC4_128_MD5"] = TLS_RSA_WITH_RC4_128_MD5; + //_ciphers["RSA_WITH_RC4_128_SHA"] = TLS_RSA_WITH_RC4_128_SHA; + //_ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["RSA_WITH_NULL_SHA256"] = TLS_RSA_WITH_NULL_SHA256; + _ciphers["RSA_WITH_AES_128_CBC_SHA256"] = TLS_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["RSA_WITH_AES_256_CBC_SHA256"] = TLS_RSA_WITH_AES_256_CBC_SHA256; + + // + // Server-authenticated (and optionally client-authenticated) Diffie-Hellman. + // + //_ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA256; + _ciphers["DH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["DH_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA256; + _ciphers["DH_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA256; + _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA256; + _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; + + // + // Completely anonymous Diffie-Hellman + // + //_ciphers["DH_anon_WITH_RC4_128_MD5"] = TLS_DH_anon_WITH_RC4_128_MD5; + //_ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_anon_WITH_AES_128_CBC_SHA256"] = TLS_DH_anon_WITH_AES_128_CBC_SHA256; + _ciphers["DH_anon_WITH_AES_256_CBC_SHA256"] = TLS_DH_anon_WITH_AES_256_CBC_SHA256; + + // + // Addendum from RFC 4279, TLS PSK + // + _ciphers["PSK_WITH_RC4_128_SHA"] = TLS_PSK_WITH_RC4_128_SHA; + _ciphers["PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["PSK_WITH_AES_128_CBC_SHA"] = TLS_PSK_WITH_AES_128_CBC_SHA; + _ciphers["PSK_WITH_AES_256_CBC_SHA"] = TLS_PSK_WITH_AES_256_CBC_SHA; + _ciphers["DHE_PSK_WITH_RC4_128_SHA"] = TLS_DHE_PSK_WITH_RC4_128_SHA; + _ciphers["DHE_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA; + _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA; + _ciphers["RSA_PSK_WITH_RC4_128_SHA"] = TLS_RSA_PSK_WITH_RC4_128_SHA; + _ciphers["RSA_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA; + _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA; + + // + // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption + // + _ciphers["PSK_WITH_NULL_SHA"] = TLS_PSK_WITH_NULL_SHA; + _ciphers["DHE_PSK_WITH_NULL_SHA"] = TLS_DHE_PSK_WITH_NULL_SHA; + _ciphers["RSA_PSK_WITH_NULL_SHA"] = TLS_RSA_PSK_WITH_NULL_SHA; + + // + // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS. + // + _ciphers["RSA_WITH_AES_128_GCM_SHA256"] = TLS_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["RSA_WITH_AES_256_GCM_SHA384"] = TLS_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DH_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["DH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DH_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DHE_DSS_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DHE_DSS_WITH_AES_256_GCM_SHA384; + _ciphers["DH_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DH_DSS_WITH_AES_128_GCM_SHA256; + _ciphers["DH_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DH_DSS_WITH_AES_256_GCM_SHA384; + _ciphers["DH_anon_WITH_AES_128_GCM_SHA256"] = TLS_DH_anon_WITH_AES_128_GCM_SHA256; + _ciphers["DH_anon_WITH_AES_256_GCM_SHA384"] = TLS_DH_anon_WITH_AES_256_GCM_SHA384; + + // + // RFC 5487 - PSK with SHA-256/384 and AES GCM + // + _ciphers["PSK_WITH_AES_128_GCM_SHA256"] = TLS_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["PSK_WITH_AES_256_GCM_SHA384"] = TLS_PSK_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_PSK_WITH_AES_128_GCM_SHA256"] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_PSK_WITH_AES_256_GCM_SHA384"] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384; + _ciphers["RSA_PSK_WITH_AES_128_GCM_SHA256"] = TLS_RSA_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["RSA_PSK_WITH_AES_256_GCM_SHA384"] = TLS_RSA_PSK_WITH_AES_256_GCM_SHA384; + + _ciphers["PSK_WITH_AES_128_CBC_SHA256"] = TLS_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["PSK_WITH_AES_256_CBC_SHA384"] = TLS_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["PSK_WITH_NULL_SHA256"] = TLS_PSK_WITH_NULL_SHA256; + _ciphers["PSK_WITH_NULL_SHA384"] = TLS_PSK_WITH_NULL_SHA384; + + _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA256"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA384"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["DHE_PSK_WITH_NULL_SHA256"] = TLS_DHE_PSK_WITH_NULL_SHA256; + _ciphers["DHE_PSK_WITH_NULL_SHA384"] = TLS_DHE_PSK_WITH_NULL_SHA384; + + _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA256"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA384"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["RSA_PSK_WITH_NULL_SHA256"] = TLS_RSA_PSK_WITH_NULL_SHA256; + _ciphers["RSA_PSK_WITH_NULL_SHA384"] = TLS_RSA_PSK_WITH_NULL_SHA384; + + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with HMAC SHA-256/384. + // + _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384; + + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) + // + _ciphers["ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDH_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDH_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384; + + // + // RFC 5746 - Secure Renegotiation + // + _ciphers["EMPTY_RENEGOTIATION_INFO_SCSV"] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV; + + // + // Tags for SSL 2 cipher kinds that are not specified for SSL 3. + // + _ciphers["RSA_WITH_RC2_CBC_MD5"] = SSL_RSA_WITH_RC2_CBC_MD5; + _ciphers["RSA_WITH_IDEA_CBC_MD5"] = SSL_RSA_WITH_IDEA_CBC_MD5; + _ciphers["RSA_WITH_DES_CBC_MD5"] = SSL_RSA_WITH_DES_CBC_MD5; + _ciphers["RSA_WITH_3DES_EDE_CBC_MD5"] = SSL_RSA_WITH_3DES_EDE_CBC_MD5; + _ciphers["NO_SUCH_CIPHERSUITE"] = SSL_NO_SUCH_CIPHERSUITE; + + // + // TLS 1.3 standard cipher suites + // + _ciphers["TLS_AES_128_GCM_SHA256"] = TLS_AES_128_GCM_SHA256; + _ciphers["TLS_AES_256_GCM_SHA384"] = TLS_AES_256_GCM_SHA384; + _ciphers["TLS_CHACHA20_POLY1305_SHA256"] = TLS_CHACHA20_POLY1305_SHA256; + _ciphers["TLS_AES_128_CCM_SHA256"] = TLS_AES_128_CCM_SHA256; + _ciphers["TLS_AES_128_CCM_8_SHA256"] = TLS_AES_128_CCM_8_SHA256; + + } +} + +SSLCipherSuite +CiphersHelper::cipherForName(const string& name) +{ + map::const_iterator i = _ciphers.find(name); + if(i == _ciphers.end() || i->second == SSL_NO_SUCH_CIPHERSUITE) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: no such cipher " + name); + } + return i->second; +} + +// +// Retrive the name of a cipher, SSLCipherSuite inlude duplicated values for TLS/SSL +// protocol ciphers, for example SSL_RSA_WITH_RC4_128_MD5/TLS_RSA_WITH_RC4_128_MD5 +// are represeted by the same SSLCipherSuite value, the names return by this method +// doesn't include a protocol prefix. +// +string +CiphersHelper::cipherName(SSLCipherSuite cipher) +{ + switch(cipher) + { + case SSL_NULL_WITH_NULL_NULL: + return "NULL_WITH_NULL_NULL"; + case SSL_RSA_WITH_NULL_MD5: + return "RSA_WITH_NULL_MD5"; + case SSL_RSA_WITH_NULL_SHA: + return "RSA_WITH_NULL_SHA"; + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + return "RSA_EXPORT_WITH_RC4_40_MD5"; + case SSL_RSA_WITH_RC4_128_MD5: + return "RSA_WITH_RC4_128_MD5"; + case SSL_RSA_WITH_RC4_128_SHA: + return "RSA_WITH_RC4_128_SHA"; + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + return "RSA_EXPORT_WITH_RC2_CBC_40_MD5"; + case SSL_RSA_WITH_IDEA_CBC_SHA: + return "RSA_WITH_IDEA_CBC_SHA"; + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "RSA_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_RSA_WITH_DES_CBC_SHA: + return "RSA_WITH_DES_CBC_SHA"; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "RSA_WITH_3DES_EDE_CBC_SHA"; + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_DH_DSS_WITH_DES_CBC_SHA: + return "DH_DSS_WITH_DES_CBC_SHA"; + case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "DH_DSS_WITH_3DES_EDE_CBC_SHA"; + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_DH_RSA_WITH_DES_CBC_SHA: + return "DH_RSA_WITH_DES_CBC_SHA"; + case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "DH_RSA_WITH_3DES_EDE_CBC_SHA"; + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + return "DHE_DSS_WITH_DES_CBC_SHA"; + case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + return "DHE_RSA_WITH_DES_CBC_SHA"; + case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + return "DH_anon_EXPORT_WITH_RC4_40_MD5"; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "DH_anon_WITH_RC4_128_MD5"; + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + return "DH_anon_EXPORT_WITH_DES40_CBC_SHA"; + case SSL_DH_anon_WITH_DES_CBC_SHA: + return "DH_anon_WITH_DES_CBC_SHA"; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "DH_anon_WITH_3DES_EDE_CBC_SHA"; + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + return "FORTEZZA_DMS_WITH_NULL_SHA"; + case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: + return "FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; + + // + // TLS addenda using AES, per RFC 3268 + // + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "RSA_WITH_AES_128_CBC_SHA"; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "DH_DSS_WITH_AES_128_CBC_SHA"; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "DH_RSA_WITH_AES_128_CBC_SHA"; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "DHE_DSS_WITH_AES_128_CBC_SHA"; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "DHE_RSA_WITH_AES_128_CBC_SHA"; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "DH_anon_WITH_AES_128_CBC_SHA"; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "RSA_WITH_AES_256_CBC_SHA"; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "DH_DSS_WITH_AES_256_CBC_SHA"; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "DH_RSA_WITH_AES_256_CBC_SHA"; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "DHE_DSS_WITH_AES_256_CBC_SHA"; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "DHE_RSA_WITH_AES_256_CBC_SHA"; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "DH_anon_WITH_AES_256_CBC_SHA"; + + // + // ECDSA addenda, RFC 4492 + // + case TLS_ECDH_ECDSA_WITH_NULL_SHA: + return "ECDH_ECDSA_WITH_NULL_SHA"; + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return "ECDH_ECDSA_WITH_RC4_128_SHA"; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + return "ECDH_ECDSA_WITH_AES_128_CBC_SHA"; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + return "ECDH_ECDSA_WITH_AES_256_CBC_SHA"; + case TLS_ECDHE_ECDSA_WITH_NULL_SHA: + return "ECDHE_ECDSA_WITH_NULL_SHA"; + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return "ECDHE_ECDSA_WITH_RC4_128_SHA"; + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; + case TLS_ECDH_RSA_WITH_NULL_SHA: + return "ECDH_RSA_WITH_NULL_SHA"; + case TLS_ECDH_RSA_WITH_RC4_128_SHA: + return "ECDH_RSA_WITH_RC4_128_SHA"; + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + return "ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + return "ECDH_RSA_WITH_AES_128_CBC_SHA"; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + return "ECDH_RSA_WITH_AES_256_CBC_SHA"; + case TLS_ECDHE_RSA_WITH_NULL_SHA: + return "ECDHE_RSA_WITH_NULL_SHA"; + case TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return "ECDHE_RSA_WITH_RC4_128_SHA"; + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "ECDHE_RSA_WITH_AES_128_CBC_SHA"; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "ECDHE_RSA_WITH_AES_256_CBC_SHA"; + case TLS_ECDH_anon_WITH_NULL_SHA: + return "ECDH_anon_WITH_NULL_SHA"; + case TLS_ECDH_anon_WITH_RC4_128_SHA: + return "ECDH_anon_WITH_RC4_128_SHA"; + case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + return "ECDH_anon_WITH_3DES_EDE_CBC_SHA"; + case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + return "ECDH_anon_WITH_AES_128_CBC_SHA"; + case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + return "ECDH_anon_WITH_AES_256_CBC_SHA"; + + // + // TLS 1.2 addenda, RFC 5246 + // + //case TLS_NULL_WITH_NULL_NULL: + // return "NULL_WITH_NULL_NULL"; + + // + // Server provided RSA certificate for key exchange. + // + //case TLS_RSA_WITH_NULL_MD5: + // return "RSA_WITH_NULL_MD5"; + //case TLS_RSA_WITH_NULL_SHA: + // return "RSA_WITH_NULL_SHA"; + //case TLS_RSA_WITH_RC4_128_MD5: + // return "RSA_WITH_RC4_128_MD5"; + //case TLS_RSA_WITH_RC4_128_SHA: + // return "RSA_WITH_RC4_128_SHA"; + //case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + // return "RSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_RSA_WITH_NULL_SHA256: + return "RSA_WITH_NULL_SHA256"; + case TLS_RSA_WITH_AES_128_CBC_SHA256: + return "RSA_WITH_AES_128_CBC_SHA256"; + case TLS_RSA_WITH_AES_256_CBC_SHA256: + return "RSA_WITH_AES_256_CBC_SHA256"; + + // + // Server-authenticated (and optionally client-authenticated) Diffie-Hellman. + // + //case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + // return "DH_DSS_WITH_3DES_EDE_CBC_SHA"; + //case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + // return "DH_RSA_WITH_3DES_EDE_CBC_SHA"; + //case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + // return "DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + //case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + // return "DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + return "DH_DSS_WITH_AES_128_CBC_SHA256"; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + return "DH_RSA_WITH_AES_128_CBC_SHA256"; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + return "DHE_DSS_WITH_AES_128_CBC_SHA256"; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + return "DHE_RSA_WITH_AES_128_CBC_SHA256"; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + return "DH_DSS_WITH_AES_256_CBC_SHA256"; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + return "DH_RSA_WITH_AES_256_CBC_SHA256"; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + return "DHE_DSS_WITH_AES_256_CBC_SHA256"; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + return "DHE_RSA_WITH_AES_256_CBC_SHA256"; + + // + // Completely anonymous Diffie-Hellman + // + //case TLS_DH_anon_WITH_RC4_128_MD5: + // return "DH_anon_WITH_RC4_128_MD5"; + //case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + // return "DH_anon_WITH_3DES_EDE_CBC_SHA"; + case TLS_DH_anon_WITH_AES_128_CBC_SHA256: + return "DH_anon_WITH_AES_128_CBC_SHA256"; + case TLS_DH_anon_WITH_AES_256_CBC_SHA256: + return "DH_anon_WITH_AES_256_CBC_SHA256"; + + // + // Addendum from RFC 4279, TLS PSK + // + case TLS_PSK_WITH_RC4_128_SHA: + return "PSK_WITH_RC4_128_SHA"; + case TLS_PSK_WITH_3DES_EDE_CBC_SHA: + return "PSK_WITH_3DES_EDE_CBC_SHA"; + case TLS_PSK_WITH_AES_128_CBC_SHA: + return "PSK_WITH_AES_128_CBC_SHA"; + case TLS_PSK_WITH_AES_256_CBC_SHA: + return "PSK_WITH_AES_256_CBC_SHA"; + case TLS_DHE_PSK_WITH_RC4_128_SHA: + return "DHE_PSK_WITH_RC4_128_SHA"; + case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + return "DHE_PSK_WITH_3DES_EDE_CBC_SHA"; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + return "DHE_PSK_WITH_AES_128_CBC_SHA"; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + return "DHE_PSK_WITH_AES_256_CBC_SHA"; + case TLS_RSA_PSK_WITH_RC4_128_SHA: + return "RSA_PSK_WITH_RC4_128_SHA"; + case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + return "RSA_PSK_WITH_3DES_EDE_CBC_SHA"; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + return "RSA_PSK_WITH_AES_128_CBC_SHA"; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + return "RSA_PSK_WITH_AES_256_CBC_SHA"; + + // + // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption + // + case TLS_PSK_WITH_NULL_SHA: + return "PSK_WITH_NULL_SHA"; + case TLS_DHE_PSK_WITH_NULL_SHA: + return "DHE_PSK_WITH_NULL_SHA"; + case TLS_RSA_PSK_WITH_NULL_SHA: + return "RSA_PSK_WITH_NULL_SHA"; + + // + // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS. + // + case TLS_RSA_WITH_AES_128_GCM_SHA256: + return "RSA_WITH_AES_128_GCM_SHA256"; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + return "RSA_WITH_AES_256_GCM_SHA384"; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + return "DHE_RSA_WITH_AES_128_GCM_SHA256"; + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + return "DHE_RSA_WITH_AES_256_GCM_SHA384"; + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + return "DH_RSA_WITH_AES_128_GCM_SHA256"; + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + return "DH_RSA_WITH_AES_256_GCM_SHA384"; + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return "DHE_DSS_WITH_AES_128_GCM_SHA256"; + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + return "DHE_DSS_WITH_AES_256_GCM_SHA384"; + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + return "DH_DSS_WITH_AES_128_GCM_SHA256"; + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + return "DH_DSS_WITH_AES_256_GCM_SHA384"; + case TLS_DH_anon_WITH_AES_128_GCM_SHA256: + return "DH_anon_WITH_AES_128_GCM_SHA256"; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + return "DH_anon_WITH_AES_256_GCM_SHA384"; + + // + // RFC 5487 - PSK with SHA-256/384 and AES GCM + // + case TLS_PSK_WITH_AES_128_GCM_SHA256: + return "PSK_WITH_AES_128_GCM_SHA256"; + case TLS_PSK_WITH_AES_256_GCM_SHA384: + return "PSK_WITH_AES_256_GCM_SHA384"; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + return "DHE_PSK_WITH_AES_128_GCM_SHA256"; + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + return "DHE_PSK_WITH_AES_256_GCM_SHA384"; + case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + return "RSA_PSK_WITH_AES_128_GCM_SHA256"; + case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + return "RSA_PSK_WITH_AES_256_GCM_SHA384"; + + case TLS_PSK_WITH_AES_128_CBC_SHA256: + return "PSK_WITH_AES_128_CBC_SHA256"; + case TLS_PSK_WITH_AES_256_CBC_SHA384: + return "PSK_WITH_AES_256_CBC_SHA384"; + case TLS_PSK_WITH_NULL_SHA256: + return "WITH_NULL_SHA256"; + case TLS_PSK_WITH_NULL_SHA384: + return "PSK_WITH_NULL_SHA384"; + + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + return "DHE_PSK_WITH_AES_128_CBC_SHA256"; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + return "DHE_PSK_WITH_AES_256_CBC_SHA384"; + case TLS_DHE_PSK_WITH_NULL_SHA256: + return "DHE_PSK_WITH_NULL_SHA256"; + case TLS_DHE_PSK_WITH_NULL_SHA384: + return "DHE_PSK_WITH_NULL_SHA384"; + + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + return "RSA_PSK_WITH_AES_128_CBC_SHA256"; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + return "RSA_PSK_WITH_AES_256_CBC_SHA384"; + case TLS_RSA_PSK_WITH_NULL_SHA256: + return "RSA_PSK_WITH_NULL_SHA256"; + case TLS_RSA_PSK_WITH_NULL_SHA384: + return "RSA_PSK_WITH_NULL_SHA384"; + + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with HMAC SHA-256/384. + // + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + return "ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + return "ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "ECDHE_RSA_WITH_AES_256_CBC_SHA384"; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + return "ECDH_RSA_WITH_AES_128_CBC_SHA256"; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + return "ECDH_RSA_WITH_AES_256_CBC_SHA384"; + + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) + // + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + return "ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + return "ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + return "ECDH_RSA_WITH_AES_128_GCM_SHA256"; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + return "ECDH_RSA_WITH_AES_256_GCM_SHA384"; + + // + // RFC 5746 - Secure Renegotiation + // + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + return "EMPTY_RENEGOTIATION_INFO_SCSV"; + + // + // Tags for SSL 2 cipher kinds that are not specified for SSL 3. + // + case SSL_RSA_WITH_RC2_CBC_MD5: + return "RSA_WITH_RC2_CBC_MD5"; + case SSL_RSA_WITH_IDEA_CBC_MD5: + return "RSA_WITH_IDEA_CBC_MD5"; + case SSL_RSA_WITH_DES_CBC_MD5: + return "RSA_WITH_DES_CBC_MD5"; + case SSL_RSA_WITH_3DES_EDE_CBC_MD5: + return "RSA_WITH_3DES_EDE_CBC_MD5"; + + // + //TLS 1.3 standard cipher suites + // + case TLS_AES_128_GCM_SHA256: + return "TLS_AES_128_GCM_SHA256"; + case TLS_AES_256_GCM_SHA384: + return "TLS_AES_256_GCM_SHA384"; + case TLS_CHACHA20_POLY1305_SHA256: + return "TLS_CHACHA20_POLY1305_SHA256"; + case TLS_AES_128_CCM_SHA256: + return "TLS_AES_128_CCM_SHA256"; + case TLS_AES_128_CCM_8_SHA256: + return "TLS_AES_128_CCM_8_SHA256"; + + default: + return ""; + } +} + +map +CiphersHelper::ciphers() +{ + return _ciphers; +} + +SSLProtocol +parseProtocol(const string& p) +{ + const string prot = IceUtilInternal::toUpper(p); + if(prot == "SSL3" || prot == "SSLV3") + { + return kSSLProtocol3; + } + else if(prot == "TLS" || prot == "TLS1" || prot == "TLSV1" || prot == "TLS1_0" || prot == "TLSV1_0") + { + return kTLSProtocol1; + } + else if(prot == "TLS1_1" || prot == "TLSV1_1") + { + return kTLSProtocol11; + } + else if(prot == "TLS1_2" || prot == "TLSV1_2") + { + return kTLSProtocol12; + } + else if(prot == "TLS1_3" || prot == "TLSV1_3") + { + return kTLSProtocol13; + } + else + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unrecognized protocol `" + p + "'"); + } +} + +} + +IceUtil::Shared* +IceSSL::SecureTransport::upCast(IceSSL::SecureTransport::SSLEngine* p) +{ + return p; +} + +IceSSL::SecureTransport::SSLEngine::SSLEngine(const Ice::CommunicatorPtr& communicator) : + IceSSL::SSLEngine(communicator), + _certificateAuthorities(0), + _chain(0), + _protocolVersionMax(kSSLProtocolUnknown), + _protocolVersionMin(kSSLProtocolUnknown) +{ +} + +// +// Setup the engine. +// +void +IceSSL::SecureTransport::SSLEngine::initialize() +{ + IceUtil::Mutex::Lock lock(_mutex); + if(_initialized) + { + return; + } + + IceSSL::SSLEngine::initialize(); + + const PropertiesPtr properties = communicator()->getProperties(); + + // + // Check for a default directory. We look in this directory for + // files mentioned in the configuration. + // + const string defaultDir = properties->getProperty("IceSSL.DefaultDir"); + + // + // Load the CA certificates used to authenticate peers into + // _certificateAuthorities array. + // + try + { + string caFile = properties->getProperty("IceSSL.CAs"); + if(caFile.empty()) + { + caFile = properties->getProperty("IceSSL.CertAuthFile"); + } + if(!caFile.empty()) + { + string resolved; + if(!checkPath(caFile, defaultDir, false, resolved)) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: CA certificate file not found:\n" + caFile); + } + _certificateAuthorities.reset(loadCACertificates(resolved)); + } + else if(properties->getPropertyAsInt("IceSSL.UsePlatformCAs") <= 0) + { + // Setup an empty list of Root CAs to not use the system root CAs. + _certificateAuthorities.reset(CFArrayCreate(0, 0, 0, 0)); + } + } + catch(const CertificateReadException& ce) + { + throw PluginInitializationException(__FILE__, __LINE__, ce.reason); + } + + const string password = properties->getProperty("IceSSL.Password"); + const int passwordRetryMax = properties->getPropertyAsIntWithDefault("IceSSL.PasswordRetryMax", 3); + PasswordPromptPtr passwordPrompt = getPasswordPrompt(); + + string certFile = properties->getProperty("IceSSL.CertFile"); + string findCert = properties->getProperty("IceSSL.FindCert"); + string keychain = properties->getProperty("IceSSL.Keychain"); + string keychainPassword = properties->getProperty("IceSSL.KeychainPassword"); + + if(!certFile.empty()) + { + vector files; + if(!IceUtilInternal::splitString(certFile, IceUtilInternal::pathsep, files) || files.size() > 2) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid value for IceSSL.CertFile:\n" + certFile); + } + vector keyFiles; + { + string keyFile = properties->getProperty("IceSSL.KeyFile"); + if(!keyFile.empty()) + { + if(!IceUtilInternal::splitString(keyFile, IceUtilInternal::pathsep, keyFiles) || keyFiles.size() > 2) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid value for IceSSL.KeyFile:\n" + keyFile); + } + if(files.size() != keyFiles.size()) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: IceSSL.KeyFile does not agree with IceSSL.CertFile"); + } + } + } + + for(size_t i = 0; i < files.size(); ++i) + { + string file = files[i]; + string keyFile = keyFiles.empty() ? "" : keyFiles[i]; + string resolved; + + if(!checkPath(file, defaultDir, false, resolved)) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: certificate file not found:\n" + file); + } + file = resolved; + + if(!keyFile.empty()) + { + if(!checkPath(keyFile, defaultDir, false, resolved)) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: key file not found:\n" + keyFile); + } + keyFile = resolved; + } + + try + { + _chain.reset(loadCertificateChain(file, keyFile, keychain, keychainPassword, password, passwordPrompt, + passwordRetryMax)); + break; + } + catch(const CertificateReadException& ce) + { + // + // If this is the last certificate rethrow the exception as PluginInitializationException, + // otherwise try the next certificate. + // + if(i == files.size() - 1) + { + throw PluginInitializationException(__FILE__, __LINE__, ce.reason); + } + } + } + } + else if(!findCert.empty()) + { + _chain.reset(findCertificateChain(keychain, keychainPassword, findCert)); + } + + // + // DiffieHellmanParams in DER format. + // +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) + string dhFile = properties->getProperty("IceSSL.DHParams"); + if(!dhFile.empty()) + { + string resolved; + if(!checkPath(dhFile, defaultDir, false, resolved)) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: DH params file not found:\n" + dhFile); + } + + readFile(resolved, _dhParams); + } +#endif + + // + // Establish the cipher list. + // + const string ciphers = properties->getProperty("IceSSL.Ciphers"); + CiphersHelper::initialize(); + + if(!ciphers.empty()) + { + parseCiphers(ciphers); + } + + if(securityTraceLevel() >= 1) + { + ostringstream os; + os << "enabling SSL ciphersuites:"; + + if(_ciphers.empty()) + { + map enabled = CiphersHelper::ciphers(); + for(map::const_iterator i = enabled.begin(); i != enabled.end(); ++i) + { + os << "\n " << i->first; + } + } + else + { + for(vector::const_iterator i = _ciphers.begin(); i != _ciphers.end(); ++i) + { + os << "\n " << getCipherName(*i); + } + } + getLogger()->trace(securityTraceCategory(), os.str()); + } + + // + // Parse protocols + // + const string protocolVersionMax = properties->getProperty("IceSSL.ProtocolVersionMax"); + if(!protocolVersionMax.empty()) + { + _protocolVersionMax = parseProtocol(protocolVersionMax); + } + + // + // The default min protocol version is set to TLS1.0 to avoid security issues with SSLv3 + // + const string protocolVersionMin = properties->getPropertyWithDefault("IceSSL.ProtocolVersionMin", "tls1_0"); + if(!protocolVersionMin.empty()) + { + _protocolVersionMin = parseProtocol(protocolVersionMin); + } + _initialized = true; +} + +// +// Destroy the engine. +// +void +IceSSL::SecureTransport::SSLEngine::destroy() +{ +} + +IceInternal::TransceiverPtr +IceSSL::SecureTransport::SSLEngine::createTransceiver(const InstancePtr& instance, + const IceInternal::TransceiverPtr& delegate, + const string& hostOrAdapterName, + bool incoming) +{ + return new IceSSL::SecureTransport::TransceiverI(instance, delegate, hostOrAdapterName, incoming); +} + +SSLContextRef +IceSSL::SecureTransport::SSLEngine::newContext(bool incoming) +{ + SSLContextRef ssl = SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, + kSSLStreamType); + if(!ssl) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: unable to create SSL context"); + } + + OSStatus err = noErr; + if(incoming) + { + switch(getVerifyPeer()) + { + case 0: + { + SSLSetClientSideAuthenticate(ssl, kNeverAuthenticate); + break; + } + case 1: + { + SSLSetClientSideAuthenticate(ssl, kTryAuthenticate); + break; + } + case 2: + { + SSLSetClientSideAuthenticate(ssl, kAlwaysAuthenticate); + break; + } + default: + { + assert(false); + break; + } + } + +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) + if(!_dhParams.empty()) + { + if((err = SSLSetDiffieHellmanParams(ssl, &_dhParams[0], _dhParams.size()))) + { + throw SecurityException(__FILE__, __LINE__, + "IceSSL: unable to create the trust object:\n" + sslErrorToString(err)); + } + } +#endif + } + + if(_chain && (err = SSLSetCertificate(ssl, _chain.get()))) + { + throw SecurityException(__FILE__, __LINE__, + "IceSSL: error while setting the SSL context certificate:\n" + sslErrorToString(err)); + } + + if(!_ciphers.empty()) + { + if((err = SSLSetEnabledCiphers(ssl, &_ciphers[0], _ciphers.size()))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: error while setting ciphers:\n" + sslErrorToString(err)); + } + } + + if((err = SSLSetSessionOption(ssl, incoming ? kSSLSessionOptionBreakOnClientAuth : + kSSLSessionOptionBreakOnServerAuth, + true))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: error while setting SSL option:\n" + sslErrorToString(err)); + } + + if(_protocolVersionMax != kSSLProtocolUnknown) + { + if((err = SSLSetProtocolVersionMax(ssl, _protocolVersionMax))) + { + throw SecurityException(__FILE__, __LINE__, + "IceSSL: error while setting SSL protocol version max:\n" + sslErrorToString(err)); + } + } + + if(_protocolVersionMin != kSSLProtocolUnknown) + { + if((err = SSLSetProtocolVersionMin(ssl, _protocolVersionMin))) + { + throw SecurityException(__FILE__, __LINE__, + "IceSSL: error while setting SSL protocol version min:\n" + sslErrorToString(err)); + } + } + + return ssl; +} + +CFArrayRef +IceSSL::SecureTransport::SSLEngine::getCertificateAuthorities() const +{ + return _certificateAuthorities.get(); +} + +string +IceSSL::SecureTransport::SSLEngine::getCipherName(SSLCipherSuite cipher) const +{ + return CiphersHelper::cipherName(cipher); +} + +void +IceSSL::SecureTransport::SSLEngine::parseCiphers(const string& ciphers) +{ + vector tokens; + vector cipherExpressions; + + bool allCiphers = false; + IceUtilInternal::splitString(ciphers, " \t", tokens); + for(vector::const_iterator i = tokens.begin(); i != tokens.end(); ++i) + { + string token(*i); + if(token == "ALL") + { + if(i != tokens.begin()) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: `ALL' must be first in cipher list `" + ciphers + "'"); + } + allCiphers = true; + } + else if(token == "NONE") + { + if(i != tokens.begin()) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: `NONE' must be first in cipher list `" + ciphers + "'"); + } + } + else + { + CipherExpression ce; + if(token.find('!') == 0) + { + ce.negation = true; + if(token.size() > 1) + { + token = token.substr(1); + } + else + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid cipher expression `" + token + "'"); + } + } + else + { + ce.negation = false; + } + + if(token.find('(') == 0) + { + if(token.rfind(')') != token.size() - 1) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid cipher expression `" + token + "'"); + } + + try + { + ce.re = new RegExp(token.substr(1, token.size() - 2)); + } + catch(const Ice::SyscallException&) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid cipher expression `" + token + "'"); + } + } + else + { + ce.cipher = token; + } + + cipherExpressions.push_back(ce); + } + } + + // + // Context used to get the cipher list + // + UniqueRef ctx(SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType)); + size_t numSupportedCiphers = 0; + SSLGetNumberSupportedCiphers(ctx.get(), &numSupportedCiphers); + + vector supported; + supported.resize(numSupportedCiphers); + + OSStatus err = SSLGetSupportedCiphers(ctx.get(), &supported[0], &numSupportedCiphers); + if(err) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to get supported ciphers list:\n" + sslErrorToString(err)); + } + + vector enabled; + if(allCiphers) + { + enabled = supported; + } + + for(vector::const_iterator i = cipherExpressions.begin(); i != cipherExpressions.end(); ++i) + { + CipherExpression ce = *i; + if(ce.negation) + { + for(vector::iterator j = enabled.begin(); j != enabled.end();) + { + string name = CiphersHelper::cipherName(*j); + if((ce.cipher.empty() && ce.re->match(name)) || ce.cipher == name) + { + j = enabled.erase(j); + } + else + { + ++j; + } + } + } + else + { + if(ce.cipher.empty()) + { + for(vector::const_iterator j = supported.begin(); j != supported.end(); ++j) + { + SSLCipherSuite cipher = *j; + string name = CiphersHelper::cipherName(cipher); + if(ce.re->match(name)) + { + vector::const_iterator k = find(enabled.begin(), enabled.end(), cipher); + if(k == enabled.end()) + { + enabled.push_back(cipher); + } + } + } + } + else + { + SSLCipherSuite cipher = CiphersHelper::cipherForName(ce.cipher); + vector::const_iterator k = find(enabled.begin(), enabled.end(), cipher); + if(k == enabled.end()) + { + enabled.push_back(cipher); + } + } + } + } + _ciphers = enabled; + + if(_ciphers.empty()) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid value for IceSSL.Ciphers:\n" + ciphers + + "\nThe result cipher list does not contain any entries"); + } +} diff --git a/Sources/IceSSLCpp/SecureTransportPluginI.cpp b/Sources/IceSSLCpp/SecureTransportPluginI.cpp new file mode 100644 index 0000000..1ecbeec --- /dev/null +++ b/Sources/IceSSLCpp/SecureTransportPluginI.cpp @@ -0,0 +1,75 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +#include + +using namespace Ice; +using namespace std; + +namespace +{ + +class PluginI : public IceSSL::PluginI +{ +public: + + PluginI(const Ice::CommunicatorPtr&); + + virtual IceSSL::CertificatePtr create(SecCertificateRef) const; + virtual IceSSL::CertificatePtr load(const std::string&) const; + virtual IceSSL::CertificatePtr decode(const std::string&) const; +}; + +} // anonymous namespace end + +// +// Plugin implementation. +// +PluginI::PluginI(const Ice::CommunicatorPtr& com) : + IceSSL::PluginI(com, new IceSSL::SecureTransport::SSLEngine(com)) +{ +} + +IceSSL::CertificatePtr +PluginI::create(SecCertificateRef cert) const +{ + return IceSSL::SecureTransport::Certificate::create(cert); +} + +IceSSL::CertificatePtr +PluginI::load(const std::string& file) const +{ + return IceSSL::SecureTransport::Certificate::load(file); +} + +IceSSL::CertificatePtr +PluginI::decode(const std::string& encoding) const +{ + return IceSSL::SecureTransport::Certificate::load(encoding); +} + +// +// Plug-in factory function. +// +extern "C" ICESSL_API Ice::Plugin* +createIceSSL(const Ice::CommunicatorPtr& communicator, const string& /*name*/, const Ice::StringSeq& /*args*/) +{ + return new PluginI(communicator); +} + +IceSSL::CertificatePtr +IceSSL::Certificate::load(const std::string& file) +{ + return IceSSL::SecureTransport::Certificate::load(file); +} + +IceSSL::CertificatePtr +IceSSL::Certificate::decode(const std::string& encoding) +{ + return IceSSL::SecureTransport::Certificate::decode(encoding); +} diff --git a/Sources/IceSSLCpp/SecureTransportTransceiverI.cpp b/Sources/IceSSLCpp/SecureTransportTransceiverI.cpp new file mode 100644 index 0000000..2ae6518 --- /dev/null +++ b/Sources/IceSSLCpp/SecureTransportTransceiverI.cpp @@ -0,0 +1,719 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +#include +#include + +// Disable deprecation warnings from SecureTransport APIs +#include + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceSSL; +using namespace IceSSL::SecureTransport; + +namespace +{ + +string +protocolName(SSLProtocol protocol) +{ + switch(protocol) + { + case kSSLProtocol2: + return "SSL 2.0"; + case kSSLProtocol3: + return "SSL 3.0"; + case kTLSProtocol1: + return "TLS 1.0"; + case kTLSProtocol11: + return "TLS 1.1"; + case kTLSProtocol12: + return "TLS 1.2"; + default: + return "Unknown"; + } +} + +// +// Socket write callback +// +OSStatus +socketWrite(SSLConnectionRef connection, const void* data, size_t* length) +{ + const TransceiverI* transceiver = static_cast(connection); + assert(transceiver); + return transceiver->writeRaw(reinterpret_cast(data), length); +} + +// +// Socket read callback +// +OSStatus +socketRead(SSLConnectionRef connection, void* data, size_t* length) +{ + const TransceiverI* transceiver = static_cast(connection); + assert(transceiver); + return transceiver->readRaw(reinterpret_cast(data), length); +} + +TrustError errorToTrustError(CFErrorRef err) +{ + long errorCode = CFErrorGetCode(err); + switch (errorCode) + { + case errSecPathLengthConstraintExceeded: + { + return IceSSL::ICE_ENUM(TrustError, ChainTooLong); + } + case errSecUnknownCRLExtension: + case errSecUnknownCriticalExtensionFlag: + { + return IceSSL::ICE_ENUM(TrustError, HasNonSupportedCriticalExtension); + } + case errSecHostNameMismatch: + { + return IceSSL::ICE_ENUM(TrustError, HostNameMismatch); + } + case errSecCodeSigningNoBasicConstraints: + case errSecNoBasicConstraints: + case errSecNoBasicConstraintsCA: + { + return IceSSL::ICE_ENUM(TrustError, InvalidBasicConstraints); + } + case errSecMissingRequiredExtension: + case errSecUnknownCertExtension: + { + return IceSSL::ICE_ENUM(TrustError, InvalidExtension); + } + case errSecCertificateNameNotAllowed: + case errSecInvalidName: + { + return IceSSL::ICE_ENUM(TrustError, InvalidNameConstraints); + } + case errSecCertificatePolicyNotAllowed: + case errSecInvalidPolicyIdentifiers: + case errSecInvalidCertificateRef: + case errSecInvalidDigestAlgorithm: + case errSecUnsupportedKeySize: + { + return IceSSL::ICE_ENUM(TrustError, InvalidPolicyConstraints); + } + case errSecInvalidExtendedKeyUsage: + case errSecInvalidKeyUsageForPolicy: + { + return IceSSL::ICE_ENUM(TrustError, InvalidPurpose); + } + case errSecInvalidSignature: + { + return IceSSL::ICE_ENUM(TrustError, InvalidSignature); + } + case errSecCertificateExpired: + case errSecCertificateNotValidYet: + case errSecCertificateValidityPeriodTooLong: + { + return IceSSL::ICE_ENUM(TrustError, InvalidTime); + } + case errSecCreateChainFailed: + { + return IceSSL::ICE_ENUM(TrustError, PartialChain); + } + case errSecCertificateRevoked: + { + return IceSSL::ICE_ENUM(TrustError, Revoked); + } + case errSecIncompleteCertRevocationCheck: + case errSecOCSPNotTrustedToAnchor: + { + return IceSSL::ICE_ENUM(TrustError, RevocationStatusUnknown); + } + case errSecNotTrusted: + case errSecVerifyActionFailed: + { + return IceSSL::ICE_ENUM(TrustError, UntrustedRoot); + } + default: + { + return IceSSL::ICE_ENUM(TrustError, UnknownTrustFailure); + } + } +} + +TrustError +checkTrustResult(SecTrustRef trust, + const IceSSL::SecureTransport::SSLEnginePtr& engine, + const IceSSL::InstancePtr& instance, + const string& host) +{ + OSStatus err = noErr; + UniqueRef trustErr; + if(trust) + { + // Do not allow to fetch missing intermediate certificates from the network. + if((err = SecTrustSetNetworkFetchAllowed(trust, false))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + sslErrorToString(err)); + } + + UniqueRef policies(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + // Add SSL trust policy if we need to check the certificate name, otherwise use basic x509 policy. + if(engine->getCheckCertName() && !host.empty()) + { + UniqueRef hostref(toCFString(host)); + UniqueRef policy(SecPolicyCreateSSL(true, hostref.get())); + CFArrayAppendValue(policies.get(), policy.get()); + } + else + { + UniqueRef policy(SecPolicyCreateBasicX509()); + CFArrayAppendValue(policies.get(), policy.get()); + } + + int revocationCheck = engine->getRevocationCheck(); + if(revocationCheck > 0) + { + CFOptionFlags revocationFlags = kSecRevocationUseAnyAvailableMethod | kSecRevocationRequirePositiveResponse; + if(engine->getRevocationCheckCacheOnly()) + { + revocationFlags |= kSecRevocationNetworkAccessDisabled; + } + + UniqueRef revocationPolicy(SecPolicyCreateRevocation(revocationFlags)); + if(!revocationPolicy) + { + throw SecurityException(__FILE__, + __LINE__, + "IceSSL: handshake failure: error creating revocation policy"); + } + CFArrayAppendValue(policies.get(), revocationPolicy.get()); + } + + if((err = SecTrustSetPolicies(trust, policies.get()))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + sslErrorToString(err)); + } + + CFArrayRef certificateAuthorities = engine->getCertificateAuthorities(); + if(certificateAuthorities != 0) + { + if((err = SecTrustSetAnchorCertificates(trust, certificateAuthorities))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + sslErrorToString(err)); + } + SecTrustSetAnchorCertificatesOnly(trust, true); + } + + // + // Evaluate the trust + // + if(SecTrustEvaluateWithError(trust, &trustErr.get())) + { + return IceSSL::ICE_ENUM(TrustError, NoError); + } + else + { + TrustError trustError = errorToTrustError(trustErr.get()); + if(engine->getVerifyPeer() == 0) + { + if(instance->traceLevel() >= 1) + { + ostringstream os; + os << "IceSSL: ignoring certificate verification failure:\n" + << getTrustErrorDescription(trustError); + instance->logger()->trace(instance->traceCategory(), os.str()); + } + return trustError; + } + else + { + ostringstream os; + os << "IceSSL: certificate verification failure:\n" << getTrustErrorDescription(trustError); + string msg = os.str(); + if(instance->traceLevel() >= 1) + { + instance->logger()->trace(instance->traceCategory(), msg); + } + throw SecurityException(__FILE__, __LINE__, msg); + } + } + } + return IceSSL::ICE_ENUM(TrustError, UnknownTrustFailure); +} +} + +IceInternal::NativeInfoPtr +IceSSL::SecureTransport::TransceiverI::getNativeInfo() +{ + return _delegate->getNativeInfo(); +} + +IceInternal::SocketOperation +IceSSL::SecureTransport::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) +{ + if(!_connected) + { + IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer); + if(status != IceInternal::SocketOperationNone) + { + return status; + } + _connected = true; + } + + // + // Limit the size of packets passed to SSLWrite/SSLRead to avoid + // blocking and holding too much memory. + // + if(_delegate->getNativeInfo()->fd() != INVALID_SOCKET) + { + _maxSendPacketSize = + static_cast(std::max(512, IceInternal::getSendBufferSize(_delegate->getNativeInfo()->fd()))); + _maxRecvPacketSize = + static_cast(std::max(512, IceInternal::getRecvBufferSize(_delegate->getNativeInfo()->fd()))); + } + else + { + _maxSendPacketSize = 128 * 1024; // 128KB + _maxRecvPacketSize = 128 * 1024; // 128KB + } + + OSStatus err = 0; + if(!_ssl) + { + // + // Initialize SSL context + // + _ssl.reset(_engine->newContext(_incoming)); + if((err = SSLSetIOFuncs(_ssl.get(), socketRead, socketWrite))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: setting IO functions failed\n" + + sslErrorToString(err)); + } + + if((err = SSLSetConnection(_ssl.get(), reinterpret_cast(this)))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: setting SSL connection failed\n" + + sslErrorToString(err)); + } + + // + // Enable SNI + // + if(!_incoming && _engine->getServerNameIndication() && !_host.empty() && !IceInternal::isIpAddress(_host)) + { + if((err = SSLSetPeerDomainName(_ssl.get(), _host.data(), _host.length()))) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: setting SNI host failed `" + _host + "'\n" + + sslErrorToString(err)); + } + } + } + + SSLSessionState state; + SSLGetSessionState(_ssl.get(), &state); + + // + // SSL Handshake + // + while(state == kSSLHandshake || state == kSSLIdle) + { + err = SSLHandshake(_ssl.get()); + if(err == noErr) + { + break; // We're done! + } + else if(err == errSSLWouldBlock) + { + assert(_tflags & SSLWantRead || _tflags & SSLWantWrite); + return _tflags & SSLWantRead ? IceInternal::SocketOperationRead : IceInternal::SocketOperationWrite; + } + else if(err == errSSLPeerAuthCompleted) + { + assert(!_trust); + err = SSLCopyPeerTrust(_ssl.get(), &_trust.get()); + + if(_incoming && _engine->getVerifyPeer() == 1 && (err == errSSLBadCert || !_trust)) + { + // This is expected if the client doesn't provide a certificate. With 10.10 and 10.11 errSSLBadCert + // is expected, the server is configured to verify but not require the client + // certificate so we ignore the failure. In 10.12 there is no error and trust is 0. + continue; + } + if(err == noErr) + { + _trustError = checkTrustResult(_trust.get(), _engine, _instance, _host); + _verified = _trustError == IceSSL::ICE_ENUM(TrustError, NoError); + continue; // Call SSLHandshake to resume the handsake. + } + // Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error. + } + else if(err == errSSLClosedGraceful || err == errSSLClosedAbort) + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + + ostringstream os; + os << "IceSSL: ssl error occurred for new " << (_incoming ? "incoming" : "outgoing") << " connection:\n" + << _delegate->toString() << "\n" << sslErrorToString(err); + throw ProtocolException(__FILE__, __LINE__, os.str()); + } + + for(CFIndex i = 0, count = SecTrustGetCertificateCount(_trust.get()); i < count; ++i) + { + SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust.get(), i); + CFRetain(cert); + _certs.push_back(IceSSL::SecureTransport::Certificate::create(cert)); + } + + assert(_ssl); + { + SSLCipherSuite cipher; + SSLGetNegotiatedCipher(_ssl.get(), &cipher); + _cipher = _engine->getCipherName(cipher); + } + + _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(ConnectionInfo, getInfo()), toString()); + + if(_instance->engine()->securityTraceLevel() >= 1) + { + + Trace out(_instance->logger(), _instance->traceCategory()); + out << "SSL summary for " << (_incoming ? "incoming" : "outgoing") << " connection\n"; + + SSLProtocol protocol; + SSLGetNegotiatedProtocolVersion(_ssl.get(), &protocol); + const string sslProtocolName = protocolName(protocol); + + SSLCipherSuite cipher; + SSLGetNegotiatedCipher(_ssl.get(), &cipher); + const string sslCipherName = _engine->getCipherName(cipher); + + if(sslCipherName.empty()) + { + out << "unknown cipher\n"; + } + else + { + out << "cipher = " << sslCipherName << "\n"; + out << "protocol = " << sslProtocolName << "\n"; + } + out << toString(); + } + + return IceInternal::SocketOperationNone; +} + +IceInternal::SocketOperation +IceSSL::SecureTransport::TransceiverI::closing(bool initiator, const Ice::LocalException&) +{ + // If we are initiating the connection closure, wait for the peer + // to close the TCP/IP connection. Otherwise, close immediately. + return initiator ? IceInternal::SocketOperationRead : IceInternal::SocketOperationNone; +} + +void +IceSSL::SecureTransport::TransceiverI::close() +{ + _trust.reset(0); + if(_ssl) + { + SSLClose(_ssl.get()); + } + _ssl.reset(0); + + _delegate->close(); +} + +IceInternal::SocketOperation +IceSSL::SecureTransport::TransceiverI::write(IceInternal::Buffer& buf) +{ + if(!_connected) + { + return _delegate->write(buf); + } + + if(buf.i == buf.b.end()) + { + return IceInternal::SocketOperationNone; + } + + // + // It's impossible for packetSize to be more than an Int. + // + size_t packetSize = std::min(static_cast(buf.b.end() - buf.i), _maxSendPacketSize); + while(buf.i != buf.b.end()) + { + size_t processed = 0; + OSStatus err = _buffered ? SSLWrite(_ssl.get(), 0, 0, &processed) : + SSLWrite(_ssl.get(), reinterpret_cast(buf.i), packetSize, &processed); + + if(err) + { + if(err == errSSLWouldBlock) + { + if(_buffered == 0) + { + _buffered = processed; + } + assert(_tflags & SSLWantWrite); + return IceInternal::SocketOperationWrite; + } + + if(err == errSSLClosedGraceful) + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + + // + // SSL protocol errors are defined in SecureTransport.h are in the range + // -9800 to -9849 + // + if(err <= -9800 && err >= -9849) + { + throw ProtocolException(__FILE__, __LINE__, "IceSSL: error during write:\n" + sslErrorToString(err)); + } + + errno = err; + if(IceInternal::connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + } + + if(_buffered) + { + buf.i += _buffered; + _buffered = 0; + } + else + { + buf.i += processed; + } + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + + return IceInternal::SocketOperationNone; +} + +IceInternal::SocketOperation +IceSSL::SecureTransport::TransceiverI::read(IceInternal::Buffer& buf) +{ + if(!_connected) + { + return _delegate->read(buf); + } + + if(buf.i == buf.b.end()) + { + return IceInternal::SocketOperationNone; + } + + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); + + size_t packetSize = std::min(static_cast(buf.b.end() - buf.i), _maxRecvPacketSize); + while(buf.i != buf.b.end()) + { + size_t processed = 0; + OSStatus err = SSLRead(_ssl.get(), reinterpret_cast(buf.i), packetSize, &processed); + if(err) + { + if(err == errSSLWouldBlock) + { + buf.i += processed; + assert(_tflags & SSLWantRead); + return IceInternal::SocketOperationRead; + } + + if(err == errSSLClosedGraceful || err == errSSLClosedAbort) + { + throw ConnectionLostException(__FILE__, __LINE__, 0); + } + + // + // SSL protocol errors are defined in SecureTransport.h are in the range + // -9800 to -9849 + // + if(err <= -9800 && err >= -9849) + { + throw ProtocolException(__FILE__, __LINE__, "IceSSL: error during read:\n" + sslErrorToString(err)); + } + + errno = err; + if(IceInternal::connectionLost()) + { + throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + else + { + throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + } + + buf.i += processed; + + if(packetSize > static_cast(buf.b.end() - buf.i)) + { + packetSize = static_cast(buf.b.end() - buf.i); + } + } + + // + // Check if there's still buffered data to read. In this case, set the read ready status. + // + size_t buffered = 0; + OSStatus err = SSLGetBufferedReadSize(_ssl.get(), &buffered); + if(err) + { + errno = err; + throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } + _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, buffered > 0); + return IceInternal::SocketOperationNone; +} + +string +IceSSL::SecureTransport::TransceiverI::protocol() const +{ + return _instance->protocol(); +} + +string +IceSSL::SecureTransport::TransceiverI::toString() const +{ + return _delegate->toString(); +} + +string +IceSSL::SecureTransport::TransceiverI::toDetailedString() const +{ + return toString(); +} + +Ice::ConnectionInfoPtr +IceSSL::SecureTransport::TransceiverI::getInfo() const +{ + IceSSL::ExtendedConnectionInfoPtr info = ICE_MAKE_SHARED(IceSSL::ExtendedConnectionInfo); + info->underlying = _delegate->getInfo(); + info->incoming = _incoming; + info->adapterName = _adapterName; + info->cipher = _cipher; + info->certs = _certs; + info->verified = _verified; + info->errorCode = _trustError; + info->host = _incoming ? "" : _host; + return info; +} + +void +IceSSL::SecureTransport::TransceiverI::checkSendSize(const IceInternal::Buffer&) +{ +} + +void +IceSSL::SecureTransport::TransceiverI::setBufferSize(int rcvSize, int sndSize) +{ + _delegate->setBufferSize(rcvSize, sndSize); +} + +IceSSL::SecureTransport::TransceiverI::TransceiverI(const IceSSL::InstancePtr& instance, + const IceInternal::TransceiverPtr& delegate, + const string& hostOrAdapterName, + bool incoming) : + _instance(instance), + _engine(IceSSL::SecureTransport::SSLEnginePtr::dynamicCast(instance->engine())), + _host(incoming ? "" : hostOrAdapterName), + _adapterName(incoming ? hostOrAdapterName : ""), + _incoming(incoming), + _delegate(delegate), + _connected(false), + _verified(false), + _buffered(0) +{ +} + +IceSSL::SecureTransport::TransceiverI::~TransceiverI() +{ +} + +OSStatus +IceSSL::SecureTransport::TransceiverI::writeRaw(const char* data, size_t* length) const +{ + _tflags &= ~SSLWantWrite; + + try + { + IceInternal::Buffer buf(reinterpret_cast(data), reinterpret_cast(data) + *length); + IceInternal::SocketOperation op = _delegate->write(buf); + if(op == IceInternal::SocketOperationWrite) + { + *length = static_cast(buf.i - buf.b.begin()); + _tflags |= SSLWantWrite; + return errSSLWouldBlock; + } + assert(op == IceInternal::SocketOperationNone); + } + catch(const Ice::ConnectionLostException&) + { + return errSSLClosedGraceful; + } + catch(const Ice::SocketException& ex) + { + return ex.error; + } + catch(...) + { + assert(false); + return IceInternal::getSocketErrno(); + } + return noErr; +} + +OSStatus +IceSSL::SecureTransport::TransceiverI::readRaw(char* data, size_t* length) const +{ + _tflags &= ~SSLWantRead; + + try + { + IceInternal::Buffer buf(reinterpret_cast(data), reinterpret_cast(data) + *length); + IceInternal::SocketOperation op = _delegate->read(buf); + if(op == IceInternal::SocketOperationRead) + { + *length = static_cast(buf.i - buf.b.begin()); + _tflags |= SSLWantRead; + return errSSLWouldBlock; + } + assert(op == IceInternal::SocketOperationNone); + } + catch(const Ice::ConnectionLostException&) + { + return errSSLClosedGraceful; + } + catch(const Ice::SocketException& ex) + { + return ex.error; + } + catch(...) + { + assert(false); + return IceInternal::getSocketErrno(); + } + return noErr; +} diff --git a/Sources/IceSSLCpp/SecureTransportUtil.cpp b/Sources/IceSSLCpp/SecureTransportUtil.cpp new file mode 100644 index 0000000..5e79bed --- /dev/null +++ b/Sources/IceSSLCpp/SecureTransportUtil.cpp @@ -0,0 +1,868 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +using namespace Ice; +using namespace IceInternal; +using namespace IceSSL; +using namespace IceSSL::SecureTransport; +using namespace std; + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + +namespace +{ + +CFMutableDataRef +readCertFile(const string& file) +{ + ifstream is(IceUtilInternal::streamFilename(file).c_str(), ios::in | ios::binary); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } + + is.seekg(0, is.end); + size_t size = static_cast(is.tellg()); + is.seekg(0, is.beg); + + UniqueRef data(CFDataCreateMutable(kCFAllocatorDefault, static_cast(size))); + CFDataSetLength(data.get(), static_cast(size)); + is.read(reinterpret_cast(CFDataGetMutableBytePtr(data.get())), + static_cast(size)); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); + } + return data.release(); +} + +} + +string +IceSSL::SecureTransport::sslErrorToString(CFErrorRef err) +{ + ostringstream os; + if(err) + { + UniqueRef s(CFErrorCopyDescription(err)); + os << "(error: " << CFErrorGetCode(err) << " description: " << fromCFString(s.get()) << ")"; + } + return os.str(); +} + +string +IceSSL::SecureTransport::sslErrorToString(OSStatus status) +{ + ostringstream os; + os << "(error: " << status; +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) + UniqueRef s(SecCopyErrorMessageString(status, 0)); + if(s) + { + os << " description: " << fromCFString(s.get()); + } +#endif + os << ")"; + return os.str(); +} + +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) +CFDictionaryRef +IceSSL::SecureTransport::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) +{ + UniqueRef property; + UniqueRef keys(CFArrayCreate(ICE_NULLPTR, &key , 1, &kCFTypeArrayCallBacks)); + UniqueRef err; + UniqueRef values(SecCertificateCopyValues(cert, keys.get(), &err.get())); + if(err) + { + ostringstream os; + os << "IceSSL: error getting property for certificate:\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + + assert(values); + property.retain(static_cast(CFDictionaryGetValue(values.get(), key))); + return property.release(); +} + +namespace +{ + +// +// Check the certificate basic constraints to check if the certificate is marked as a CA. +// +bool +isCA(SecCertificateRef cert) +{ + UniqueRef property(getCertificateProperty(cert, kSecOIDBasicConstraints)); + if(property) + { + CFArrayRef propertyValues = static_cast(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); + for(CFIndex i = 0, size = CFArrayGetCount(propertyValues); i < size; ++i) + { + CFDictionaryRef dict = static_cast(CFArrayGetValueAtIndex(propertyValues, i)); + CFStringRef label = static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyLabel)); + if(CFEqual(label, CFSTR("Certificate Authority"))) + { + return CFEqual(static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyValue)), CFSTR("Yes")); + } + } + } + return false; +} + +// +// Load keychain items (Certificates or Private Keys) from a file. On return items param contain +// the list of items, the caller must release it. +// +CFArrayRef +loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef keychain, const string& passphrase, + const PasswordPromptPtr& prompt, int retryMax) +{ + UniqueRef data(readCertFile(file)); + + SecItemImportExportKeyParameters params; + memset(¶ms, 0, sizeof(params)); + params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + params.flags |= kSecKeyNoAccessControl; + UniqueRef passphraseHolder; + if(!passphrase.empty()) + { + passphraseHolder.reset(toCFString(passphrase)); + params.passphrase = passphraseHolder.get(); + } + + UniqueRef items; + SecExternalItemType importType = type; + SecExternalFormat format = type == kSecItemTypeUnknown ? kSecFormatPKCS12 : kSecFormatUnknown; + UniqueRef path(toCFString(file)); + OSStatus err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items.get()); + + // + // If passphrase failure and no password was configured, we obtain + // the password from the given prompt or configure the import to + // prompt the user with an alert dialog. + // + UniqueRef alertPromptHolder; + if(passphrase.empty() && + (err == errSecPassphraseRequired || err == errSecInvalidData || err == errSecPkcs12VerifyFailure)) + { + if(!prompt) + { + params.flags |= kSecKeySecurePassphrase; + ostringstream os; + os << "Enter the password for\n" << file; + alertPromptHolder.reset(toCFString(os.str())); + params.alertPrompt = alertPromptHolder.get(); + } + + int count = 0; + while((err == errSecPassphraseRequired || err == errSecInvalidData || err == errSecPkcs12VerifyFailure) && + count < retryMax) + { + if(prompt) + { + passphraseHolder.reset(toCFString(prompt->getPassword())); + params.passphrase = passphraseHolder.get(); + } + err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items.get()); + ++count; + } + } + + if(err != noErr) + { + ostringstream os; + os << "IceSSL: error reading " << (type == kSecItemTypePrivateKey ? "private key" : "certificate"); + os << " `" << file << "':\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + + if(type != kSecItemTypeUnknown && importType != kSecItemTypeAggregate && importType != type) + { + ostringstream os; + os << "IceSSL: error reading " << (type == kSecItemTypePrivateKey ? "private key" : "certificate"); + os << " `" << file << "' doesn't contain the expected item"; + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + + return items.release(); +} + +SecKeychainRef +openKeychain(const std::string& path, const std::string& keychainPassword) +{ + string keychainPath = path; + UniqueRef keychain; + OSStatus err = 0; + if(keychainPath.empty()) + { + if((err = SecKeychainCopyDefault(&keychain.get()))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to retrieve default keychain:\n" + sslErrorToString(err)); + } + } + else + { + // + // KeyChain path is relative to the current working directory. + // + if(!IceUtilInternal::isAbsolutePath(keychainPath)) + { + string cwd; + if(IceUtilInternal::getcwd(cwd) == 0) + { + keychainPath = string(cwd) + '/' + keychainPath; + } + } + + if((err = SecKeychainOpen(keychainPath.c_str(), &keychain.get()))) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" + + keychainPath + "'\n" + sslErrorToString(err)); + } + } + + SecKeychainStatus status; + err = SecKeychainGetStatus(keychain.get(), &status); + if(err == noErr) + { + const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); + if((err = SecKeychainUnlock(keychain.get(), static_cast(keychainPassword.size()), pass, pass != 0))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to unlock keychain:\n" + sslErrorToString(err)); + } + } + else if(err == errSecNoSuchKeychain) + { + const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); + keychain.reset(0); + if((err = SecKeychainCreate(keychainPath.c_str(), + static_cast(keychainPassword.size()), pass, pass == 0, 0, &keychain.get()))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to create keychain:\n" + sslErrorToString(err)); + } + } + else + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: unable to open keychain:\n" + sslErrorToString(err)); + } + + // + // Set keychain settings to avoid keychain lock. + // + SecKeychainSettings settings; + settings.version = SEC_KEYCHAIN_SETTINGS_VERS1; + settings.lockOnSleep = FALSE; + settings.useLockInterval = FALSE; + settings.lockInterval = INT_MAX; + if((err = SecKeychainSetSettings(keychain.get(), &settings))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error setting keychain settings:\n" + sslErrorToString(err)); + } + + return keychain.release(); +} + +// +// Imports a certificate private key and optionally add it to a keychain. +// +SecIdentityRef +loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password, + const PasswordPromptPtr& prompt, int retryMax) +{ + // + // Check if we already imported the certificate + // + UniqueRef hash; + UniqueRef subjectKeyProperty(getCertificateProperty(cert, kSecOIDSubjectKeyIdentifier)); + if(subjectKeyProperty) + { + CFArrayRef values = static_cast(CFDictionaryGetValue(subjectKeyProperty.get(), + kSecPropertyKeyValue)); + for(int i = 0; i < CFArrayGetCount(values); ++i) + { + CFDictionaryRef dict = static_cast(CFArrayGetValueAtIndex(values, i)); + if(CFEqual(CFDictionaryGetValue(dict, kSecPropertyKeyLabel), CFSTR("Key Identifier"))) + { + hash.retain(static_cast(CFDictionaryGetValue(dict, kSecPropertyKeyValue))); + break; + } + } + } + + const void* values[] = { keychain }; + UniqueRef searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks)); + + UniqueRef query(CFDictionaryCreateMutable(0, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); + CFDictionarySetValue(query.get(), kSecMatchSearchList, searchList.get()); + CFDictionarySetValue(query.get(), kSecAttrSubjectKeyID, hash.get()); + CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); + + UniqueRef value(0); + OSStatus err = SecItemCopyMatching(query.get(), &value.get()); + UniqueRef item(static_cast(const_cast(value.release()))); + if(err == noErr) + { + // + // If the certificate has already been imported, create the + // identity. The key should also have been imported. + // + UniqueRef identity; + err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity.get()); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: error creating certificate identity:\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + return identity.release(); + } + else if(err != errSecItemNotFound) + { + ostringstream os; + os << "IceSSL: error searching for keychain items:\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + + // + // If the certificate isn't already in the keychain, load the + // private key into the keychain and add the certificate. + // + UniqueRef items(loadKeychainItems(file, kSecItemTypePrivateKey, keychain, password, prompt, retryMax)); + CFIndex count = CFArrayGetCount(items.get()); + UniqueRef key; + for(CFIndex i = 0; i < count; ++i) + { + SecKeychainItemRef itemRef = + static_cast(const_cast(CFArrayGetValueAtIndex(items.get(), 0))); + if(SecKeyGetTypeID() == CFGetTypeID(itemRef)) + { + key.retain(reinterpret_cast(itemRef)); + break; + } + } + if(!key) + { + throw CertificateReadException(__FILE__, __LINE__, "IceSSL: no key in file `" + file + "'"); + } + + // + // Add the certificate to the keychain + // + query.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + + CFDictionarySetValue(query.get(), kSecUseKeychain, keychain); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, cert); + CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); + + value.reset(0); + err = SecItemAdd(query.get(), static_cast(&value.get())); + UniqueRef added(static_cast(value.release())); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: failure adding certificate to keychain\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + item.retain(static_cast(const_cast(CFArrayGetValueAtIndex(added.get(), 0)))); + + // + // Create the association between the private key and the certificate, + // kSecKeyLabel attribute should match the subject key identifier. + // + vector attributes; + if(hash) + { + SecKeychainAttribute attr; + attr.tag = kSecKeyLabel; + attr.data = const_cast(CFDataGetBytePtr(hash.get())); + attr.length = static_cast(CFDataGetLength(hash.get())); + attributes.push_back(attr); + } + + // + // kSecKeyPrintName attribute correspond to the keychain display + // name. + // + string label; + UniqueRef commonName(0); + if(SecCertificateCopyCommonName(item.get(), &commonName.get()) == noErr) + { + label = fromCFString(commonName.get()); + SecKeychainAttribute attr; + attr.tag = kSecKeyPrintName; + attr.data = const_cast(label.c_str()); + attr.length = static_cast(label.size()); + attributes.push_back(attr); + } + + SecKeychainAttributeList attrs; + attrs.attr = &attributes[0]; + attrs.count = static_cast(attributes.size()); + SecKeychainItemModifyAttributesAndData(reinterpret_cast(key.get()), &attrs, 0, 0); + + UniqueRef identity; + err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity.get()); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: error creating certificate identity:\n" << sslErrorToString(err); + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + return identity.release(); +} + +} // anonymous namespace end + +#else + +namespace +{ + +CFArrayRef +loadCerts(const string& file) +{ + UniqueRef certs(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + if(file.find(".pem") != string::npos) + { + vector buffer; + readFile(file, buffer); + string strbuf(buffer.begin(), buffer.end()); + string::size_type size, startpos, endpos = 0; + bool first = true; + while(true) + { + startpos = strbuf.find("-----BEGIN CERTIFICATE-----", endpos); + if(startpos != string::npos) + { + startpos += sizeof("-----BEGIN CERTIFICATE-----"); + endpos = strbuf.find("-----END CERTIFICATE-----", startpos); + if(endpos == string::npos) + { + throw InitializationException(__FILE__, __LINE__, "IceSSL: certificate " + file + + " is not a valid PEM-encoded certificate"); + } + size = endpos - startpos; + } + else if(first) + { + startpos = 0; + endpos = string::npos; + size = strbuf.size(); + } + else + { + break; + } + + vector data(IceInternal::Base64::decode(string(&buffer[startpos], size))); + UniqueRef certdata(CFDataCreate(kCFAllocatorDefault, &data[0], + static_cast(data.size()))); + UniqueRef cert(SecCertificateCreateWithData(0, certdata.get())); + if(!cert) + { + throw InitializationException(__FILE__, __LINE__, "IceSSL: certificate " + file + + " is not a valid PEM-encoded certificate"); + } + CFArrayAppendValue(const_cast(certs.get()), cert.get()); + first = false; + } + } + else + { + UniqueRef data(readCertFile(file)); + UniqueRef cert(SecCertificateCreateWithData(0, data.get())); + if(!cert) + { + throw InitializationException(__FILE__, __LINE__, "IceSSL: certificate " + file + + " is not a valid DER-encoded certificate"); + } + CFArrayAppendValue(const_cast(certs.get()), cert.get()); + } + return certs.release(); +} + +} + +#endif + +// +// Imports a certificate (it might contain an identity or certificate depending on the format). +// +CFArrayRef +IceSSL::SecureTransport::loadCertificateChain(const string& file, +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + const string& /*keyFile*/, + const std::string& /*keychainPath*/, + const string& /*keychainPassword*/, +#else + const string& keyFile, + const std::string& keychainPath, + const string& keychainPassword, +#endif + const string& password, + const PasswordPromptPtr& prompt, + int retryMax) +{ + UniqueRef chain; +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + UniqueRef cert(readCertFile(file)); + + UniqueRef settings(CFDictionaryCreateMutable(0, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + UniqueRef items; + OSStatus err; + int count = 0; + do + { + items.reset(); + UniqueRef pass(toCFString(password.empty() && prompt ? prompt->getPassword() : password)); + CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get()); + err = SecPKCS12Import(cert.get(), settings.get(), &items.get()); + ++count; + } + while(password.empty() && prompt && err == errSecAuthFailed && count < retryMax); + + if(err != noErr) + { + ostringstream os; + os << "IceSSL: unable to import certificate from file " << file << " (error = " << err << ")"; + throw InitializationException(__FILE__, __LINE__, os.str()); + } + + for(int i = 0; i < CFArrayGetCount(items.get()); ++i) + { + CFDictionaryRef dict = static_cast(CFArrayGetValueAtIndex(items.get(), i)); + SecIdentityRef identity = static_cast( + const_cast(CFDictionaryGetValue(dict, kSecImportItemIdentity))); + if(identity) + { + CFArrayRef certs = static_cast(CFDictionaryGetValue(dict, kSecImportItemCertChain)); + chain.reset(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs)); + CFArraySetValueAtIndex(const_cast(chain.get()), 0, identity); + } + } + + if(!chain) + { + ostringstream os; + os << "IceSSL: couldn't find identity in file " << file; + throw InitializationException(__FILE__, __LINE__, os.str()); + } +#else + UniqueRef keychain(openKeychain(keychainPath, keychainPassword)); + if(keyFile.empty()) + { + chain.reset(loadKeychainItems(file, kSecItemTypeUnknown, keychain.get(), password, prompt, retryMax)); + } + else + { + // + // Load the certificate, don't load into the keychain as it + // might already have been imported. + // + UniqueRef items(loadKeychainItems(file, kSecItemTypeCertificate, 0, password, prompt, retryMax)); + SecCertificateRef cert = + static_cast(const_cast(CFArrayGetValueAtIndex(items.get(), 0))); + if(SecCertificateGetTypeID() != CFGetTypeID(cert)) + { + ostringstream os; + os << "IceSSL: couldn't find certificate in `" << file << "'"; + throw CertificateReadException(__FILE__, __LINE__, os.str()); + } + + // + // Load the private key for the given certificate. This will + // add the certificate/key to the keychain if they aren't + // already present in the keychain. + // + UniqueRef identity(loadPrivateKey(keyFile, cert, keychain.get(), password, prompt, retryMax)); + chain.reset(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, items.get())); + CFArraySetValueAtIndex(const_cast(chain.get()), 0, identity.get()); + } +#endif + return chain.release(); +} + +SecCertificateRef +IceSSL::SecureTransport::loadCertificate(const string& file) +{ + UniqueRef cert; +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + UniqueRef certs(loadCerts(file)); + assert(CFArrayGetCount(certs.get()) > 0); + cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0)); +#else + UniqueRef items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); + cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0)); +#endif + return cert.release(); +} + +CFArrayRef +IceSSL::SecureTransport::loadCACertificates(const string& file) +{ +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + return loadCerts(file); +#else + UniqueRef items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); + UniqueRef certificateAuthorities(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + CFIndex count = CFArrayGetCount(items.get()); + for(CFIndex i = 0; i < count; ++i) + { + SecCertificateRef cert = + static_cast(const_cast(CFArrayGetValueAtIndex(items.get(), i))); + assert(SecCertificateGetTypeID() == CFGetTypeID(cert)); + if(isCA(cert)) + { + CFArrayAppendValue(const_cast(certificateAuthorities.get()), cert); + } + } + return certificateAuthorities.release(); +#endif +} + +CFArrayRef +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) +IceSSL::SecureTransport::findCertificateChain(const std::string&, + const std::string&, + const string& value) +#else +IceSSL::SecureTransport::findCertificateChain(const std::string& keychainPath, + const std::string& keychainPassword, + const string& value) +#endif +{ + // + // Search the keychain using key:value pairs. The following keys are supported: + // + // Label + // Serial + // Subject + // SubjectKeyId + // + // A value must be enclosed in single or double quotes if it contains whitespace. + // + UniqueRef query(CFDictionaryCreateMutable(0, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + +#if defined(ICE_USE_SECURE_TRANSPORT_MACOS) + UniqueRef keychain(openKeychain(keychainPath, keychainPassword)); + const void* values[] = { keychain.get() }; + UniqueRef searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks)); + CFDictionarySetValue(query.get(), kSecMatchSearchList, searchList.get()); +#endif + CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); + CFDictionarySetValue(query.get(), kSecMatchCaseInsensitive, kCFBooleanTrue); + + size_t start = 0; + size_t pos; + bool valid = false; + while((pos = value.find(':', start)) != string::npos) + { + string field = IceUtilInternal::toUpper(IceUtilInternal::trim(value.substr(start, pos - start))); + string arg; + if(field != "LABEL" && field != "SERIAL" && field != "SUBJECT" && field != "SUBJECTKEYID") + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unknown key in `" + value + "'"); + } + + start = pos + 1; + while(start < value.size() && (value[start] == ' ' || value[start] == '\t')) + { + ++start; + } + + if(start == value.size()) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: missing argument in `" + value + "'"); + } + + if(value[start] == '"' || value[start] == '\'') + { + size_t end = start; + ++end; + while(end < value.size()) + { + if(value[end] == value[start] && value[end - 1] != '\\') + { + break; + } + ++end; + } + if(end == value.size() || value[end] != value[start]) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unmatched quote in `" + value + "'"); + } + ++start; + arg = value.substr(start, end - start); + start = end + 1; + } + else + { + size_t end = value.find_first_of(" \t", start); + if(end == string::npos) + { + arg = value.substr(start); + start = value.size(); + } + else + { + arg = value.substr(start, end - start); + start = end + 1; + } + } + + if(field == "SUBJECT" || field == "LABEL") + { + UniqueRef v(toCFString(arg)); + CFDictionarySetValue(query.get(), field == "LABEL" ? kSecAttrLabel : kSecMatchSubjectContains, v.get()); + valid = true; + } + else if(field == "SUBJECTKEYID" || field == "SERIAL") + { + vector buffer; + if(!parseBytes(arg, buffer)) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value `" + value + "'"); + } + UniqueRef v(CFDataCreate(kCFAllocatorDefault, &buffer[0], static_cast(buffer.size()))); + CFDictionarySetValue(query.get(), field == "SUBJECTKEYID" ? kSecAttrSubjectKeyID : kSecAttrSerialNumber, + v.get()); + valid = true; + } + } + + if(!valid) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value `" + value + "'"); + } + + UniqueRef cert; + OSStatus err = SecItemCopyMatching(query.get(), (CFTypeRef*)&cert.get()); + if(err != noErr) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: find certificate `" + value + "' failed:\n" + sslErrorToString(err)); + } + + // + // Retrieve the certificate chain + // + UniqueRef policy(SecPolicyCreateSSL(true, 0)); + UniqueRef trust; + err = SecTrustCreateWithCertificates(reinterpret_cast(cert.get()), policy.get(), &trust.get()); + if(err || !trust) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error creating trust object" + + (err ? ":\n" + sslErrorToString(err) : "")); + } + + SecTrustResultType trustResult; + if((err = SecTrustEvaluate(trust.get(), &trustResult))) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: error evaluating trust:\n" + sslErrorToString(err)); + } + + CFIndex chainLength = SecTrustGetCertificateCount(trust.get()); + UniqueRef items(CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks)); + for(int i = 0; i < chainLength; ++i) + { + CFArrayAppendValue(const_cast(items.get()), SecTrustGetCertificateAtIndex(trust.get(), i)); + } + + // + // Replace the first certificate in the chain with the + // identity. + // + UniqueRef identity; +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) + + // + // SecIdentityCreateWithCertificate isn't supported on iOS so we lookup the identity + // using the certicate label. If the user added the identity with SecItemAdd the + // identity has the same label as the certificate. + // + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, cert.get()); + CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue); + UniqueRef attributes; + err = SecItemCopyMatching(query.get(), reinterpret_cast(&attributes.get())); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << sslErrorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + + // Now lookup the identity with the label + query.reset(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); + CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity); + CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes.get(), kSecAttrLabel)); + CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); + err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity.get()); + if(err == noErr) + { + UniqueRef cert2; + if((err = SecIdentityCopyCertificate(identity.get(), &cert2.get())) == noErr) + { + err = CFEqual(cert2.get(), cert.get()) ? noErr : errSecItemNotFound; + } + } +#else + err = SecIdentityCreateWithCertificate(keychain.get(), cert.get(), &identity.get()); +#endif + if(err != noErr) + { + ostringstream os; + os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << sslErrorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } + CFArraySetValueAtIndex(const_cast(items.get()), 0, identity.get()); + return items.release(); +} diff --git a/Sources/IceSSLCpp/TrustManager.cpp b/Sources/IceSSLCpp/TrustManager.cpp new file mode 100644 index 0000000..551a4ba --- /dev/null +++ b/Sources/IceSSLCpp/TrustManager.cpp @@ -0,0 +1,236 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace IceSSL; + +IceUtil::Shared* IceSSL::upCast(IceSSL::TrustManager* p) { return p; } + +TrustManager::TrustManager(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator) +{ + Ice::PropertiesPtr properties = communicator->getProperties(); + _traceLevel = properties->getPropertyAsInt("IceSSL.Trace.Security"); + string key; + try + { + key = "IceSSL.TrustOnly"; + parse(properties->getProperty(key), _rejectAll, _acceptAll); + key = "IceSSL.TrustOnly.Client"; + parse(properties->getProperty(key), _rejectClient, _acceptClient); + key = "IceSSL.TrustOnly.Server"; + parse(properties->getProperty(key), _rejectAllServer, _acceptAllServer); + Ice::PropertyDict dict = properties->getPropertiesForPrefix("IceSSL.TrustOnly.Server."); + for(Ice::PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + string name = p->first.substr(string("IceSSL.TrustOnly.Server.").size()); + key = p->first; + list reject, accept; + parse(p->second, reject, accept); + if(!reject.empty()) + { + _rejectServer[name] = reject; + } + if(!accept.empty()) + { + _acceptServer[name] = accept; + } + } + } + catch(const ParseException& ex) + { + throw Ice::PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid property " + key + ":\n" + + ex.reason); + } +} + +bool +TrustManager::verify(const ConnectionInfoPtr& info, const std::string& desc) +{ + list > reject, accept; + + if(_rejectAll.size() > 0) + { + reject.push_back(_rejectAll); + } + if(info->incoming) + { + if(_rejectAllServer.size() > 0) + { + reject.push_back(_rejectAllServer); + } + if(info->adapterName.size() > 0) + { + map >::const_iterator p = _rejectServer.find(info->adapterName); + if(p != _rejectServer.end()) + { + reject.push_back(p->second); + } + } + } + else + { + if(_rejectClient.size() > 0) + { + reject.push_back(_rejectClient); + } + } + + if(_acceptAll.size() > 0) + { + accept.push_back(_acceptAll); + } + if(info->incoming) + { + if(_acceptAllServer.size() > 0) + { + accept.push_back(_acceptAllServer); + } + if(info->adapterName.size() > 0) + { + map >::const_iterator p = _acceptServer.find(info->adapterName); + if(p != _acceptServer.end()) + { + accept.push_back(p->second); + } + } + } + else + { + if(_acceptClient.size() > 0) + { + accept.push_back(_acceptClient); + } + } + + // + // If there is nothing to match against, then we accept the cert. + // + if(reject.empty() && accept.empty()) + { + return true; + } + + // + // If there is no certificate then we match false. + // + if(info->certs.size() != 0) + { + DistinguishedName subject = info->certs[0]->getSubjectDN(); + if(_traceLevel > 0) + { + Ice::Trace trace(_communicator->getLogger(), "Security"); + if(info->incoming) + { + trace << "trust manager evaluating client:\n" << "subject = " << string(subject) << '\n' + << "adapter = " << info->adapterName << '\n'; + } + else + { + trace << "trust manager evaluating server:\n" << "subject = " << string(subject) << '\n'; + } + trace << desc; + } + + // + // Fail if we match anything in the reject set. + // + for(list >::const_iterator p = reject.begin(); p != reject.end(); ++p) + { + if(_traceLevel > 1) + { + Ice::Trace trace(_communicator->getLogger(), "Security"); + trace << "trust manager rejecting PDNs:\n"; + for(list::const_iterator r = p->begin(); r != p->end(); ++r) + { + if(r != p->begin()) + { + trace << ';'; + } + trace << string(*r); + } + } + if(match(*p, subject)) + { + return false; + } + } + + // + // Succeed if we match anything in the accept set. + // + for(list >::const_iterator p = accept.begin(); p != accept.end(); ++p) + { + if(_traceLevel > 1) + { + Ice::Trace trace(_communicator->getLogger(), "Security"); + trace << "trust manager accepting PDNs:\n"; + for(list::const_iterator r = p->begin(); r != p->end(); ++r) + { + if(r != p->begin()) + { + trace << ';'; + } + trace << string(*r); + } + } + if(match(*p, subject)) + { + return true; + } + } + + // + // At this point we accept the connection if there are no explicit accept rules. + // + return accept.empty(); + } + + return false; +} + +bool +TrustManager::match(const list< DistinguishedName>& matchSet, const DistinguishedName& subject) const +{ + for(list::const_iterator r = matchSet.begin(); r != matchSet.end(); ++r) + { + if(subject.match(*r)) + { + return true; + } + } + return false; +} + +void +TrustManager::parse(const string& value, list& reject, list& accept) const +{ + if(!value.empty()) + { + RFC2253::RDNEntrySeq dns = RFC2253::parse(value); + + for(RFC2253::RDNEntrySeq::const_iterator p = dns.begin(); p != dns.end(); ++p) + { + if(p->negate) + { + reject.push_back(DistinguishedName(p->rdn)); + } + else + { + accept.push_back(DistinguishedName(p->rdn)); + } + } + } +} diff --git a/Sources/IceSSLCpp/Util.cpp b/Sources/IceSSLCpp/Util.cpp new file mode 100644 index 0000000..95f02bd --- /dev/null +++ b/Sources/IceSSLCpp/Util.cpp @@ -0,0 +1,192 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#include +#if defined(_WIN32) +# include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __IBMCPP__ +// Work-around for xlC visibility bug +// See "ifstream::tellg visibility error" thread on IBM xlC forum +extern template class std::fpos; +#endif + +using namespace std; +using namespace Ice; +using namespace IceInternal; +using namespace IceUtil; +using namespace IceSSL; + +#if defined(__APPLE__) + +std::string +IceSSL::fromCFString(CFStringRef v) +{ + string s; + if(v) + { + CFIndex size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(v), kCFStringEncodingUTF8); + vector buffer; + buffer.resize(static_cast(size + 1)); + CFStringGetCString(v, &buffer[0], static_cast(buffer.size()), kCFStringEncodingUTF8); + s.assign(&buffer[0]); + } + return s; +} + +#endif + +#ifdef ICE_CPP11_MAPPING +IceSSL::CertificateVerifier::CertificateVerifier(std::function&)> v) : + _verify(std::move(v)) +{ +} + +bool +IceSSL::CertificateVerifier::verify(const ConnectionInfoPtr& info) +{ + return _verify(info); +} + +IceSSL::PasswordPrompt::PasswordPrompt(std::function p) : + _prompt(std::move(p)) +{ +} + +std::string +IceSSL::PasswordPrompt::getPassword() +{ + return _prompt(); +} +#endif + +bool +IceSSL::parseBytes(const string& arg, vector& buffer) +{ + string v = IceUtilInternal::toUpper(arg); + + // + // Check for any invalid characters. + // + size_t pos = v.find_first_not_of(" :0123456789ABCDEF"); + if(pos != string::npos) + { + return false; + } + + // + // Remove any separator characters. + // + ostringstream s; + for(string::const_iterator i = v.begin(); i != v.end(); ++i) + { + if(*i == ' ' || *i == ':') + { + continue; + } + s << *i; + } + v = s.str(); + + // + // Convert the bytes. + // + for(size_t i = 0, length = v.size(); i + 2 <= length;) + { + buffer.push_back(static_cast(strtol(v.substr(i, 2).c_str(), 0, 16))); + i += 2; + } + return true; +} + +void +IceSSL::readFile(const string& file, vector& buffer) +{ + ifstream is(IceUtilInternal::streamFilename(file).c_str(), ios::in | ios::binary); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file); + } + + is.seekg(0, is.end); + buffer.resize(static_cast(is.tellg())); + is.seekg(0, is.beg); + + if(!buffer.empty()) + { + is.read(&buffer[0], static_cast(buffer.size())); + if(!is.good()) + { + throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); + } + } +} + +bool +IceSSL::checkPath(const string& path, const string& defaultDir, bool dir, string& resolved) +{ +#if defined(ICE_USE_SECURE_TRANSPORT_IOS) || defined(ICE_SWIFT) + CFBundleRef bundle = CFBundleGetMainBundle(); + if(bundle) + { + UniqueRef resourceName(toCFString(path)); + UniqueRef subDirName(toCFString(defaultDir)); + UniqueRef url(CFBundleCopyResourceURL(bundle, resourceName.get(), 0, subDirName.get())); + + UInt8 filePath[PATH_MAX]; + if(CFURLGetFileSystemRepresentation(url.get(), true, filePath, sizeof(filePath))) + { + string tmp = string(reinterpret_cast(filePath)); + if((dir && IceUtilInternal::directoryExists(tmp)) || (!dir && IceUtilInternal::fileExists(tmp))) + { + resolved = tmp; + return true; + } + } + } +#endif + if(IceUtilInternal::isAbsolutePath(path)) + { + if((dir && IceUtilInternal::directoryExists(path)) || (!dir && IceUtilInternal::fileExists(path))) + { + resolved = path; + return true; + } + return false; + } + + // + // If a default directory is provided, the given path is relative to the default directory. + // + string tmp; + if(!defaultDir.empty()) + { + tmp = defaultDir + IceUtilInternal::separator + path; + } + else + { + tmp = path; + } + + if((dir && IceUtilInternal::directoryExists(tmp)) || (!dir && IceUtilInternal::fileExists(tmp))) + { + resolved = tmp; + return true; + } + return false; +} diff --git a/Sources/IceSSLCpp/include/IceSSL/AcceptorI.h b/Sources/IceSSLCpp/include/IceSSL/AcceptorI.h new file mode 100644 index 0000000..64d3297 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/AcceptorI.h @@ -0,0 +1,52 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_ACCEPTOR_I_H +#define ICESSL_ACCEPTOR_I_H + +#include +#include +#include +#include + +#include + +namespace IceSSL +{ + +class AcceptorI : public IceInternal::Acceptor, public IceInternal::NativeInfo +{ +public: + + virtual IceInternal::NativeInfoPtr getNativeInfo(); +#if defined(ICE_USE_IOCP) + virtual IceInternal::AsyncInfo* getAsyncInfo(IceInternal::SocketOperation); +#endif + + virtual void close(); + virtual IceInternal::EndpointIPtr listen(); +#if defined(ICE_USE_IOCP) + virtual void startAccept(); + virtual void finishAccept(); +#endif + virtual IceInternal::TransceiverPtr accept(); + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + +private: + + AcceptorI(const EndpointIPtr&, const InstancePtr&, const IceInternal::AcceptorPtr&, const std::string&); + virtual ~AcceptorI(); + friend class EndpointI; + + EndpointIPtr _endpoint; + const InstancePtr _instance; + const IceInternal::AcceptorPtr _delegate; + const std::string _adapterName; +}; + +} + +#endif // IceSSL namespace end diff --git a/Sources/IceSSLCpp/include/IceSSL/CertificateI.h b/Sources/IceSSLCpp/include/IceSSL/CertificateI.h new file mode 100644 index 0000000..c7b617b --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/CertificateI.h @@ -0,0 +1,64 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_CERTIFICATE_I_H +#define ICESSL_CERTIFICATE_I_H + +#include + +#include +#include + +namespace IceSSL +{ + +// +// Map a certificate OID to its alias +// +struct ICESSL_API CertificateOID +{ + const char* name; + const char* alias; +}; + +extern const ICESSL_API CertificateOID certificateOIDS[]; +extern const ICESSL_API int certificateOIDSSize; + +// +// Certificate common implementation +// +class ICESSL_API CertificateI : public virtual IceSSL::Certificate +{ +public: + + virtual bool operator!=(const IceSSL::Certificate&) const; + + virtual std::vector getX509Extensions() const; + virtual X509ExtensionPtr getX509Extension(const std::string&) const; + + virtual bool checkValidity() const; +# ifdef ICE_CPP11_MAPPING + virtual bool checkValidity(const std::chrono::system_clock::time_point& now) const; +# else + virtual bool checkValidity(const IceUtil::Time& now) const; +# endif + + virtual std::string toString() const; + +protected: + + // + // Implementations that support retrieving X509 extensions must + // reimplement this method to lazzy initialize the extensions + // list. + // + // The default implementation just throw FeatureNotSupportedException + // + virtual void loadX509Extensions() const; + mutable std::vector _extensions; +}; + +} // IceSSL namespace end + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/Config.h b/Sources/IceSSLCpp/include/IceSSL/Config.h new file mode 100644 index 0000000..d251dfa --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/Config.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_CONFIG_H +#define ICESSL_CONFIG_H + +#include + +// +// Automatically link IceSSL[D|++11|++11D].lib with Visual C++ +// +#if !defined(ICE_BUILDING_ICESSL) && defined(ICESSL_API_EXPORTS) +# define ICE_BUILDING_ICESSL +#endif + +#if defined(_MSC_VER) && !defined(ICE_BUILDING_ICESSL) +# pragma comment(lib, ICE_LIBNAME("IceSSL")) +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/ConnectionInfo.h b/Sources/IceSSLCpp/include/IceSSL/ConnectionInfo.h new file mode 100644 index 0000000..5854c3b --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/ConnectionInfo.h @@ -0,0 +1,228 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceSSL_ConnectionInfo_h__ +#define __IceSSL_ConnectionInfo_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICESSL_API +# if defined(ICE_STATIC_LIBS) +# define ICESSL_API /**/ +# elif defined(ICESSL_API_EXPORTS) +# define ICESSL_API ICE_DECLSPEC_EXPORT +# else +# define ICESSL_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceSSL +{ + +class ConnectionInfo; + +} + +namespace IceSSL +{ + +/** + * Provides access to the connection details of an SSL connection + * \headerfile IceSSL/IceSSL.h + */ +class ICE_CLASS(ICESSL_API) ConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + ICE_MEMBER(ICESSL_API) virtual ~ConnectionInfo(); + + ConnectionInfo() = default; + + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo(ConnectionInfo&&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; + ConnectionInfo& operator=(ConnectionInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param cipher The negotiated cipher suite. + * @param certs The certificate chain. + * @param verified The certificate chain verification status. + */ + ConnectionInfo(const ::std::shared_ptr<::Ice::ConnectionInfo>& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& cipher, const std::vector& certs, bool verified) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + cipher(cipher), + certs(certs), + verified(verified) + { + } + + /** + * The negotiated cipher suite. + */ + ::std::string cipher; + /** + * The certificate chain. + */ + std::vector certs; + /** + * The certificate chain verification status. + */ + bool verified; +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceSSL +{ + +using ConnectionInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceSSL +{ + +class ConnectionInfo; +/// \cond INTERNAL +ICESSL_API ::Ice::LocalObject* upCast(ConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionInfo> ConnectionInfoPtr; + +} + +namespace IceSSL +{ + +/** + * Provides access to the connection details of an SSL connection + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API ConnectionInfo : public ::Ice::ConnectionInfo +{ +public: + + typedef ConnectionInfoPtr PointerType; + + virtual ~ConnectionInfo(); + + ConnectionInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling transport or null if there's no underlying transport. + * @param incoming Whether or not the connection is an incoming or outgoing connection. + * @param adapterName The name of the adapter associated with the connection. + * @param connectionId The connection id. + * @param cipher The negotiated cipher suite. + * @param certs The certificate chain. + * @param verified The certificate chain verification status. + */ + ConnectionInfo(const ::Ice::ConnectionInfoPtr& underlying, bool incoming, const ::std::string& adapterName, const ::std::string& connectionId, const ::std::string& cipher, const std::vector& certs, bool verified) : + ::Ice::ConnectionInfo(underlying, incoming, adapterName, connectionId), + cipher(cipher), + certs(certs), + verified(verified) + { + } + +#ifdef ICE_CPP11_COMPILER + ConnectionInfo(const ConnectionInfo&) = default; + ConnectionInfo& operator=(const ConnectionInfo&) = default; +#endif + + /** + * The negotiated cipher suite. + */ + ::std::string cipher; + /** + * The certificate chain. + */ + std::vector certs; + /** + * The certificate chain verification status. + */ + bool verified; +}; + +/// \cond INTERNAL +inline bool operator==(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const ConnectionInfo& lhs, const ConnectionInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/ConnectionInfoF.h b/Sources/IceSSLCpp/include/IceSSL/ConnectionInfoF.h new file mode 100644 index 0000000..7451a6a --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/ConnectionInfoF.h @@ -0,0 +1,101 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `ConnectionInfoF.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceSSL_ConnectionInfoF_h__ +#define __IceSSL_ConnectionInfoF_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICESSL_API +# if defined(ICE_STATIC_LIBS) +# define ICESSL_API /**/ +# elif defined(ICESSL_API_EXPORTS) +# define ICESSL_API ICE_DECLSPEC_EXPORT +# else +# define ICESSL_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceSSL +{ + +class ConnectionInfo; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceSSL +{ + +using ConnectionInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceSSL +{ + +class ConnectionInfo; +/// \cond INTERNAL +ICESSL_API ::Ice::LocalObject* upCast(ConnectionInfo*); +/// \endcond +typedef ::IceInternal::Handle< ConnectionInfo> ConnectionInfoPtr; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/ConnectorI.h b/Sources/IceSSLCpp/include/IceSSL/ConnectorI.h new file mode 100644 index 0000000..5bc487a --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/ConnectorI.h @@ -0,0 +1,44 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_CONNECTOR_I_H +#define ICESSL_CONNECTOR_I_H + +#include +#include +#include + +#include + +namespace IceSSL +{ + +class EndpointI; + +class ConnectorI : public IceInternal::Connector +{ +public: + + virtual IceInternal::TransceiverPtr connect(); + + virtual Ice::Short type() const; + virtual std::string toString() const; + + virtual bool operator==(const IceInternal::Connector&) const; + virtual bool operator<(const IceInternal::Connector&) const; + +private: + + ConnectorI(const InstancePtr&, const IceInternal::ConnectorPtr&, const std::string&); + virtual ~ConnectorI(); + friend class EndpointI; + + const InstancePtr _instance; + const IceInternal::ConnectorPtr _delegate; + const std::string _host; +}; + +} // IceSSL namespace end + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/EndpointI.h b/Sources/IceSSLCpp/include/IceSSL/EndpointI.h new file mode 100644 index 0000000..0c5d32b --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/EndpointI.h @@ -0,0 +1,100 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_ENDPOINT_I_H +#define ICESSL_ENDPOINT_I_H + +#include +#include +#include +#include +#include +#include +#include + +namespace IceSSL +{ + +class EndpointI : public IceInternal::EndpointI +#ifdef ICE_CPP11_MAPPING + , public std::enable_shared_from_this +#endif +{ +public: + + EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&); + + virtual void streamWriteImpl(Ice::OutputStream*) const; + + virtual Ice::EndpointInfoPtr getInfo() const ICE_NOEXCEPT; + virtual Ice::Short type() const; + virtual const std::string& protocol() const; + + virtual Ice::Int timeout() const; + virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; + virtual const std::string& connectionId() const; + virtual IceInternal::EndpointIPtr connectionId(const ::std::string&) const; + virtual bool compress() const; + virtual IceInternal::EndpointIPtr compress(bool) const; + virtual bool datagram() const; + virtual bool secure() const; + + virtual IceInternal::TransceiverPtr transceiver() const; + virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; + virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; + virtual std::vector expandIfWildcard() const; + virtual std::vector expandHost(IceInternal::EndpointIPtr&) const; + virtual bool equivalent(const IceInternal::EndpointIPtr&) const; + virtual ::Ice::Int hash() const; + virtual std::string options() const; + + EndpointIPtr endpoint(const IceInternal::EndpointIPtr&) const; + +#ifdef ICE_CPP11_MAPPING + virtual bool operator==(const Ice::Endpoint&) const; + virtual bool operator<(const Ice::Endpoint&) const; +#else + virtual bool operator==(const Ice::LocalObject&) const; + virtual bool operator<(const Ice::LocalObject&) const; +#endif + +protected: + + virtual bool checkOption(const std::string&, const std::string&, const std::string&); + +private: + + // + // All members are const, because endpoints are immutable. + // + const InstancePtr _instance; + const IceInternal::EndpointIPtr _delegate; +}; + +class EndpointFactoryI : public IceInternal::EndpointFactoryWithUnderlying +{ +public: + + EndpointFactoryI(const InstancePtr&, Ice::Short); + + virtual void destroy(); + + virtual IceInternal::EndpointFactoryPtr + cloneWithUnderlying(const IceInternal::ProtocolInstancePtr&, Ice::Short) const; + +protected: + + virtual IceInternal::EndpointIPtr + createWithUnderlying(const IceInternal::EndpointIPtr&, std::vector&, bool) const; + virtual IceInternal::EndpointIPtr + readWithUnderlying(const IceInternal::EndpointIPtr&, Ice::InputStream*) const; + +private: + + InstancePtr _sslInstance; +}; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/EndpointInfo.h b/Sources/IceSSLCpp/include/IceSSL/EndpointInfo.h new file mode 100644 index 0000000..d9e770b --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/EndpointInfo.h @@ -0,0 +1,186 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `EndpointInfo.ice' +// +// Warning: do not edit this file. +// +// +// + +#ifndef __IceSSL_EndpointInfo_h__ +#define __IceSSL_EndpointInfo_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ICE_IGNORE_VERSION +# if ICE_INT_VERSION / 100 != 307 +# error Ice version mismatch! +# endif +# if ICE_INT_VERSION % 100 >= 50 +# error Beta header file detected +# endif +# if ICE_INT_VERSION % 100 < 10 +# error Ice patch level mismatch! +# endif +#endif + +#ifndef ICESSL_API +# if defined(ICE_STATIC_LIBS) +# define ICESSL_API /**/ +# elif defined(ICESSL_API_EXPORTS) +# define ICESSL_API ICE_DECLSPEC_EXPORT +# else +# define ICESSL_API ICE_DECLSPEC_IMPORT +# endif +#endif + +#ifdef ICE_CPP11_MAPPING // C++11 mapping + +namespace IceSSL +{ + +class EndpointInfo; + +} + +namespace IceSSL +{ + +/** + * Provides access to an SSL endpoint information. + * \headerfile IceSSL/IceSSL.h + */ +class ICE_CLASS(ICESSL_API) EndpointInfo : public ::Ice::EndpointInfo +{ +public: + + ICE_MEMBER(ICESSL_API) virtual ~EndpointInfo(); + + EndpointInfo() = default; + + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo(EndpointInfo&&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; + EndpointInfo& operator=(EndpointInfo&&) = default; + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + */ + EndpointInfo(const ::std::shared_ptr<::Ice::EndpointInfo>& underlying, int timeout, bool compress) : + ::Ice::EndpointInfo(underlying, timeout, compress) + { + } +}; + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +/// \cond INTERNAL +namespace IceSSL +{ + +using EndpointInfoPtr = ::std::shared_ptr; + +} +/// \endcond + +#else // C++98 mapping + +namespace IceSSL +{ + +class EndpointInfo; +/// \cond INTERNAL +ICESSL_API ::Ice::LocalObject* upCast(EndpointInfo*); +/// \endcond +typedef ::IceInternal::Handle< EndpointInfo> EndpointInfoPtr; + +} + +namespace IceSSL +{ + +/** + * Provides access to an SSL endpoint information. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API EndpointInfo : public ::Ice::EndpointInfo +{ +public: + + typedef EndpointInfoPtr PointerType; + + virtual ~EndpointInfo(); + + EndpointInfo() + { + } + + /** + * One-shot constructor to initialize all data members. + * @param underlying The information of the underyling endpoint of null if there's no underlying endpoint. + * @param timeout The timeout for the endpoint in milliseconds. + * @param compress Specifies whether or not compression should be used if available when using this endpoint. + */ + EndpointInfo(const ::Ice::EndpointInfoPtr& underlying, ::Ice::Int timeout, bool compress) : + ::Ice::EndpointInfo(underlying, timeout, compress) + { + } + +#ifdef ICE_CPP11_COMPILER + EndpointInfo(const EndpointInfo&) = default; + EndpointInfo& operator=(const EndpointInfo&) = default; +#endif +}; + +/// \cond INTERNAL +inline bool operator==(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +inline bool operator<(const EndpointInfo& lhs, const EndpointInfo& rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +/// \endcond + +} + +/// \cond STREAM +namespace Ice +{ + +} +/// \endcond + +#endif + +#include +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/IceSSL.h b/Sources/IceSSLCpp/include/IceSSL/IceSSL.h new file mode 100644 index 0000000..3034904 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/IceSSL.h @@ -0,0 +1,24 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_ICESSL_H +#define ICESSL_ICESSL_H + +#include +#include +#include + +#if defined(_WIN32) +# include +#elif defined(__APPLE__) +# include +#else +# include +#endif + +#include +#include +#include + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/Instance.h b/Sources/IceSSLCpp/include/IceSSL/Instance.h new file mode 100644 index 0000000..584fe0c --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/Instance.h @@ -0,0 +1,37 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_INSTANCE_H +#define ICESSL_INSTANCE_H + +#include +#include +#include + +namespace IceSSL +{ + +class ICESSL_API Instance : public IceInternal::ProtocolInstance +{ +public: + + Instance(const SSLEnginePtr&, Ice::Short, const std::string&); + virtual ~Instance(); + + SSLEnginePtr + engine() const + { + return _engine; + } + + bool initialized() const; + +private: + + const SSLEnginePtr _engine; +}; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/InstanceF.h b/Sources/IceSSLCpp/include/IceSSL/InstanceF.h new file mode 100644 index 0000000..5f9b721 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/InstanceF.h @@ -0,0 +1,33 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_INSTANCE_F_H +#define ICESSL_INSTANCE_F_H + +#include +#include +#include + +namespace IceSSL +{ + +class Instance; +ICESSL_API IceUtil::Shared* upCast(Instance*); +typedef IceInternal::Handle InstancePtr; + +class EndpointI; +#ifdef ICE_CPP11_MAPPING +typedef ::std::shared_ptr EndpointIPtr; +#else +ICESSL_API IceUtil::Shared* upCast(EndpointI*); +typedef IceInternal::Handle EndpointIPtr; +#endif + +class AcceptorI; +ICESSL_API IceUtil::Shared* upCast(AcceptorI*); +typedef IceInternal::Handle AcceptorIPtr; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/Plugin.h b/Sources/IceSSLCpp/include/IceSSL/Plugin.h new file mode 100644 index 0000000..288201d --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/Plugin.h @@ -0,0 +1,712 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_PLUGIN_H +#define ICESSL_PLUGIN_H + +#include +#include +#include + +#ifdef ICE_CPP11_MAPPING +# include +#else +# include +#endif + +#include +#include + +#ifndef ICESSL_API +# if defined(ICE_STATIC_LIBS) +# define ICESSL_API /**/ +# elif defined(ICESSL_API_EXPORTS) +# define ICESSL_API ICE_DECLSPEC_EXPORT +# else +# define ICESSL_API ICE_DECLSPEC_IMPORT +# endif +#endif + +namespace IceSSL +{ + +/** + * The reason for an IceSSL certificate verification failure. + */ +#ifdef ICE_CPP11_MAPPING +enum class TrustError : unsigned char +#else +enum TrustError +#endif +{ + /** The certification verification succeed */ + NoError = 0, + /** The certificate chain length is greater than the specified maximum depth **/ + ChainTooLong, + /** The X509 chain is invalid because a certificate has excluded a name constraint **/ + HasExcludedNameConstraint, + /** The certificate has an undefined name constraint **/ + HasNonDefinedNameConstraint, + /** The certificate has a non permitted name constraint **/ + HasNonPermittedNameConstraint, + /** The certificate does not support a critical extension **/ + HasNonSupportedCriticalExtension, + /** The certificate does not have a supported name constraint or has a name constraint that is unsupported **/ + HasNonSupportedNameConstraint, + /** A host name mismatch has occurred **/ + HostNameMismatch, + /** The X509 chain is invalid due to invalid basic constraints **/ + InvalidBasicConstraints, + /** The X509 chain is invalid due to an invalid extension **/ + InvalidExtension, + /** The X509 chain is invalid due to invalid name constraints **/ + InvalidNameConstraints, + /** The X509 chain is invalid due to invalid policy constraints **/ + InvalidPolicyConstraints, + /** The supplied certificate cannot be used for the specified purpose **/ + InvalidPurpose, + /** The X509 chain is invalid due to an invalid certificate signature **/ + InvalidSignature, + /** The X509 chain is not valid due to an invalid time value, such as a value that indicates an expired + certificate **/ + InvalidTime, + /** The certificate is explicitly not trusted **/ + NotTrusted, + /** The X509 chain could not be built up to the root certificate **/ + PartialChain, + /** It is not possible to determine whether the certificate has been revoked **/ + RevocationStatusUnknown, + /** The X509 chain is invalid due to a revoked certificate **/ + Revoked, + /** The X509 chain is invalid due to an untrusted root certificate **/ + UntrustedRoot, + /** The X509 chain is invalid due to other unknown failure **/ + UnknownTrustFailure, +}; + +ICESSL_API TrustError getTrustError(const IceSSL::ConnectionInfoPtr&); +ICESSL_API std::string getTrustErrorDescription(TrustError); +ICESSL_API std::string getHost(const IceSSL::ConnectionInfoPtr&); + +/** + * The key usage "digitalSignature" bit is set + */ +const unsigned int KEY_USAGE_DIGITAL_SIGNATURE = 1u << 0; +/** + * The key usage "nonRepudiation" bit is set + */ +const unsigned int KEY_USAGE_NON_REPUDIATION = 1u << 1; +/** + * The key usage "keyEncipherment" bit is set + */ +const unsigned int KEY_USAGE_KEY_ENCIPHERMENT = 1u << 2; +/** + * The key usage "dataEncipherment" bit is set + */ +const unsigned int KEY_USAGE_DATA_ENCIPHERMENT = 1u << 3; +/** + * The key usage "keyAgreement" bit is set + */ +const unsigned int KEY_USAGE_KEY_AGREEMENT = 1u << 4; +/** + * The key usage "keyCertSign" bit is set + */ +const unsigned int KEY_USAGE_KEY_CERT_SIGN = 1u << 5; +/** + * The key usage "cRLSign" bit is set + */ +const unsigned int KEY_USAGE_CRL_SIGN = 1u << 6; +/** + * The key usage "encipherOnly" bit is set + */ +const unsigned int KEY_USAGE_ENCIPHER_ONLY = 1u << 7; +/** + * The key usage "decipherOnly" bit is set + */ +const unsigned int KEY_USAGE_DECIPHER_ONLY = 1u << 8; + +/** + * The extended key usage "anyKeyUsage" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_ANY_KEY_USAGE = 1u << 0; +/** + * The extended key usage "serverAuth" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_SERVER_AUTH = 1u << 1; +/** + * The extended key usage "clientAuth" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_CLIENT_AUTH = 1u << 2; +/** + * The extended key usage "codeSigning" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_CODE_SIGNING = 1u << 3; +/** + * The extended key usage "emailProtection" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_EMAIL_PROTECTION = 1u << 4; +/** + * The extended key usage "timeStamping" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_TIME_STAMPING = 1u << 5; +/** + * The extended key usage "OCSPSigning" bit is set + */ +const unsigned int EXTENDED_KEY_USAGE_OCSP_SIGNING = 1u << 6; + +/** + * Thrown if the certificate cannot be read. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API CertificateReadException : public IceUtil::ExceptionHelper +{ +public: + + CertificateReadException(const char*, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~CertificateReadException() throw(); +#endif + + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + /** + * Creates a shallow copy of this exception. + * @return The new exception instance. + */ + virtual CertificateReadException* ice_clone() const; +#endif + + /** The reason for the exception. */ + std::string reason; + +private: + + static const char* _name; +}; + +/** + * Thrown if the certificate cannot be encoded. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API CertificateEncodingException : public IceUtil::ExceptionHelper +{ +public: + + CertificateEncodingException(const char*, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~CertificateEncodingException() throw(); +#endif + + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + /** + * Creates a shallow copy of this exception. + * @return The new exception instance. + */ + virtual CertificateEncodingException* ice_clone() const; +#endif + + /** The reason for the exception. */ + std::string reason; + +private: + + static const char* _name; +}; + +/** + * This exception is thrown if a distinguished name cannot be parsed. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API ParseException : public IceUtil::ExceptionHelper +{ +public: + + ParseException(const char*, int, const std::string&); + +#ifndef ICE_CPP11_COMPILER + virtual ~ParseException() throw(); +#endif + + virtual std::string ice_id() const; + +#ifndef ICE_CPP11_MAPPING + /** + * Creates a shallow copy of this exception. + * @return The new exception instance. + */ + virtual ParseException* ice_clone() const; +#endif + + /** The reason for the exception. */ + std::string reason; + +private: + + static const char* _name; +}; + +/** + * This class represents a DistinguishedName, similar to the Java + * type X500Principal and the .NET type X500DistinguishedName. + * + * For comparison purposes, the value of a relative distinguished + * name (RDN) component is always unescaped before matching, + * therefore "ZeroC, Inc." will match ZeroC\, Inc. + * + * toString() always returns exactly the same information as was + * provided in the constructor (i.e., "ZeroC, Inc." will not turn + * into ZeroC\, Inc.). + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API DistinguishedName +{ +public: + + /** + * Creates a DistinguishedName from a string encoded using the rules in RFC2253. + * @param name The encoded distinguished name. + * @throws ParseException if parsing fails. + */ + explicit DistinguishedName(const std::string& name); + + /** + * Creates a DistinguishedName from a list of RDN pairs, + * where each pair consists of the RDN's type and value. + * For example, the RDN "O=ZeroC" is represented by the + * pair ("O", "ZeroC"). + * @throws ParseException if parsing fails. + */ + explicit DistinguishedName(const std::list >&); + + /** + * Performs an exact match. The order of the RDN components is important. + */ + friend ICESSL_API bool operator==(const DistinguishedName&, const DistinguishedName&); + + /** + * Performs an exact match. The order of the RDN components is important. + */ + friend ICESSL_API bool operator<(const DistinguishedName&, const DistinguishedName&); + + /** + * Performs a partial match with another DistinguishedName. + * @param dn The name to be matched. + * @return True if all of the RDNs in the argument are present in this + * DistinguishedName and they have the same values. + */ + bool match(const DistinguishedName& dn) const; + + /** + * Performs a partial match with another DistinguishedName. + * @param dn The name to be matched. + * @return True if all of the RDNs in the argument are present in this + * DistinguishedName and they have the same values. + */ + bool match(const std::string& dn) const; + + /** + * Encodes the DN in RFC2253 format. + * @return An encoded string. + */ + operator std::string() const; + +protected: + + /// \cond INTERNAL + void unescape(); + /// \endcond + +private: + + std::list > _rdns; + std::list > _unescaped; +}; + +/** + * Performs an exact match. The order of the RDN components is important. + */ +inline bool +operator>(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return rhs < lhs; +} + +/** + * Performs an exact match. The order of the RDN components is important. + */ +inline bool +operator<=(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return !(lhs > rhs); +} + +/** + * Performs an exact match. The order of the RDN components is important. + */ +inline bool +operator>=(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return !(lhs < rhs); +} + +/** + * Performs an exact match. The order of the RDN components is important. + */ +inline bool +operator!=(const DistinguishedName& lhs, const DistinguishedName& rhs) +{ + return !(lhs == rhs); +} + +/** + * Represents an X509 Certificate extension. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API X509Extension +#ifndef ICE_CPP11_MAPPING + : public virtual IceUtil::Shared +#endif +{ +public: + + /** + * Determines whether the information in this extension is important. + * @return True if if information is important, false otherwise. + */ + virtual bool isCritical() const = 0; + + /** + * Obtains the object ID of this extension. + * @return The object ID. + */ + virtual std::string getOID() const = 0; + + /** + * Obtains the data associated with this extension. + * @return The extension data. + */ + virtual std::vector getData() const = 0; +}; +ICE_DEFINE_PTR(X509ExtensionPtr, X509Extension); + +class Certificate; +ICE_DEFINE_PTR(CertificatePtr, Certificate); + +/** + * This convenience class is a wrapper around a native certificate. + * The interface is inspired by java.security.cert.X509Certificate. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API Certificate : +#ifdef ICE_CPP11_MAPPING + public std::enable_shared_from_this +#else + public virtual IceUtil::Shared +#endif +{ +public: + + /** + * Compares the certificates for equality using the native certificate comparison method. + */ + virtual bool operator==(const Certificate&) const = 0; + + /** + * Compares the certificates for equality using the native certificate comparison method. + */ + virtual bool operator!=(const Certificate&) const = 0; + + /** + * Obtains the authority key identifier. + * @return The identifier. + */ + virtual std::vector getAuthorityKeyIdentifier() const = 0; + + /** + * Obtains the subject key identifier. + * @return The identifier. + */ + virtual std::vector getSubjectKeyIdentifier() const = 0; + + /** + * Verifies that this certificate was signed by the given certificate + * public key. + * @param cert A certificate containing the public key. + * @return True if signed, false otherwise. + */ + virtual bool verify(const CertificatePtr& cert) const = 0; + + /** + * Obtains a string encoding of the certificate in PEM format. + * @return The encoded certificate. + * @throws CertificateEncodingException if an error occurs. + */ + virtual std::string encode() const = 0; + + /** + * Checks that the certificate is currently valid, that is, the current + * date falls between the validity period given in the certificate. + * @return True if the certificate is valid, false otherwise. + */ + virtual bool checkValidity() const = 0; + + /** + * Checks that the certificate is valid at the given time. + * @param t The target time. + * @return True if the certificate is valid, false otherwise. + */ +#ifdef ICE_CPP11_MAPPING + virtual bool checkValidity(const std::chrono::system_clock::time_point& t) const = 0; +#else + virtual bool checkValidity(const IceUtil::Time& t) const = 0; +#endif + + /** + * Returns the value of the key usage extension. The flags KEY_USAGE_DIGITAL_SIGNATURE, + * KEY_USAGE_NON_REPUDIATION, KEY_USAGE_KEY_ENCIPHERMENT, KEY_USAGE_DATA_ENCIPHERMENT + * KEY_USAGE_KEY_AGREEMENT, KEY_USAGE_KEY_CERT_SIGN, KEY_USAGE_CRL_SIGN, + * KEY_USAGE_ENCIPHER_ONLY and KEY_USAGE_DECIPHER_ONLY can be used to check what + * key usage bits are set. + */ + unsigned int getKeyUsage() const; + + /** + * Returns the value of the extended key usage extension. The flags EXTENDED_KEY_USAGE_ANY_KEY_USAGE, + * EXTENDED_KEY_USAGE_SERVER_AUTH, EXTENDED_KEY_USAGE_CLIENT_AUTH, + * EXTENDED_KEY_USAGE_CODE_SIGNING, EXTENDED_KEY_USAGE_EMAIL_PROTECTION, + * EXTENDED_KEY_USAGE_TIME_STAMPING and EXTENDED_KEY_USAGE_OCSP_SIGNING can be used to check what + * extended key usage bits are set. + */ + unsigned int getExtendedKeyUsage() const; + + /** + * Obtains the not-after validity time. + * @return The time after which this certificate is invalid. + */ +#ifdef ICE_CPP11_MAPPING + virtual std::chrono::system_clock::time_point getNotAfter() const = 0; +#else + virtual IceUtil::Time getNotAfter() const = 0; +#endif + + /** + * Obtains the not-before validity time. + * @return The time at which this certificate is valid. + */ +#ifdef ICE_CPP11_MAPPING + virtual std::chrono::system_clock::time_point getNotBefore() const = 0; +#else + virtual IceUtil::Time getNotBefore() const = 0; +#endif + + /** + * Obtains the serial number. This is an arbitrarily large number. + * @return The certificate's serial number. + */ + virtual std::string getSerialNumber() const = 0; + + /** + * Obtains the issuer's distinguished name (DN). + * @return The distinguished name. + */ + virtual DistinguishedName getIssuerDN() const = 0; + + /** + * Obtains the values in the issuer's alternative names extension. + * + * The returned list contains a pair of int, string. + * + * otherName [0] OtherName + * rfc822Name [1] IA5String + * dNSName [2] IA5String + * x400Address [3] ORAddress + * directoryName [4] Name + * ediPartyName [5] EDIPartyName + * uniformResourceIdentifier [6] IA5String + * iPAddress [7] OCTET STRING + * registeredID [8] OBJECT IDENTIFIER + * + * rfc822Name, dNSName, directoryName and + * uniformResourceIdentifier data is returned as a string. + * + * iPAddress is returned in dotted quad notation. IPv6 is not + * currently supported. + * + * All distinguished names are encoded in RFC2253 format. + * + * The remainder of the data will result in an empty string. Use the raw + * X509* certificate to obtain these values. + * + * @return The issuer's alternative names. + */ + virtual std::vector > getIssuerAlternativeNames() const = 0; + + /** + * Obtains the subject's distinguished name (DN). + * @return The distinguished name. + */ + virtual DistinguishedName getSubjectDN() const = 0; + + /** + * See the comment for Plugin::getIssuerAlternativeNames. + * @return The subject's alternative names. + */ + virtual std::vector > getSubjectAlternativeNames() const = 0; + + /** + * Obtains the certificate version number. + * @return The version number. + */ + virtual int getVersion() const = 0; + + /** + * Stringifies the certificate. This is a human readable version of + * the certificate, not a DER or PEM encoding. + * @return A string version of the certificate. + */ + virtual std::string toString() const = 0; + + /** + * Obtains a list of the X509v3 extensions contained in the certificate. + * @return The extensions. + */ + virtual std::vector getX509Extensions() const = 0; + + /** + * Obtains the extension with the given OID. + * @return The extension, or null if the certificate + * does not contain a extension with the given OID. + */ + virtual X509ExtensionPtr getX509Extension(const std::string& oid) const = 0; + + /** + * Loads the certificate from a file. The certificate must use the + * PEM encoding format. + * @param file The certificate file. + * @return The new certificate instance. + * @throws CertificateReadException if the file cannot be read. + */ + static CertificatePtr load(const std::string& file); + + /** + * Decodes a certificate from a string that uses the PEM encoding format. + * @param str A string containing the encoded certificate. + * @throws CertificateEncodingException if an error occurs. + */ + static CertificatePtr decode(const std::string& str); +}; + +#ifndef ICE_CPP11_MAPPING // C++98 mapping + +/** + * An application can customize the certificate verification process + * by implementing the CertificateVerifier interface. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API CertificateVerifier : public IceUtil::Shared +{ +public: + + virtual ~CertificateVerifier(); + + /** + * Determines whether to accept a certificate. + * @param info Information about the connection. + * @return False if the connection should be rejected, or true to allow it. + */ + virtual bool verify(const ConnectionInfoPtr& info) = 0; +}; +typedef IceUtil::Handle CertificateVerifierPtr; + +/** + * In order to read an encrypted file, such as one containing a + * private key, OpenSSL requests a password from IceSSL. The password + * can be defined using an IceSSL configuration property, but a + * plain-text password is a security risk. If a password is not + * supplied via configuration, IceSSL allows OpenSSL to prompt the + * user interactively. This may not be desirable (or even possible), + * so the application can supply an implementation of PasswordPrompt + * to take responsibility for obtaining the password. + * + * Note that the password is needed during plug-in initialization, so + * in general you will need to delay initialization (by defining + * IceSSL.DelayInit=1), configure the PasswordPrompt, then manually + * initialize the plug-in. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API PasswordPrompt : public IceUtil::Shared +{ +public: + + virtual ~PasswordPrompt(); + + /** + * Obtains the password. This method may be invoked repeatedly, such as when + * several encrypted files are opened, or when multiple password + * attempts are allowed. + * @return The clear-text password. + */ + virtual std::string getPassword() = 0; +}; +typedef IceUtil::Handle PasswordPromptPtr; +#endif + +/** + * Represents the IceSSL plug-in object. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API Plugin : public Ice::Plugin +{ +public: + + virtual ~Plugin(); + + /** + * Establish the certificate verifier object. This should be done + * before any connections are established. + * @param v The verifier. + */ +#ifdef ICE_CPP11_MAPPING + virtual void setCertificateVerifier(std::function&)> v) = 0; +#else + virtual void setCertificateVerifier(const CertificateVerifierPtr& v) = 0; +#endif + + /** + * Establish the password prompt object. This must be done before + * the plug-in is initialized. + * @param p The password prompt. + */ +#ifdef ICE_CPP11_MAPPING + virtual void setPasswordPrompt(std::function p) = 0; +#else + virtual void setPasswordPrompt(const PasswordPromptPtr& p) = 0; +#endif + + /** + * Load the certificate from a file. The certificate must use the + * PEM encoding format. + * @param file The certificate file. + * @throws CertificateReadException if the file cannot be read. + */ + virtual CertificatePtr load(const std::string& file) const = 0; + + /** + * Decode a certificate from a string that uses the PEM encoding + * format. + * @param str A string containing the encoded certificate. + * @throws CertificateEncodingException if an error occurs. + */ + virtual CertificatePtr decode(const std::string& str) const = 0; +}; +ICE_DEFINE_PTR(PluginPtr, Plugin); + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/PluginI.h b/Sources/IceSSLCpp/include/IceSSL/PluginI.h new file mode 100644 index 0000000..6cd7973 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/PluginI.h @@ -0,0 +1,67 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_PLUGIN_I_H +#define ICESSL_PLUGIN_I_H + +#include +#include +#include +#include + +namespace IceSSL +{ + +class ExtendedConnectionInfo : public ConnectionInfo +{ +public: + + TrustError errorCode; + std::string host; +}; +ICE_DEFINE_PTR(ExtendedConnectionInfoPtr, ExtendedConnectionInfo); + +// TODO: This class provides new certificate virtual methods that canot be added directly to the certificate class +// without breaking binary compatibility. The class can be removed once the relevant methods can be marked as virtual in +// the certificate class in the next major release (3.8.x). +class ICESSL_API CertificateExtendedInfo +{ +public: + + virtual unsigned int getKeyUsage() const = 0; + virtual unsigned int getExtendedKeyUsage() const = 0; +}; + +class ICESSL_API PluginI : public virtual IceSSL::Plugin +{ +public: + + PluginI(const Ice::CommunicatorPtr&, const IceSSL::SSLEnginePtr&); + // + // From Ice::Plugin. + // + virtual void initialize(); + virtual void destroy(); + + // + // From IceSSL::Plugin. + // +#ifdef ICE_CPP11_MAPPING + virtual void setCertificateVerifier(std::function&)>); + virtual void setPasswordPrompt(std::function); +#else + virtual void setCertificateVerifier(const CertificateVerifierPtr&); + virtual void setPasswordPrompt(const PasswordPromptPtr&); +#endif + + virtual CertificatePtr load(const std::string&) const = 0; + virtual CertificatePtr decode(const std::string&) const = 0; +protected: + + SSLEnginePtr _engine; +}; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/RFC2253.h b/Sources/IceSSLCpp/include/IceSSL/RFC2253.h new file mode 100644 index 0000000..a43b1ca --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/RFC2253.h @@ -0,0 +1,62 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_RFC_2253_H +#define ICESSL_RFC_2253_H + +#include +#include + +// +// The methods in the IceSSL::RFC2253 namespace implement a parser +// for relative distinguished name (RDN) pairs using the parsing +// rules outlined in sections 3 and 4 of RFC 2253. +// +// Note that this parser does not unescape the elements of the RDNs. +// For example, parsing the following RDN +// +// O=Sue\, Grabit and Runn +// +// results in the pair ("O","Sue\, Grabit and Runn") and not +// ("O","Sue, Grabit and Runn"). +// +namespace IceSSL +{ +namespace RFC2253 +{ + +typedef std::list< std::pair > RDNSeq; + +struct ICESSL_API RDNEntry +{ + RDNSeq rdn; + bool negate; +}; +typedef std::list RDNEntrySeq; + +// +// This function separates DNs with the ';' character. A list of RDN +// pairs may optionally be prefixed with '!' to indicate a negation. +// The function returns a list of RDNEntry structures. Any failure in +// parsing results in a ParseException being thrown. +// +ICESSL_API RDNEntrySeq parse(const std::string&); + +// +// RDNs are separated with ',' and ';'. +// +// This function returns a list of RDN pairs. Any failure in parsing +// results in a ParseException being thrown. +// +ICESSL_API RDNSeq parseStrict(const std::string&); + +// +// Unescape the string. +// +ICESSL_API std::string unescape(const std::string&); + +} +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SSLEngine.h b/Sources/IceSSLCpp/include/IceSSL/SSLEngine.h new file mode 100644 index 0000000..bb7adc7 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SSLEngine.h @@ -0,0 +1,100 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_ENGINE_H +#define ICESSL_ENGINE_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace IceSSL +{ + +class ICESSL_API SSLEngine : public IceUtil::Shared +{ +public: + + SSLEngine(const Ice::CommunicatorPtr&); + + Ice::CommunicatorPtr communicator() const { return _communicator; } + Ice::LoggerPtr getLogger() const { return _logger; }; + + void setCertificateVerifier(const CertificateVerifierPtr&); + void setPasswordPrompt(const PasswordPromptPtr&); + std::string password(bool); + + // + // Setup the engine. + // + virtual void initialize() = 0; + + virtual bool initialized() const; + + // + // Destroy the engine. + // + virtual void destroy() = 0; + + // + // Create a transceiver using the engine specific implementation + // + virtual IceInternal::TransceiverPtr + createTransceiver(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool) = 0; + + // + // Verify peer certificate + // + virtual void verifyPeer(const std::string&, const ConnectionInfoPtr&, const std::string&); + void verifyPeerCertName(const std::string&, const ConnectionInfoPtr&); + + CertificateVerifierPtr getCertificateVerifier() const; + PasswordPromptPtr getPasswordPrompt() const; + + std::string getPassword() const; + void setPassword(const std::string& password); + + bool getCheckCertName() const; + bool getServerNameIndication() const; + int getVerifyPeer() const; + int securityTraceLevel() const; + bool getRevocationCheckCacheOnly() const; + int getRevocationCheck() const; + std::string securityTraceCategory() const; + +protected: + + bool _initialized; + IceUtil::Mutex _mutex; + +private: + + const Ice::CommunicatorPtr _communicator; + const Ice::LoggerPtr _logger; + const TrustManagerPtr _trustManager; + + std::string _password; + CertificateVerifierPtr _verifier; + PasswordPromptPtr _prompt; + + bool _checkCertName; + bool _serverNameIndication; + int _verifyDepthMax; + int _verifyPeer; + int _securityTraceLevel; + std::string _securityTraceCategory; + const bool _revocationCheckCacheOnly; + const int _revocationCheck; +}; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SSLEngineF.h b/Sources/IceSSLCpp/include/IceSSL/SSLEngineF.h new file mode 100644 index 0000000..ad965fb --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SSLEngineF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_ENGINE_F_H +#define ICESSL_ENGINE_F_H + +#include +#include +#include + +namespace IceSSL +{ + +class SSLEngine; +ICESSL_API IceUtil::Shared* upCast(SSLEngine*); +typedef IceInternal::Handle SSLEnginePtr; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SecureTransport.h b/Sources/IceSSLCpp/include/IceSSL/SecureTransport.h new file mode 100644 index 0000000..eae04a9 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SecureTransport.h @@ -0,0 +1,72 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_SECURE_TRANSPORT_H +#define ICESSL_SECURE_TRANSPORT_H + +#ifdef __APPLE__ + +#include +#include + +namespace IceSSL +{ + +namespace SecureTransport +{ + +class Certificate; +ICE_DEFINE_PTR(CertificatePtr, Certificate); + +/** + * This convenience class is a wrapper around a native certificate. + * \headerfile IceSSL/IceSSL.h + */ +class ICESSL_API Certificate : public virtual IceSSL::Certificate +{ +public: + + /** + * Constructs a certificate using a native certificate. + * The Certificate class assumes ownership of the given native + * certificate. + * @param cert The certificate cert. + * @return The new certificate instance. + */ + static CertificatePtr create(SecCertificateRef cert); + + /** + * Loads the certificate from a file. The certificate must use the + * PEM encoding format. + * @param file The certificate file. + * @return The new certificate instance. + * @throws CertificateReadException if the file cannot be read. + */ + static CertificatePtr load(const std::string& file); + + /** + * Decodes a certificate from a string that uses the PEM encoding format. + * @param str A string containing the encoded certificate. + * @return The new certificate instance. + * @throws CertificateEncodingException if an error occurs. + */ + static CertificatePtr decode(const std::string& str); + + /** + * Obtains the native X509 certificate value wrapped by this object. + * @return A reference to the native certificate. + * The returned reference is only valid for the lifetime of this + * object. You can increment the reference count of the returned + * object with CFRetain. + */ + virtual SecCertificateRef getCert() const = 0; +}; + +} // SecureTransport namespace end + +} // IceSSL namespace end + +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngine.h b/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngine.h new file mode 100644 index 0000000..fbd97d6 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngine.h @@ -0,0 +1,59 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_SECURE_TRANSPORT_ENGINE_H +#define ICESSL_SECURE_TRANSPORT_ENGINE_H + +#ifdef __APPLE__ + +#include +#include + +#include +#include + +namespace IceSSL +{ + +namespace SecureTransport +{ + +class SSLEngine : public IceSSL::SSLEngine +{ +public: + + SSLEngine(const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual void destroy(); + virtual IceInternal::TransceiverPtr + createTransceiver(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); + + SSLContextRef newContext(bool); + CFArrayRef getCertificateAuthorities() const; + std::string getCipherName(SSLCipherSuite) const; + +private: + + void parseCiphers(const std::string&); + + IceInternal::UniqueRef _certificateAuthorities; + IceInternal::UniqueRef _chain; + + SSLProtocol _protocolVersionMax; + SSLProtocol _protocolVersionMin; + +#if TARGET_OS_IPHONE==0 + std::vector _dhParams; +#endif + std::vector _ciphers; +}; + +} // SecureTransport namespace end + +} // IceSSL namespace end + +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngineF.h b/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngineF.h new file mode 100644 index 0000000..4869a0c --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SecureTransportEngineF.h @@ -0,0 +1,29 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_SECURE_TRANSPORT_ENGINE_F_H +#define ICESSL_SECURE_TRANSPORT_ENGINE_F_H + +#ifdef __APPLE__ +#include +#include +#include + +namespace IceSSL +{ + +namespace SecureTransport +{ + +class SSLEngine; +ICESSL_API IceUtil::Shared* upCast(SSLEngine*); +typedef IceInternal::Handle SSLEnginePtr; + +} + +} + +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SecureTransportTransceiverI.h b/Sources/IceSSLCpp/include/IceSSL/SecureTransportTransceiverI.h new file mode 100644 index 0000000..88b3881 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SecureTransportTransceiverI.h @@ -0,0 +1,92 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_SECURE_TRANSPORT_TRANSCEIVER_I_H +#define ICESSL_SECURE_TRANSPORT_TRANSCEIVER_I_H + +#ifdef __APPLE__ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace IceSSL +{ + +namespace SecureTransport +{ + +class TransceiverI : public IceInternal::Transceiver +{ +public: + + virtual IceInternal::NativeInfoPtr getNativeInfo(); + + virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&); + virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&); + virtual void close(); + virtual IceInternal::SocketOperation write(IceInternal::Buffer&); + virtual IceInternal::SocketOperation read(IceInternal::Buffer&); + + virtual std::string protocol() const; + virtual std::string toString() const; + virtual std::string toDetailedString() const; + virtual Ice::ConnectionInfoPtr getInfo() const; + virtual void checkSendSize(const IceInternal::Buffer&); + virtual void setBufferSize(int rcvSize, int sndSize); + + OSStatus writeRaw(const char*, size_t*) const; + OSStatus readRaw(char*, size_t*) const; + +private: + + TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool); + virtual ~TransceiverI(); + + friend class IceSSL::SecureTransport::SSLEngine; + + const InstancePtr _instance; + const SSLEnginePtr _engine; + const std::string _host; + const std::string _adapterName; + const bool _incoming; + const IceInternal::TransceiverPtr _delegate; + + IceInternal::UniqueRef _ssl; + IceInternal::UniqueRef _trust; + bool _connected; + + enum SSLWantFlags + { + SSLWantRead = 0x1, + SSLWantWrite = 0x2 + }; + + mutable Ice::Byte _tflags; + size_t _maxSendPacketSize; + size_t _maxRecvPacketSize; + std::string _cipher; + std::vector _certs; + TrustError _trustError; + bool _verified; + size_t _buffered; +}; +typedef IceUtil::Handle TransceiverIPtr; + +} // SecureTransport namespace end + +} // IceSSL namespace end + +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/SecureTransportUtil.h b/Sources/IceSSLCpp/include/IceSSL/SecureTransportUtil.h new file mode 100644 index 0000000..088af9f --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/SecureTransportUtil.h @@ -0,0 +1,45 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_SECURE_TRANSPORT_UTIL_H +#define ICESSL_SECURE_TRANSPORT_UTIL_H + +#ifdef __APPLE__ + +#include +#include + +namespace IceSSL +{ + +namespace SecureTransport +{ + +std::string sslErrorToString(CFErrorRef); +std::string sslErrorToString(OSStatus); + +# if defined(ICE_USE_SECURE_TRANSPORT_MACOS) +// +// Retrieve a certificate property +// +CFDictionaryRef getCertificateProperty(SecCertificateRef, CFTypeRef); +# endif + +// +// Read certificate from a file. +// +CFArrayRef loadCertificateChain(const std::string&, const std::string&, const std::string&, const std::string&, + const std::string&, const PasswordPromptPtr&, int); + +SecCertificateRef loadCertificate(const std::string&); +CFArrayRef loadCACertificates(const std::string&); +CFArrayRef findCertificateChain(const std::string&, const std::string&, const std::string&); + +} // SecureTransport namespace end + +} // IceSSL namespace end + +#endif + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/TrustManager.h b/Sources/IceSSLCpp/include/IceSSL/TrustManager.h new file mode 100644 index 0000000..ba379a6 --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/TrustManager.h @@ -0,0 +1,46 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_TRUST_MANAGER_H +#define ICESSL_TRUST_MANAGER_H + +#include +#include +#include +#include +#include + +namespace IceSSL +{ + +class TrustManager : public IceUtil::Shared +{ +public: + + TrustManager(const Ice::CommunicatorPtr&); + + bool verify(const ConnectionInfoPtr&, const std::string&); + +private: + + bool match(const std::list< DistinguishedName> &, const DistinguishedName&) const; + void parse(const std::string&, std::list&, std::list&) const; + + const Ice::CommunicatorPtr _communicator; + int _traceLevel; + + std::list _rejectAll; + std::list _rejectClient; + std::list _rejectAllServer; + std::map > _rejectServer; + + std::list _acceptAll; + std::list _acceptClient; + std::list _acceptAllServer; + std::map > _acceptServer; +}; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/TrustManagerF.h b/Sources/IceSSLCpp/include/IceSSL/TrustManagerF.h new file mode 100644 index 0000000..606715e --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/TrustManagerF.h @@ -0,0 +1,21 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_TRUST_MANAGER_F_H +#define ICESSL_TRUST_MANAGER_F_H + +#include + +#include + +namespace IceSSL +{ + +class TrustManager; +IceUtil::Shared* upCast(IceSSL::TrustManager*); +typedef IceInternal::Handle TrustManagerPtr; + +} + +#endif diff --git a/Sources/IceSSLCpp/include/IceSSL/Util.h b/Sources/IceSSLCpp/include/IceSSL/Util.h new file mode 100644 index 0000000..42d232d --- /dev/null +++ b/Sources/IceSSLCpp/include/IceSSL/Util.h @@ -0,0 +1,99 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// + +#ifndef ICESSL_UTIL_H +#define ICESSL_UTIL_H + +#include +#include +#include +#include + +#if defined(__APPLE__) +# include +# if TARGET_OS_IPHONE != 0 +# define ICE_USE_SECURE_TRANSPORT_IOS 1 +# else +# define ICE_USE_SECURE_TRANSPORT_MACOS 1 +# endif +#endif + +namespace IceSSL +{ + +#if defined(__APPLE__) +// +// Helper functions to use by Secure Transport. +// +std::string fromCFString(CFStringRef); + +inline CFStringRef +toCFString(const std::string& s) +{ + return CFStringCreateWithCString(ICE_NULLPTR, s.c_str(), kCFStringEncodingUTF8); +} +#endif + +#ifdef ICE_CPP11_MAPPING +// +// Adapts the C++11 functions to C++98-like callbacks +// +class ICESSL_API CertificateVerifier +{ +public: + + CertificateVerifier(std::function&)>); + bool verify(const ConnectionInfoPtr&); + +private: + + std::function&)> _verify; +}; +using CertificateVerifierPtr = std::shared_ptr; + +class ICESSL_API PasswordPrompt +{ +public: + + PasswordPrompt(std::function); + std::string getPassword(); + +private: + + std::function _prompt; +}; +using PasswordPromptPtr = std::shared_ptr; +#endif + +// +// Constants for X509 certificate alt names (AltNameOther, AltNameORAddress, AltNameEDIPartyName and +// AltNameObjectIdentifier) are not supported. +// + +//const int AltNameOther = 0; +const int AltNameEmail = 1; +const int AltNameDNS = 2; +//const int AltNameORAddress = 3; +const int AltNameDirectory = 4; +//const int AltNameEDIPartyName = 5; +const int AltNameURL = 6; +const int AltNAmeIP = 7; +//const AltNameObjectIdentifier = 8; + +// +// Read a file into memory buffer. +// +ICESSL_API void readFile(const std::string&, std::vector&); + +// +// Determine if a file or directory exists, with an optional default +// directory. +// +ICESSL_API bool checkPath(const std::string&, const std::string&, bool, std::string&); + +ICESSL_API bool parseBytes(const std::string&, std::vector&); + +} + +#endif diff --git a/Sources/IceStorm/IceStorm.swift b/Sources/IceStorm/IceStorm.swift new file mode 100644 index 0000000..40d3c74 --- /dev/null +++ b/Sources/IceStorm/IceStorm.swift @@ -0,0 +1,2256 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `IceStorm.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice +import PromiseKit + +/// Information on the topic links. +public struct LinkInfo { + /// The linked topic. + public var theTopic: TopicPrx? = nil + /// The name of the linked topic. + public var name: Swift.String = "" + /// The cost of traversing this link. + public var cost: Swift.Int32 = 0 + + public init() {} + + public init(theTopic: TopicPrx?, name: Swift.String, cost: Swift.Int32) { + self.theTopic = theTopic + self.name = name + self.cost = cost + } +} + +/// An `Ice.InputStream` extension to read `LinkInfo` structured values from the stream. +public extension Ice.InputStream { + /// Read a `LinkInfo` structured value from the stream. + /// + /// - returns: `LinkInfo` - The structured value read from the stream. + func read() throws -> LinkInfo { + var v = LinkInfo() + v.theTopic = try self.read(TopicPrx.self) + v.name = try self.read() + v.cost = try self.read() + return v + } + + /// Read an optional `LinkInfo?` structured value from the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LinkInfo?` - The structured value read from the stream. + func read(tag: Swift.Int32) throws -> LinkInfo? { + guard try readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try skip(4) + return try read() as LinkInfo + } +} + +/// An `Ice.OutputStream` extension to write `LinkInfo` structured values from the stream. +public extension Ice.OutputStream { + /// Write a `LinkInfo` structured value to the stream. + /// + /// - parameter _: `LinkInfo` - The value to write to the stream. + func write(_ v: LinkInfo) { + self.write(v.theTopic) + self.write(v.name) + self.write(v.cost) + } + + /// Write an optional `LinkInfo?` structured value to the stream. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LinkInfo?` - The value to write to the stream. + func write(tag: Swift.Int32, value: LinkInfo?) { + if let v = value { + if writeOptional(tag: tag, format: .FSize) { + let pos = startSize() + write(v) + endSize(position: pos) + } + } + } +} + +/// A sequence of LinkInfo objects. +public typealias LinkInfoSeq = [LinkInfo] + +/// Helper class to read and write `LinkInfoSeq` sequence values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct LinkInfoSeqHelper { + /// Read a `LinkInfoSeq` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `LinkInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream) throws -> LinkInfoSeq { + let sz = try istr.readAndCheckSeqSize(minSize: 7) + var v = LinkInfoSeq() + v.reserveCapacity(sz) + for _ in 0 ..< sz { + let j: LinkInfo = try istr.read() + v.append(j) + } + return v + } + /// Read an optional `LinkInfoSeq?` sequence from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Swift.Int32` - The numeric tag associated with the value. + /// + /// - returns: `LinkInfoSeq` - The sequence read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> LinkInfoSeq? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `LinkInfoSeq` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `LinkInfoSeq` - The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: LinkInfoSeq) { + ostr.write(size: v.count) + for item in v { + ostr.write(item) + } + } + + /// Wite an optional `LinkInfoSeq?` sequence to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `LinkInfoSeq` The sequence value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: LinkInfoSeq?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// This dictionary represents quality of service parameters. +public typealias QoS = [Swift.String: Swift.String] + +/// Helper class to read and write `QoS` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct QoSHelper { + /// Read a `QoS` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `QoS` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> QoS { + let sz = try Swift.Int(istr.readSize()) + var v = QoS() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: Swift.String = try istr.read() + v[key] = value + } + return v + } + /// Read an optional `QoS?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `QoS` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> QoS? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `QoS` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `QoS` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: QoS) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `QoS?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `QoS` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: QoS?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// :nodoc: +public class LinkExists_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return LinkExists.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_LinkExists() -> Ice.UserExceptionTypeResolver { + return LinkExists_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to create a link +/// that already exists. +open class LinkExists: Ice.UserException { + /// The name of the linked topic. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::LinkExists" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: LinkExists.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class NoSuchLink_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return NoSuchLink.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_NoSuchLink() -> Ice.UserExceptionTypeResolver { + return NoSuchLink_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to remove a +/// link that does not exist. +open class NoSuchLink: Ice.UserException { + /// The name of the link that does not exist. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::NoSuchLink" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: NoSuchLink.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class AlreadySubscribed_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return AlreadySubscribed.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_AlreadySubscribed() -> Ice.UserExceptionTypeResolver { + return AlreadySubscribed_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to subscribe +/// a proxy for which a subscription already exists. +open class AlreadySubscribed: Ice.UserException { + public required init() {} + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::AlreadySubscribed" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: AlreadySubscribed.ice_staticId(), compactId: -1, last: true) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + try istr.endSlice() + } +} + +/// :nodoc: +public class InvalidSubscriber_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return InvalidSubscriber.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_InvalidSubscriber() -> Ice.UserExceptionTypeResolver { + return InvalidSubscriber_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to subscribe +/// a proxy that is null. +open class InvalidSubscriber: Ice.UserException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::InvalidSubscriber" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: InvalidSubscriber.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class BadQoS_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return BadQoS.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_BadQoS() -> Ice.UserExceptionTypeResolver { + return BadQoS_TypeResolver() + } +} + +/// This exception indicates that a subscription failed due to an +/// invalid QoS. +open class BadQoS: Ice.UserException { + /// The reason for the failure. + public var reason: Swift.String = "" + + public required init() {} + + public init(reason: Swift.String) { + self.reason = reason + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::BadQoS" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: BadQoS.ice_staticId(), compactId: -1, last: true) + ostr.write(self.reason) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.reason = try istr.read() + try istr.endSlice() + } +} + +/// Traits for Slice interface `Topic`. +public struct TopicTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceStorm::Topic"] + public static let staticId = "::IceStorm::Topic" +} + +/// Mapping of topic name to topic proxy. +public typealias TopicDict = [Swift.String: TopicPrx?] + +/// Helper class to read and write `TopicDict` dictionary values from +/// `Ice.InputStream` and `Ice.OutputStream`. +public struct TopicDictHelper { + /// Read a `TopicDict` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - returns: `TopicDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream) throws -> TopicDict { + let sz = try Swift.Int(istr.readSize()) + var v = TopicDict() + for _ in 0 ..< sz { + let key: Swift.String = try istr.read() + let value: TopicPrx? = try istr.read(TopicPrx.self) + v[key] = value + } + return v + } + /// Read an optional `TopicDict?` dictionary from the stream. + /// + /// - parameter istr: `Ice.InputStream` - The stream to read from. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - returns: `TopicDict` - The dictionary read from the stream. + public static func read(from istr: Ice.InputStream, tag: Swift.Int32) throws -> TopicDict? { + guard try istr.readOptional(tag: tag, expectedFormat: .FSize) else { + return nil + } + try istr.skip(4) + return try read(from: istr) + } + + /// Wite a `TopicDict` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter value: `TopicDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, value v: TopicDict) { + ostr.write(size: v.count) + for (key, value) in v { + ostr.write(key) + ostr.write(value) + } + } + + /// Wite an optional `TopicDict?` dictionary to the stream. + /// + /// - parameter ostr: `Ice.OuputStream` - The stream to write to. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter value: `TopicDict` - The dictionary value to write to the stream. + public static func write(to ostr: Ice.OutputStream, tag: Swift.Int32, value v: TopicDict?) { + guard let val = v else { + return + } + if ostr.writeOptional(tag: tag, format: .FSize) { + let pos = ostr.startSize() + write(to: ostr, value: val) + ostr.endSize(position: pos) + } + } +} + +/// :nodoc: +public class TopicExists_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return TopicExists.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_TopicExists() -> Ice.UserExceptionTypeResolver { + return TopicExists_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to create a topic +/// that already exists. +open class TopicExists: Ice.UserException { + /// The name of the topic that already exists. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::TopicExists" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: TopicExists.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// :nodoc: +public class NoSuchTopic_TypeResolver: Ice.UserExceptionTypeResolver { + public override func type() -> Ice.UserException.Type { + return NoSuchTopic.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceStorm_NoSuchTopic() -> Ice.UserExceptionTypeResolver { + return NoSuchTopic_TypeResolver() + } +} + +/// This exception indicates that an attempt was made to retrieve a +/// topic that does not exist. +open class NoSuchTopic: Ice.UserException { + /// The name of the topic that does not exist. + public var name: Swift.String = "" + + public required init() {} + + public init(name: Swift.String) { + self.name = name + } + + /// Returns the Slice type ID of this exception. + /// + /// - returns: `Swift.String` - the Slice type ID of this exception. + open override class func ice_staticId() -> Swift.String { + return "::IceStorm::NoSuchTopic" + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: NoSuchTopic.ice_staticId(), compactId: -1, last: true) + ostr.write(self.name) + ostr.endSlice() + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.name = try istr.read() + try istr.endSlice() + } +} + +/// Traits for Slice interface `TopicManager`. +public struct TopicManagerTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceStorm::TopicManager"] + public static let staticId = "::IceStorm::TopicManager" +} + +/// Traits for Slice interface `Finder`. +public struct FinderTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceStorm::Finder"] + public static let staticId = "::IceStorm::Finder" +} + +/// Publishers publish information on a particular topic. A topic +/// logically represents a type. +/// +/// TopicPrx Methods: +/// +/// - getName: Get the name of this topic. +/// +/// - getNameAsync: Get the name of this topic. +/// +/// - getPublisher: Get a proxy to a publisher object for this topic. +/// +/// - getPublisherAsync: Get a proxy to a publisher object for this topic. +/// +/// - getNonReplicatedPublisher: Get a non-replicated proxy to a publisher object for this topic. +/// +/// - getNonReplicatedPublisherAsync: Get a non-replicated proxy to a publisher object for this topic. +/// +/// - subscribeAndGetPublisher: Subscribe with the given qos to this topic. +/// +/// - subscribeAndGetPublisherAsync: Subscribe with the given qos to this topic. +/// +/// - unsubscribe: Unsubscribe the given subscriber. +/// +/// - unsubscribeAsync: Unsubscribe the given subscriber. +/// +/// - link: Create a link to the given topic. +/// +/// - linkAsync: Create a link to the given topic. +/// +/// - unlink: Destroy the link from this topic to the given topic linkTo. +/// +/// - unlinkAsync: Destroy the link from this topic to the given topic linkTo. +/// +/// - getLinkInfoSeq: Retrieve information on the current links. +/// +/// - getLinkInfoSeqAsync: Retrieve information on the current links. +/// +/// - getSubscribers: Retrieve the list of subscribers for this topic. +/// +/// - getSubscribersAsync: Retrieve the list of subscribers for this topic. +/// +/// - destroy: Destroy the topic. +/// +/// - destroyAsync: Destroy the topic. +public protocol TopicPrx: Ice.ObjectPrx {} + +private final class TopicPrxI: Ice.ObjectPrxI, TopicPrx { + public override class func ice_staticId() -> Swift.String { + return TopicTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `TopicPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `TopicPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: TopicPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> TopicPrx? { + return try TopicPrxI.checkedCast(prx: prx, facet: facet, context: context) as TopicPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `TopicPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `TopicPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: TopicPrx.Protocol, facet: Swift.String? = nil) -> TopicPrx { + return TopicPrxI.uncheckedCast(prx: prx, facet: facet) as TopicPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `TopicPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: TopicPrx.Protocol) -> Swift.String { + return TopicTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `TopicPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `TopicPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `TopicPrx?` - The extracted proxy + func read(_ type: TopicPrx.Protocol) throws -> TopicPrx? { + return try read() as TopicPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `TopicPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `TopicPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: TopicPrx.Protocol) throws -> TopicPrx? { + return try read(tag: tag) as TopicPrxI? + } +} + +/// Publishers publish information on a particular topic. A topic +/// logically represents a type. +/// +/// TopicPrx Methods: +/// +/// - getName: Get the name of this topic. +/// +/// - getNameAsync: Get the name of this topic. +/// +/// - getPublisher: Get a proxy to a publisher object for this topic. +/// +/// - getPublisherAsync: Get a proxy to a publisher object for this topic. +/// +/// - getNonReplicatedPublisher: Get a non-replicated proxy to a publisher object for this topic. +/// +/// - getNonReplicatedPublisherAsync: Get a non-replicated proxy to a publisher object for this topic. +/// +/// - subscribeAndGetPublisher: Subscribe with the given qos to this topic. +/// +/// - subscribeAndGetPublisherAsync: Subscribe with the given qos to this topic. +/// +/// - unsubscribe: Unsubscribe the given subscriber. +/// +/// - unsubscribeAsync: Unsubscribe the given subscriber. +/// +/// - link: Create a link to the given topic. +/// +/// - linkAsync: Create a link to the given topic. +/// +/// - unlink: Destroy the link from this topic to the given topic linkTo. +/// +/// - unlinkAsync: Destroy the link from this topic to the given topic linkTo. +/// +/// - getLinkInfoSeq: Retrieve information on the current links. +/// +/// - getLinkInfoSeqAsync: Retrieve information on the current links. +/// +/// - getSubscribers: Retrieve the list of subscribers for this topic. +/// +/// - getSubscribersAsync: Retrieve the list of subscribers for this topic. +/// +/// - destroy: Destroy the topic. +/// +/// - destroyAsync: Destroy the topic. +public extension TopicPrx { + /// Get the name of this topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Swift.String` - The name of the topic. + func getName(context: Ice.Context? = nil) throws -> Swift.String { + return try _impl._invoke(operation: "getName", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context) + } + + /// Get the name of this topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNameAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getName", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Swift.String = try istr.read() + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a proxy to a publisher object for this topic. To publish + /// data to a topic, the publisher calls getPublisher and then + /// casts to the topic type. An unchecked cast must be used on this + /// proxy. If a replicated IceStorm deployment is used this call + /// may return a replicated proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to publish data on this topic. + func getPublisher(context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getPublisher", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get a proxy to a publisher object for this topic. To publish + /// data to a topic, the publisher calls getPublisher and then + /// casts to the topic type. An unchecked cast must be used on this + /// proxy. If a replicated IceStorm deployment is used this call + /// may return a replicated proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getPublisherAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getPublisher", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Get a non-replicated proxy to a publisher object for this + /// topic. To publish data to a topic, the publisher calls + /// getPublisher and then casts to the topic type. An unchecked + /// cast must be used on this proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to publish data on this topic. + func getNonReplicatedPublisher(context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "getNonReplicatedPublisher", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get a non-replicated proxy to a publisher object for this + /// topic. To publish data to a topic, the publisher calls + /// getPublisher and then casts to the topic type. An unchecked + /// cast must be used on this proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getNonReplicatedPublisherAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getNonReplicatedPublisher", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Subscribe with the given qos to this topic. A + /// per-subscriber publisher object is returned. + /// + /// - parameter theQoS: `QoS` The quality of service parameters for this + /// subscription. + /// + /// - parameter subscriber: `Ice.ObjectPrx?` The subscriber's proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.ObjectPrx?` - The per-subscriber publisher object. + /// + /// - throws: + /// + /// - AlreadySubscribed - Raised if the subscriber object is + /// already subscribed. + /// + /// - BadQoS - Raised if the requested quality of service + /// is unavailable or invalid. + /// + /// - InvalidSubscriber - Raised if the subscriber object is null. + func subscribeAndGetPublisher(theQoS iceP_theQoS: QoS, subscriber iceP_subscriber: Ice.ObjectPrx?, context: Ice.Context? = nil) throws -> Ice.ObjectPrx? { + return try _impl._invoke(operation: "subscribeAndGetPublisher", + mode: .Normal, + write: { ostr in + QoSHelper.write(to: ostr, value: iceP_theQoS) + ostr.write(iceP_subscriber) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AlreadySubscribed { + throw error + } catch let error as BadQoS { + throw error + } catch let error as InvalidSubscriber { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Subscribe with the given qos to this topic. A + /// per-subscriber publisher object is returned. + /// + /// - parameter theQoS: `QoS` The quality of service parameters for this + /// subscription. + /// + /// - parameter subscriber: `Ice.ObjectPrx?` The subscriber's proxy. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func subscribeAndGetPublisherAsync(theQoS iceP_theQoS: QoS, subscriber iceP_subscriber: Ice.ObjectPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "subscribeAndGetPublisher", + mode: .Normal, + write: { ostr in + QoSHelper.write(to: ostr, value: iceP_theQoS) + ostr.write(iceP_subscriber) + }, + read: { istr in + let iceP_returnValue: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as AlreadySubscribed { + throw error + } catch let error as BadQoS { + throw error + } catch let error as InvalidSubscriber { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Unsubscribe the given subscriber. + /// + /// - parameter _: `Ice.ObjectPrx?` The proxy of an existing subscriber. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func unsubscribe(_ iceP_subscriber: Ice.ObjectPrx?, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "unsubscribe", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_subscriber) + }, + context: context) + } + + /// Unsubscribe the given subscriber. + /// + /// - parameter _: `Ice.ObjectPrx?` The proxy of an existing subscriber. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func unsubscribeAsync(_ iceP_subscriber: Ice.ObjectPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "unsubscribe", + mode: .Idempotent, + write: { ostr in + ostr.write(iceP_subscriber) + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Create a link to the given topic. All events originating + /// on this topic will also be sent to linkTo. + /// + /// - parameter linkTo: `TopicPrx?` The topic to link to. + /// + /// - parameter cost: `Swift.Int32` The cost to the linked topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - LinkExists - Raised if a link to the same topic already + /// exists. + func link(linkTo iceP_linkTo: TopicPrx?, cost iceP_cost: Swift.Int32, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "link", + mode: .Normal, + write: { ostr in + ostr.write(iceP_linkTo) + ostr.write(iceP_cost) + }, + userException:{ ex in + do { + throw ex + } catch let error as LinkExists { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a link to the given topic. All events originating + /// on this topic will also be sent to linkTo. + /// + /// - parameter linkTo: `TopicPrx?` The topic to link to. + /// + /// - parameter cost: `Swift.Int32` The cost to the linked topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func linkAsync(linkTo iceP_linkTo: TopicPrx?, cost iceP_cost: Swift.Int32, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "link", + mode: .Normal, + write: { ostr in + ostr.write(iceP_linkTo) + ostr.write(iceP_cost) + }, + userException:{ ex in + do { + throw ex + } catch let error as LinkExists { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Destroy the link from this topic to the given topic linkTo. + /// + /// - parameter _: `TopicPrx?` The topic to destroy the link to. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - throws: + /// + /// - NoSuchLink - Raised if a link to the topic does not exist. + func unlink(_ iceP_linkTo: TopicPrx?, context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "unlink", + mode: .Normal, + write: { ostr in + ostr.write(iceP_linkTo) + }, + userException:{ ex in + do { + throw ex + } catch let error as NoSuchLink { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Destroy the link from this topic to the given topic linkTo. + /// + /// - parameter _: `TopicPrx?` The topic to destroy the link to. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func unlinkAsync(_ iceP_linkTo: TopicPrx?, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "unlink", + mode: .Normal, + write: { ostr in + ostr.write(iceP_linkTo) + }, + userException:{ ex in + do { + throw ex + } catch let error as NoSuchLink { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Retrieve information on the current links. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `LinkInfoSeq` - A sequence of LinkInfo objects. + func getLinkInfoSeq(context: Ice.Context? = nil) throws -> LinkInfoSeq { + return try _impl._invoke(operation: "getLinkInfoSeq", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: LinkInfoSeq = try LinkInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Retrieve information on the current links. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getLinkInfoSeqAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getLinkInfoSeq", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: LinkInfoSeq = try LinkInfoSeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Retrieve the list of subscribers for this topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.IdentitySeq` - The sequence of Ice identities for the subscriber objects. + func getSubscribers(context: Ice.Context? = nil) throws -> Ice.IdentitySeq { + return try _impl._invoke(operation: "getSubscribers", + mode: .Normal, + read: { istr in + let iceP_returnValue: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Retrieve the list of subscribers for this topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSubscribersAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSubscribers", + mode: .Normal, + read: { istr in + let iceP_returnValue: Ice.IdentitySeq = try Ice.IdentitySeqHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Destroy the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + func destroy(context: Ice.Context? = nil) throws { + try _impl._invoke(operation: "destroy", + mode: .Normal, + context: context) + } + + /// Destroy the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise<>` - The result of the operation + func destroyAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "destroy", + mode: .Normal, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// A topic manager manages topics, and subscribers to topics. +/// +/// TopicManagerPrx Methods: +/// +/// - create: Create a new topic. +/// +/// - createAsync: Create a new topic. +/// +/// - retrieve: Retrieve a topic by name. +/// +/// - retrieveAsync: Retrieve a topic by name. +/// +/// - retrieveAll: Retrieve all topics managed by this topic manager. +/// +/// - retrieveAllAsync: Retrieve all topics managed by this topic manager. +/// +/// - getSliceChecksums: Returns the checksums for the IceStorm Slice definitions. +/// +/// - getSliceChecksumsAsync: Returns the checksums for the IceStorm Slice definitions. +public protocol TopicManagerPrx: Ice.ObjectPrx {} + +private final class TopicManagerPrxI: Ice.ObjectPrxI, TopicManagerPrx { + public override class func ice_staticId() -> Swift.String { + return TopicManagerTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `TopicManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `TopicManagerPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: TopicManagerPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> TopicManagerPrx? { + return try TopicManagerPrxI.checkedCast(prx: prx, facet: facet, context: context) as TopicManagerPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `TopicManagerPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `TopicManagerPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: TopicManagerPrx.Protocol, facet: Swift.String? = nil) -> TopicManagerPrx { + return TopicManagerPrxI.uncheckedCast(prx: prx, facet: facet) as TopicManagerPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `TopicManagerPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: TopicManagerPrx.Protocol) -> Swift.String { + return TopicManagerTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `TopicManagerPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `TopicManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `TopicManagerPrx?` - The extracted proxy + func read(_ type: TopicManagerPrx.Protocol) throws -> TopicManagerPrx? { + return try read() as TopicManagerPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `TopicManagerPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `TopicManagerPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: TopicManagerPrx.Protocol) throws -> TopicManagerPrx? { + return try read(tag: tag) as TopicManagerPrxI? + } +} + +/// A topic manager manages topics, and subscribers to topics. +/// +/// TopicManagerPrx Methods: +/// +/// - create: Create a new topic. +/// +/// - createAsync: Create a new topic. +/// +/// - retrieve: Retrieve a topic by name. +/// +/// - retrieveAsync: Retrieve a topic by name. +/// +/// - retrieveAll: Retrieve all topics managed by this topic manager. +/// +/// - retrieveAllAsync: Retrieve all topics managed by this topic manager. +/// +/// - getSliceChecksums: Returns the checksums for the IceStorm Slice definitions. +/// +/// - getSliceChecksumsAsync: Returns the checksums for the IceStorm Slice definitions. +public extension TopicManagerPrx { + /// Create a new topic. The topic name must be unique. + /// + /// - parameter _: `Swift.String` The name of the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `TopicPrx?` - A proxy to the topic instance. + /// + /// - throws: + /// + /// - TopicExists - Raised if a topic with the same name already + /// exists. + func create(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> TopicPrx? { + return try _impl._invoke(operation: "create", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: TopicPrx? = try istr.read(TopicPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as TopicExists { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Create a new topic. The topic name must be unique. + /// + /// - parameter _: `Swift.String` The name of the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func createAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "create", + mode: .Normal, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: TopicPrx? = try istr.read(TopicPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as TopicExists { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Retrieve a topic by name. + /// + /// - parameter _: `Swift.String` The name of the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `TopicPrx?` - A proxy to the topic instance. + /// + /// - throws: + /// + /// - NoSuchTopic - Raised if the topic does not exist. + func retrieve(_ iceP_name: Swift.String, context: Ice.Context? = nil) throws -> TopicPrx? { + return try _impl._invoke(operation: "retrieve", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: TopicPrx? = try istr.read(TopicPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NoSuchTopic { + throw error + } catch is Ice.UserException {} + }, + context: context) + } + + /// Retrieve a topic by name. + /// + /// - parameter _: `Swift.String` The name of the topic. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func retrieveAsync(_ iceP_name: Swift.String, context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "retrieve", + mode: .Nonmutating, + write: { ostr in + ostr.write(iceP_name) + }, + read: { istr in + let iceP_returnValue: TopicPrx? = try istr.read(TopicPrx.self) + return iceP_returnValue + }, + userException:{ ex in + do { + throw ex + } catch let error as NoSuchTopic { + throw error + } catch is Ice.UserException {} + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Retrieve all topics managed by this topic manager. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `TopicDict` - A dictionary of string, topic proxy pairs. + func retrieveAll(context: Ice.Context? = nil) throws -> TopicDict { + return try _impl._invoke(operation: "retrieveAll", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: TopicDict = try TopicDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Retrieve all topics managed by this topic manager. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func retrieveAllAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "retrieveAll", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: TopicDict = try TopicDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } + + /// Returns the checksums for the IceStorm Slice definitions. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `Ice.SliceChecksumDict` - A dictionary mapping Slice type ids to their checksums. + func getSliceChecksums(context: Ice.Context? = nil) throws -> Ice.SliceChecksumDict { + return try _impl._invoke(operation: "getSliceChecksums", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.SliceChecksumDict = try Ice.SliceChecksumDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context) + } + + /// Returns the checksums for the IceStorm Slice definitions. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getSliceChecksumsAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getSliceChecksums", + mode: .Nonmutating, + read: { istr in + let iceP_returnValue: Ice.SliceChecksumDict = try Ice.SliceChecksumDictHelper.read(from: istr) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + +/// This inferface is advertised by the IceStorm service through the +/// Ice object with the identity `IceStorm/Finder'. This allows clients +/// to retrieve the topic manager with just the endpoint information of +/// the IceStorm service. +/// +/// FinderPrx Methods: +/// +/// - getTopicManager: Get the topic manager proxy. +/// +/// - getTopicManagerAsync: Get the topic manager proxy. +public protocol FinderPrx: Ice.ObjectPrx {} + +private final class FinderPrxI: Ice.ObjectPrxI, FinderPrx { + public override class func ice_staticId() -> Swift.String { + return FinderTraits.staticId + } +} + +/// Casts a proxy to the requested type. This call contacts the server and verifies that the object +/// implements this type. +/// +/// It will throw a local exception if a communication error occurs. You can optionally supply a +/// facet name and a context map. +/// +/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast. +/// +/// - parameter type: `FinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet. +/// +/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation. +/// +/// - returns: `FinderPrx` - A proxy with the requested type or nil if the objet does not +/// support this type. +/// +/// - throws: `Ice.LocalException` if a communication error occurs. +public func checkedCast(prx: Ice.ObjectPrx, type: FinderPrx.Protocol, facet: Swift.String? = nil, context: Ice.Context? = nil) throws -> FinderPrx? { + return try FinderPrxI.checkedCast(prx: prx, facet: facet, context: context) as FinderPrxI? +} + +/// Downcasts the given proxy to this type without contacting the remote server. +/// +/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast. +/// +/// - parameter type: `FinderPrx.Protocol` - The proxy type to cast to. +/// +/// - parameter facet: `String` - The optional name of the desired facet +/// +/// - returns: `FinderPrx` - A proxy with the requested type +public func uncheckedCast(prx: Ice.ObjectPrx, type: FinderPrx.Protocol, facet: Swift.String? = nil) -> FinderPrx { + return FinderPrxI.uncheckedCast(prx: prx, facet: facet) as FinderPrxI +} + +/// Returns the Slice type id of the interface or class associated with this proxy type. +/// +/// parameter type: `FinderPrx.Protocol` - The proxy type to retrieve the type id. +/// +/// returns: `String` - The type id of the interface or class associated with this proxy type. +public func ice_staticId(_ type: FinderPrx.Protocol) -> Swift.String { + return FinderTraits.staticId +} + +/// Extension to `Ice.InputStream` class to support reading proxy of type +/// `FinderPrx`. +public extension Ice.InputStream { + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter type: `FinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FinderPrx?` - The extracted proxy + func read(_ type: FinderPrx.Protocol) throws -> FinderPrx? { + return try read() as FinderPrxI? + } + /// Extracts a proxy from the stream. The stream must have been initialized with a communicator. + /// + /// - parameter tag: `Int32` - The numeric tag associated with the value. + /// + /// - parameter type: `FinderPrx.Protocol` - The type of the proxy to be extracted. + /// + /// - returns: `FinderPrx` - The extracted proxy. + func read(tag: Swift.Int32, type: FinderPrx.Protocol) throws -> FinderPrx? { + return try read(tag: tag) as FinderPrxI? + } +} + +/// This inferface is advertised by the IceStorm service through the +/// Ice object with the identity `IceStorm/Finder'. This allows clients +/// to retrieve the topic manager with just the endpoint information of +/// the IceStorm service. +/// +/// FinderPrx Methods: +/// +/// - getTopicManager: Get the topic manager proxy. +/// +/// - getTopicManagerAsync: Get the topic manager proxy. +public extension FinderPrx { + /// Get the topic manager proxy. The proxy might point to several + /// replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - returns: `TopicManagerPrx?` - The topic manager proxy. + func getTopicManager(context: Ice.Context? = nil) throws -> TopicManagerPrx? { + return try _impl._invoke(operation: "getTopicManager", + mode: .Normal, + read: { istr in + let iceP_returnValue: TopicManagerPrx? = try istr.read(TopicManagerPrx.self) + return iceP_returnValue + }, + context: context) + } + + /// Get the topic manager proxy. The proxy might point to several + /// replicas. + /// + /// - parameter context: `Ice.Context` - Optional request context. + /// + /// - parameter sentOn: `Dispatch.DispatchQueue?` - Optional dispatch queue used to + /// dispatch the sent callback. + /// + /// - parameter sentFlags: `Dispatch.DispatchWorkItemFlags?` - Optional dispatch flags used + /// to dispatch the sent callback + /// + /// - parameter sent: `((Swift.Bool) -> Swift.Void)` - Optional sent callback. + /// + /// - returns: `PromiseKit.Promise` - The result of the operation + func getTopicManagerAsync(context: Ice.Context? = nil, sentOn: Dispatch.DispatchQueue? = nil, sentFlags: Dispatch.DispatchWorkItemFlags? = nil, sent: ((Swift.Bool) -> Swift.Void)? = nil) -> PromiseKit.Promise { + return _impl._invokeAsync(operation: "getTopicManager", + mode: .Normal, + read: { istr in + let iceP_returnValue: TopicManagerPrx? = try istr.read(TopicManagerPrx.self) + return iceP_returnValue + }, + context: context, + sentOn: sentOn, + sentFlags: sentFlags, + sent: sent) + } +} + + +/// Dispatcher for `Topic` servants. +public struct TopicDisp: Ice.Disp { + public let servant: Topic + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Topic) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "destroy": + return try servant._iceD_destroy(incoming: request, current: current) + case "getLinkInfoSeq": + return try servant._iceD_getLinkInfoSeq(incoming: request, current: current) + case "getName": + return try servant._iceD_getName(incoming: request, current: current) + case "getNonReplicatedPublisher": + return try servant._iceD_getNonReplicatedPublisher(incoming: request, current: current) + case "getPublisher": + return try servant._iceD_getPublisher(incoming: request, current: current) + case "getSubscribers": + return try servant._iceD_getSubscribers(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? TopicDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? TopicDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? TopicDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? TopicDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "link": + return try servant._iceD_link(incoming: request, current: current) + case "subscribeAndGetPublisher": + return try servant._iceD_subscribeAndGetPublisher(incoming: request, current: current) + case "unlink": + return try servant._iceD_unlink(incoming: request, current: current) + case "unsubscribe": + return try servant._iceD_unsubscribe(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// Publishers publish information on a particular topic. A topic +/// logically represents a type. +public protocol Topic { + /// Get the name of this topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Swift.String` - The name of the topic. + func getName(current: Ice.Current) throws -> Swift.String + + /// Get a proxy to a publisher object for this topic. To publish + /// data to a topic, the publisher calls getPublisher and then + /// casts to the topic type. An unchecked cast must be used on this + /// proxy. If a replicated IceStorm deployment is used this call + /// may return a replicated proxy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to publish data on this topic. + func getPublisher(current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Get a non-replicated proxy to a publisher object for this + /// topic. To publish data to a topic, the publisher calls + /// getPublisher and then casts to the topic type. An unchecked + /// cast must be used on this proxy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - A proxy to publish data on this topic. + func getNonReplicatedPublisher(current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Subscribe with the given qos to this topic. A + /// per-subscriber publisher object is returned. + /// + /// - parameter theQoS: `QoS` The quality of service parameters for this + /// subscription. + /// + /// - parameter subscriber: `Ice.ObjectPrx?` The subscriber's proxy. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.ObjectPrx?` - The per-subscriber publisher object. + /// + /// - throws: + /// + /// - AlreadySubscribed - Raised if the subscriber object is + /// already subscribed. + /// + /// - BadQoS - Raised if the requested quality of service + /// is unavailable or invalid. + /// + /// - InvalidSubscriber - Raised if the subscriber object is null. + func subscribeAndGetPublisher(theQoS: QoS, subscriber: Ice.ObjectPrx?, current: Ice.Current) throws -> Ice.ObjectPrx? + + /// Unsubscribe the given subscriber. + /// + /// - parameter subscriber: `Ice.ObjectPrx?` The proxy of an existing subscriber. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func unsubscribe(subscriber: Ice.ObjectPrx?, current: Ice.Current) throws + + /// Create a link to the given topic. All events originating + /// on this topic will also be sent to linkTo. + /// + /// - parameter linkTo: `TopicPrx?` The topic to link to. + /// + /// - parameter cost: `Swift.Int32` The cost to the linked topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - LinkExists - Raised if a link to the same topic already + /// exists. + func link(linkTo: TopicPrx?, cost: Swift.Int32, current: Ice.Current) throws + + /// Destroy the link from this topic to the given topic linkTo. + /// + /// - parameter linkTo: `TopicPrx?` The topic to destroy the link to. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - throws: + /// + /// - NoSuchLink - Raised if a link to the topic does not exist. + func unlink(linkTo: TopicPrx?, current: Ice.Current) throws + + /// Retrieve information on the current links. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `LinkInfoSeq` - A sequence of LinkInfo objects. + func getLinkInfoSeq(current: Ice.Current) throws -> LinkInfoSeq + + /// Retrieve the list of subscribers for this topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.IdentitySeq` - The sequence of Ice identities for the subscriber objects. + func getSubscribers(current: Ice.Current) throws -> Ice.IdentitySeq + + /// Destroy the topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + func destroy(current: Ice.Current) throws +} + + +/// Dispatcher for `TopicManager` servants. +public struct TopicManagerDisp: Ice.Disp { + public let servant: TopicManager + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: TopicManager) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "create": + return try servant._iceD_create(incoming: request, current: current) + case "getSliceChecksums": + return try servant._iceD_getSliceChecksums(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? TopicManagerDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? TopicManagerDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? TopicManagerDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? TopicManagerDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + case "retrieve": + return try servant._iceD_retrieve(incoming: request, current: current) + case "retrieveAll": + return try servant._iceD_retrieveAll(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// A topic manager manages topics, and subscribers to topics. +public protocol TopicManager { + /// Create a new topic. The topic name must be unique. + /// + /// - parameter name: `Swift.String` The name of the topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `TopicPrx?` - A proxy to the topic instance. + /// + /// - throws: + /// + /// - TopicExists - Raised if a topic with the same name already + /// exists. + func create(name: Swift.String, current: Ice.Current) throws -> TopicPrx? + + /// Retrieve a topic by name. + /// + /// - parameter name: `Swift.String` The name of the topic. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `TopicPrx?` - A proxy to the topic instance. + /// + /// - throws: + /// + /// - NoSuchTopic - Raised if the topic does not exist. + func retrieve(name: Swift.String, current: Ice.Current) throws -> TopicPrx? + + /// Retrieve all topics managed by this topic manager. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `TopicDict` - A dictionary of string, topic proxy pairs. + func retrieveAll(current: Ice.Current) throws -> TopicDict + + /// Returns the checksums for the IceStorm Slice definitions. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `Ice.SliceChecksumDict` - A dictionary mapping Slice type ids to their checksums. + func getSliceChecksums(current: Ice.Current) throws -> Ice.SliceChecksumDict +} + + +/// Dispatcher for `Finder` servants. +public struct FinderDisp: Ice.Disp { + public let servant: Finder + private static let defaultObject = Ice.ObjectI() + + public init(_ servant: Finder) { + self.servant = servant + } + + public func dispatch(request: Ice.Request, current: Ice.Current) throws -> PromiseKit.Promise? { + request.startOver() + switch current.operation { + case "getTopicManager": + return try servant._iceD_getTopicManager(incoming: request, current: current) + case "ice_id": + return try (servant as? Object ?? FinderDisp.defaultObject)._iceD_ice_id(incoming: request, current: current) + case "ice_ids": + return try (servant as? Object ?? FinderDisp.defaultObject)._iceD_ice_ids(incoming: request, current: current) + case "ice_isA": + return try (servant as? Object ?? FinderDisp.defaultObject)._iceD_ice_isA(incoming: request, current: current) + case "ice_ping": + return try (servant as? Object ?? FinderDisp.defaultObject)._iceD_ice_ping(incoming: request, current: current) + default: + throw Ice.OperationNotExistException(id: current.id, facet: current.facet, operation: current.operation) + } + } +} + +/// This inferface is advertised by the IceStorm service through the +/// Ice object with the identity `IceStorm/Finder'. This allows clients +/// to retrieve the topic manager with just the endpoint information of +/// the IceStorm service. +public protocol Finder { + /// Get the topic manager proxy. The proxy might point to several + /// replicas. + /// + /// - parameter current: `Ice.Current` - The Current object for the dispatch. + /// + /// - returns: `TopicManagerPrx?` - The topic manager proxy. + func getTopicManager(current: Ice.Current) throws -> TopicManagerPrx? +} + +/// Publishers publish information on a particular topic. A topic +/// logically represents a type. +/// +/// Topic Methods: +/// +/// - getName: Get the name of this topic. +/// +/// - getPublisher: Get a proxy to a publisher object for this topic. +/// +/// - getNonReplicatedPublisher: Get a non-replicated proxy to a publisher object for this topic. +/// +/// - subscribeAndGetPublisher: Subscribe with the given qos to this topic. +/// +/// - unsubscribe: Unsubscribe the given subscriber. +/// +/// - link: Create a link to the given topic. +/// +/// - unlink: Destroy the link from this topic to the given topic linkTo. +/// +/// - getLinkInfoSeq: Retrieve information on the current links. +/// +/// - getSubscribers: Retrieve the list of subscribers for this topic. +/// +/// - destroy: Destroy the topic. +public extension Topic { + func _iceD_getName(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getName(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getPublisher(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getPublisher(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_getNonReplicatedPublisher(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getNonReplicatedPublisher(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_subscribeAndGetPublisher(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_theQoS, iceP_subscriber): (QoS, Ice.ObjectPrx?) = try inS.read { istr in + let iceP_theQoS: QoS = try QoSHelper.read(from: istr) + let iceP_subscriber: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return (iceP_theQoS, iceP_subscriber) + } + + let iceP_returnValue = try self.subscribeAndGetPublisher(theQoS: iceP_theQoS, subscriber: iceP_subscriber, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_unsubscribe(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_subscriber: Ice.ObjectPrx? = try inS.read { istr in + let iceP_subscriber: Ice.ObjectPrx? = try istr.read(Ice.ObjectPrx.self) + return iceP_subscriber + } + + try self.unsubscribe(subscriber: iceP_subscriber, current: current) + + return inS.setResult() + } + + func _iceD_link(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let (iceP_linkTo, iceP_cost): (TopicPrx?, Swift.Int32) = try inS.read { istr in + let iceP_linkTo: TopicPrx? = try istr.read(TopicPrx.self) + let iceP_cost: Swift.Int32 = try istr.read() + return (iceP_linkTo, iceP_cost) + } + + try self.link(linkTo: iceP_linkTo, cost: iceP_cost, current: current) + + return inS.setResult() + } + + func _iceD_unlink(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_linkTo: TopicPrx? = try inS.read { istr in + let iceP_linkTo: TopicPrx? = try istr.read(TopicPrx.self) + return iceP_linkTo + } + + try self.unlink(linkTo: iceP_linkTo, current: current) + + return inS.setResult() + } + + func _iceD_getLinkInfoSeq(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getLinkInfoSeq(current: current) + + return inS.setResult{ ostr in + LinkInfoSeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_getSubscribers(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSubscribers(current: current) + + return inS.setResult{ ostr in + Ice.IdentitySeqHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_destroy(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + try self.destroy(current: current) + + return inS.setResult() + } +} + +/// A topic manager manages topics, and subscribers to topics. +/// +/// TopicManager Methods: +/// +/// - create: Create a new topic. +/// +/// - retrieve: Retrieve a topic by name. +/// +/// - retrieveAll: Retrieve all topics managed by this topic manager. +/// +/// - getSliceChecksums: Returns the checksums for the IceStorm Slice definitions. +public extension TopicManager { + func _iceD_create(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.create(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_retrieve(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + let iceP_name: Swift.String = try inS.read { istr in + let iceP_name: Swift.String = try istr.read() + return iceP_name + } + + let iceP_returnValue = try self.retrieve(name: iceP_name, current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } + + func _iceD_retrieveAll(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.retrieveAll(current: current) + + return inS.setResult{ ostr in + TopicDictHelper.write(to: ostr, value: iceP_returnValue) + } + } + + func _iceD_getSliceChecksums(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getSliceChecksums(current: current) + + return inS.setResult{ ostr in + Ice.SliceChecksumDictHelper.write(to: ostr, value: iceP_returnValue) + } + } +} + +/// This inferface is advertised by the IceStorm service through the +/// Ice object with the identity `IceStorm/Finder'. This allows clients +/// to retrieve the topic manager with just the endpoint information of +/// the IceStorm service. +/// +/// Finder Methods: +/// +/// - getTopicManager: Get the topic manager proxy. +public extension Finder { + func _iceD_getTopicManager(incoming inS: Ice.Incoming, current: Ice.Current) throws -> PromiseKit.Promise? { + try inS.readEmptyParams() + + let iceP_returnValue = try self.getTopicManager(current: current) + + return inS.setResult{ ostr in + ostr.write(iceP_returnValue) + } + } +} diff --git a/Sources/IceStorm/Metrics.swift b/Sources/IceStorm/Metrics.swift new file mode 100644 index 0000000..c4bc25a --- /dev/null +++ b/Sources/IceStorm/Metrics.swift @@ -0,0 +1,156 @@ +// +// Copyright (c) ZeroC, Inc. All rights reserved. +// +// +// Ice version 3.7.10 +// +// +// +// Generated from file `Metrics.ice' +// +// Warning: do not edit this file. +// +// +// + +import Foundation +import Ice + +/// Traits for Slice class `MXTopicMetrics`. +public struct MXTopicMetricsTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::Metrics", "::IceMX::TopicMetrics"] + public static let staticId = "::IceMX::TopicMetrics" +} + +/// Traits for Slice class `MXSubscriberMetrics`. +public struct MXSubscriberMetricsTraits: Ice.SliceTraits { + public static let staticIds = ["::Ice::Object", "::IceMX::Metrics", "::IceMX::SubscriberMetrics"] + public static let staticId = "::IceMX::SubscriberMetrics" +} + +/// :nodoc: +public class MXTopicMetrics_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return MXTopicMetrics.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceMX_TopicMetrics() -> Ice.ValueTypeResolver { + return MXTopicMetrics_TypeResolver() + } +} + +/// Provides information on IceStorm topics. +open class MXTopicMetrics: Ice.MXMetrics { + /// Number of events published on the topic by publishers. + public var published: Swift.Int64 = 0 + /// Number of events forwarded on the topic by IceStorm topic links. + public var forwarded: Swift.Int64 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, published: Swift.Int64, forwarded: Swift.Int64) { + self.published = published + self.forwarded = forwarded + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXTopicMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXTopicMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.published = try istr.read() + self.forwarded = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: MXTopicMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.published) + ostr.write(self.forwarded) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +} + +/// :nodoc: +public class MXSubscriberMetrics_TypeResolver: Ice.ValueTypeResolver { + public override func type() -> Ice.Value.Type { + return MXSubscriberMetrics.self + } +} + +public extension Ice.ClassResolver { + @objc static func IceMX_SubscriberMetrics() -> Ice.ValueTypeResolver { + return MXSubscriberMetrics_TypeResolver() + } +} + +/// Provides information on IceStorm subscribers. +open class MXSubscriberMetrics: Ice.MXMetrics { + /// Number of queued events. + public var queued: Swift.Int32 = 0 + /// Number of outstanding events. + public var outstanding: Swift.Int32 = 0 + /// Number of forwarded events. + public var delivered: Swift.Int64 = 0 + + public required init() { + super.init() + } + + public init(id: Swift.String, total: Swift.Int64, current: Swift.Int32, totalLifetime: Swift.Int64, failures: Swift.Int32, queued: Swift.Int32, outstanding: Swift.Int32, delivered: Swift.Int64) { + self.queued = queued + self.outstanding = outstanding + self.delivered = delivered + super.init(id: id, total: total, current: current, totalLifetime: totalLifetime, failures: failures) + } + + /// Returns the Slice type ID of the most-derived interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the most-derived interface supported by this object + open override func ice_id() -> Swift.String { + return MXSubscriberMetricsTraits.staticId + } + + /// Returns the Slice type ID of the interface supported by this object. + /// + /// - returns: `String` - The Slice type ID of the interface supported by this object. + open override class func ice_staticId() -> Swift.String { + return MXSubscriberMetricsTraits.staticId + } + + open override func _iceReadImpl(from istr: Ice.InputStream) throws { + _ = try istr.startSlice() + self.queued = try istr.read() + self.outstanding = try istr.read() + self.delivered = try istr.read() + try istr.endSlice() + try super._iceReadImpl(from: istr); + } + + open override func _iceWriteImpl(to ostr: Ice.OutputStream) { + ostr.startSlice(typeId: MXSubscriberMetricsTraits.staticId, compactId: -1, last: false) + ostr.write(self.queued) + ostr.write(self.outstanding) + ostr.write(self.delivered) + ostr.endSlice() + super._iceWriteImpl(to: ostr); + } +}