// // Copyright (c) ZeroC, Inc. All rights reserved. // using System; using System.Threading; using System.Collections; using System.Globalization; namespace Ice { /// /// Interface for thread notification hooks. Applications can derive /// a class tat implements the start and stop /// methods to intercept creation and destruction of threads created /// by the Ice run time. /// public interface ThreadNotification { /// /// The Ice run time calls start for each new /// thread it creates. The call is made by the newly-started thread. /// void start(); /// /// The Ice run time calls stop before it destroys /// a thread. The call is made by thread that is about to be /// destroyed. /// void stop(); } /// /// A class that encpasulates data to initialize a communicator. /// public class InitializationData : ICloneable { /// /// Creates and returns a copy of this object. /// public object Clone() { // // A member-wise copy is safe because the members are immutable. // return MemberwiseClone(); } /// /// The properties for the communicator. /// public Properties properties; /// /// The logger for the communicator. /// public Logger logger; /// /// The communicator observer used by the Ice run-time. /// public Instrumentation.CommunicatorObserver observer; /// /// The thread hook for the communicator. /// [Obsolete("This data member is deprecated. Use threadStart or threadStop instead.")] public ThreadNotification threadHook; /// /// The thread start hook for the communicator. The Ice run time /// calls this hook for each new thread it creates. The call is /// made by the newly-started thread. /// public System.Action threadStart; /// /// The thread stop hook for the communicator. The Ice run time /// calls stop before it destroys a thread. The call is made by /// thread that is about to be destroyed. /// public System.Action threadStop; /// /// The dispatcher for the communicator. /// public System.Action dispatcher; /// /// The compact type ID resolver. /// public System.Func compactIdResolver; /// /// The batch request interceptor. /// public System.Action batchRequestInterceptor; /// /// The value factory manager. /// public ValueFactoryManager valueFactoryManager; /// /// The list of TypeId namespaces. Default is Ice.TypeId. /// public string[] typeIdNamespaces = { "Ice.TypeId" }; } /// /// Utility methods for the Ice run time. /// public sealed class Util { /// /// Creates a new empty property set. /// /// A new empty property set. public static Properties createProperties() { return new PropertiesI(); } /// /// Creates a property set initialized from an argument vector. /// /// A command-line argument vector, 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 vector, the argument vector takes precedence. /// This method modifies the argument vector by removing any Ice-related options. /// A property set initialized with the property settings /// that were removed from args. public static Properties createProperties(ref string[] args) { return new PropertiesI(ref args, null); } /// /// Creates a property set initialized from an argument vector. /// /// A command-line argument vector, 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 vector, the argument vector takes precedence. /// This method modifies the argument vector by removing any Ice-related options. /// Default values for the property set. Settings in configuration /// files and args override these defaults. /// A property set initialized with the property settings /// that were removed from args. public static Properties createProperties(ref string[] args, Properties defaults) { return new PropertiesI(ref args, defaults); } /// /// Creates a communicator. /// /// A command-line argument vector. Any Ice-related options /// in this vector are used to intialize the communicator. /// This method modifies the argument vector by removing any Ice-related options. /// The initialized communicator. public static Communicator initialize(ref string[] args) { return initialize(ref args, (InitializationData)null); } /// /// Creates a communicator. /// /// 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. /// Additional intialization data. Property settings in args /// override property settings in initData. /// The initialized communicator. public static Communicator initialize(ref string[] args, InitializationData initData) { if(initData == null) { initData = new InitializationData(); } else { initData = (InitializationData)initData.Clone(); } initData.properties = createProperties(ref args, initData.properties); CommunicatorI result = new CommunicatorI(initData); result.finishSetup(ref args); return result; } /// /// Creates a communicator. /// /// 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. /// Path to a config file that sets the new communicator's default /// properties. /// The initialized communicator. public static Communicator initialize(ref string[] args, string configFile) { InitializationData initData = null; if(configFile != null) { initData = new InitializationData(); initData.properties = Util.createProperties(); initData.properties.load(configFile); } return initialize(ref args, initData); } /// /// Creates a communicator. /// /// Additional intialization data. /// The initialized communicator. public static Communicator initialize(InitializationData initData) { if(initData == null) { initData = new InitializationData(); } else { initData = (InitializationData)initData.Clone(); } CommunicatorI result = new CommunicatorI(initData); string[] args = new string[0]; result.finishSetup(ref args); return result; } /// /// Creates a communicator. /// /// Path to a config file that sets the new communicator's default /// properties. /// The initialized communicator. public static Communicator initialize(string configFile) { InitializationData initData = null; if(configFile != null) { initData = new InitializationData(); initData.properties = Util.createProperties(); initData.properties.load(configFile); } return initialize(initData); } /// /// Creates a communicator using a default configuration. /// public static Communicator initialize() { return initialize((InitializationData)null); } /// /// Converts a string to an object identity. /// /// The string to convert. /// The converted object identity. public static Identity stringToIdentity(string s) { Identity ident = new Identity(); // // Find unescaped separator; note that the string may contain an escaped // backslash before the separator. // int slash = -1, pos = 0; while((pos = s.IndexOf((System.Char) '/', pos)) != -1) { int escapes = 0; while(pos - escapes > 0 && s[pos - escapes - 1] == '\\') { escapes++; } // // We ignore escaped escapes // if(escapes % 2 == 0) { if(slash == -1) { slash = pos; } else { // // Extra unescaped slash found. // IdentityParseException ex = new IdentityParseException(); ex.str = "unescaped backslash in identity `" + s + "'"; throw ex; } } pos++; } if(slash == -1) { ident.category = ""; try { ident.name = IceUtilInternal.StringUtil.unescapeString(s, 0, s.Length, "/"); } catch(ArgumentException e) { IdentityParseException ex = new IdentityParseException(); ex.str = "invalid identity name `" + s + "': " + e.Message; throw ex; } } else { try { ident.category = IceUtilInternal.StringUtil.unescapeString(s, 0, slash, "/"); } catch(ArgumentException e) { IdentityParseException ex = new IdentityParseException(); ex.str = "invalid category in identity `" + s + "': " + e.Message; throw ex; } if(slash + 1 < s.Length) { try { ident.name = IceUtilInternal.StringUtil.unescapeString(s, slash + 1, s.Length, "/"); } catch(ArgumentException e) { IdentityParseException ex = new IdentityParseException(); ex.str = "invalid name in identity `" + s + "': " + e.Message; throw ex; } } else { ident.name = ""; } } return ident; } /// /// Converts an object identity to a string. /// /// The object identity to convert. /// Specifies if and how non-printable ASCII characters are escaped in the result. /// The string representation of the object identity. public static string identityToString(Identity ident, ToStringMode toStringMode = ToStringMode.Unicode) { if(ident.category == null || ident.category.Length == 0) { return IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); } else { return IceUtilInternal.StringUtil.escapeString(ident.category, "/", toStringMode) + '/' + IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); } } /// /// This method is deprecated. Use System.Guid instead. /// [Obsolete("This method is deprecated. Use System.Guid instead.")] public static string generateUUID() { return Guid.NewGuid().ToString().ToUpper(System.Globalization.CultureInfo.InvariantCulture); } /// /// Compares the object identities of two proxies. /// /// A proxy. /// A proxy. /// -1 if the identity in lhs compares /// less than the identity in rhs; 0 if the identities /// compare equal; 1, otherwise. public static int proxyIdentityCompare(ObjectPrx lhs, ObjectPrx rhs) { if(lhs == null && rhs == null) { return 0; } else if(lhs == null && rhs != null) { return -1; } else if(lhs != null && rhs == null) { return 1; } else { Identity lhsIdentity = lhs.ice_getIdentity(); Identity rhsIdentity = rhs.ice_getIdentity(); int n; n = string.CompareOrdinal(lhsIdentity.name, rhsIdentity.name); if(n != 0) { return n; } return string.CompareOrdinal(lhsIdentity.category, rhsIdentity.category); } } /// /// Compares the object identities and facets of two proxies. /// /// A proxy. /// A proxy. /// -1 if the identity and facet in lhs compare /// less than the identity and facet in rhs; 0 if the identities /// and facets compare equal; 1, otherwise. public static int proxyIdentityAndFacetCompare(ObjectPrx lhs, ObjectPrx rhs) { if(lhs == null && rhs == null) { return 0; } else if(lhs == null && rhs != null) { return -1; } else if(lhs != null && rhs == null) { return 1; } else { Identity lhsIdentity = lhs.ice_getIdentity(); Identity rhsIdentity = rhs.ice_getIdentity(); int n; n = string.CompareOrdinal(lhsIdentity.name, rhsIdentity.name); if(n != 0) { return n; } n = string.CompareOrdinal(lhsIdentity.category, rhsIdentity.category); if(n != 0) { return n; } string lhsFacet = lhs.ice_getFacet(); string rhsFacet = rhs.ice_getFacet(); if(lhsFacet == null && rhsFacet == null) { return 0; } else if(lhsFacet == null) { return -1; } else if(rhsFacet == null) { return 1; } else { return string.CompareOrdinal(lhsFacet, rhsFacet); } } } /// /// Returns the process-wide logger. /// /// The process-wide logger. public static Logger getProcessLogger() { lock(_processLoggerMutex) { if(_processLogger == null) { _processLogger = new ConsoleLoggerI(AppDomain.CurrentDomain.FriendlyName); } return _processLogger; } } /// /// Changes the process-wide logger. /// /// The new process-wide logger. public static void setProcessLogger(Logger logger) { lock(_processLoggerMutex) { _processLogger = logger; } } /// /// Returns 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. /// /// The Ice version. public static string stringVersion() { return "3.8.0"; // "A.B.C", with A=major, B=minor, C=patch } /// /// 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. /// /// The Ice version. public static int intVersion() { return 30800; // AABBCC, with AA=major, BB=minor, CC=patch } /// /// Converts a string to a protocol version. /// /// The string to convert. /// The converted protocol version. public static ProtocolVersion stringToProtocolVersion(string version) { byte major, minor; stringToMajorMinor(version, out major, out minor); return new ProtocolVersion(major, minor); } /// /// Converts a string to an encoding version. /// /// The string to convert. /// The converted encoding version. public static EncodingVersion stringToEncodingVersion(string version) { byte major, minor; stringToMajorMinor(version, out major, out minor); return new EncodingVersion(major, minor); } /// /// Converts a protocol version to a string. /// /// The protocol version to convert. /// The converted string. public static string protocolVersionToString(Ice.ProtocolVersion v) { return majorMinorToString(v.major, v.minor); } /// /// Converts an encoding version to a string. /// /// The encoding version to convert. /// The converted string. public static string encodingVersionToString(Ice.EncodingVersion v) { return majorMinorToString(v.major, v.minor); } static private void stringToMajorMinor(string str, out byte major, out byte minor) { int pos = str.IndexOf('.'); if(pos == -1) { throw new VersionParseException("malformed version value `" + str + "'"); } string majStr = str.Substring(0, (pos) - (0)); string minStr = str.Substring(pos + 1, (str.Length) - (pos + 1)); int majVersion; int minVersion; try { majVersion = int.Parse(majStr, CultureInfo.InvariantCulture); minVersion = int.Parse(minStr, CultureInfo.InvariantCulture); } catch(FormatException) { throw new VersionParseException("invalid version value `" + str + "'"); } if(majVersion < 1 || majVersion > 255 || minVersion < 0 || minVersion > 255) { throw new VersionParseException("range error in version `" + str + "'"); } major = (byte)majVersion; minor = (byte)minVersion; } static private string majorMinorToString(byte major, byte minor) { return string.Format("{0}.{1}", major, minor); } public static void registerPluginFactory(string name, PluginFactory factory, bool loadOnInit) { PluginManagerI.registerPluginFactory(name, factory, loadOnInit); } public static readonly ProtocolVersion currentProtocol = new ProtocolVersion(IceInternal.Protocol.protocolMajor, IceInternal.Protocol.protocolMinor); public static readonly EncodingVersion currentProtocolEncoding = new EncodingVersion(IceInternal.Protocol.protocolEncodingMajor, IceInternal.Protocol.protocolEncodingMinor); public static readonly EncodingVersion currentEncoding = new EncodingVersion(IceInternal.Protocol.encodingMajor, IceInternal.Protocol.encodingMinor); public static readonly ProtocolVersion Protocol_1_0 = new ProtocolVersion(1, 0); public static readonly EncodingVersion Encoding_1_0 = new EncodingVersion(1, 0); public static readonly EncodingVersion Encoding_1_1 = new EncodingVersion(1, 1); public static readonly NoneType None = new NoneType(); private static object _processLoggerMutex = new object(); private static Logger _processLogger = null; } } namespace IceInternal { public sealed class HashUtil { public static void hashAdd(ref int hashCode, bool value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); } public static void hashAdd(ref int hashCode, short value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); } public static void hashAdd(ref int hashCode, byte value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); } public static void hashAdd(ref int hashCode, int value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); } public static void hashAdd(ref int hashCode, long value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); } public static void hashAdd(ref int hashCode, float value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); } public static void hashAdd(ref int hashCode, double value) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); } public static void hashAdd(ref int hashCode, object value) { if(value != null) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); } } public static void hashAdd(ref int hashCode, object[] arr) { if(arr != null) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Arrays.GetHashCode(arr)); } } public static void hashAdd(ref int hashCode, Array arr) { if(arr != null) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Arrays.GetHashCode(arr)); } } public static void hashAdd(ref int hashCode, IEnumerable s) { if(s != null) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Collections.SequenceGetHashCode(s)); } } public static void hashAdd(ref int hashCode, IDictionary d) { if(d != null) { hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Collections.DictionaryGetHashCode(d)); } } } public sealed class Util { public static Instance getInstance(Ice.Communicator communicator) { Ice.CommunicatorI p = (Ice.CommunicatorI) communicator; return p.getInstance(); } public static ProtocolPluginFacade getProtocolPluginFacade(Ice.Communicator communicator) { return new ProtocolPluginFacadeI(communicator); } public static ThreadPriority stringToThreadPriority(string s) { if(string.IsNullOrEmpty(s)) { return ThreadPriority.Normal; } if(s.StartsWith("ThreadPriority.", StringComparison.Ordinal)) { s = s.Substring("ThreadPriority.".Length, s.Length); } if(s.Equals("Lowest")) { return ThreadPriority.Lowest; } else if(s.Equals("BelowNormal")) { return ThreadPriority.BelowNormal; } else if(s.Equals("Normal")) { return ThreadPriority.Normal; } else if(s.Equals("AboveNormal")) { return ThreadPriority.AboveNormal; } else if(s.Equals("Highest")) { return ThreadPriority.Highest; } return ThreadPriority.Normal; } } }