//
// 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.7.3"; // "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 30703; // 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;
}
}
}