Exemplo n.º 1
0
        private static Endpoint CreateEndpoint(
            Communicator communicator,
            bool oaEndpoint,
            Dictionary <string, string> options,
            Protocol protocol,
            Uri uri,
            string uriString)
        {
            Debug.Assert(uri.Scheme.StartsWith("ice+"));
            string transportName = uri.Scheme.Substring(4); // i.e. chop-off "ice+"

            ushort port = 0;

            checked
            {
                port = (ushort)uri.Port;
            }

            IEndpointFactory?factory   = null;
            Transport        transport = default;

            if (transportName == "universal")
            {
                if (protocol == Protocol.Ice1)
                {
                    throw new FormatException("ice+universal is not compatible with the ice1 protocol");
                }
                if (oaEndpoint)
                {
                    throw new FormatException("ice+universal cannot specify an object adapter endpoint");
                }

                // Enumerator names can only be used for "well-known" transports.
                transport = Enum.Parse <Transport>(options["transport"], ignoreCase: true);
                options.Remove("transport");

                // It's possible we have a factory for this transport:
                factory = communicator.IceFindEndpointFactory(transport);
            }
            else if (communicator.FindEndpointFactory(transportName) is (EndpointFactory f, Transport t))
            {
                factory   = f;
                transport = t;
            }
            else
            {
                throw new FormatException($"unknown transport `{transportName}'");
            }

            Endpoint endpoint = factory?.Create(transport,
                                                protocol,
                                                uri.DnsSafeHost,
                                                port,
                                                options,
                                                oaEndpoint,
                                                uriString) ??
                                new OpaqueEndpoint(communicator, transport, protocol, uri.DnsSafeHost, port, options);

            if (options.Count > 0)
            {
                throw new FormatException($"unknown option `{options.First().Key}' for transport `{transportName}'");
            }
            return(endpoint);
        }
Exemplo n.º 2
0
        // Creates an endpoint from a string.
        internal static Endpoint Parse(string endpointString, Communicator communicator, bool oaEndpoint)
        {
            string[]? args = IceUtilInternal.StringUtil.SplitString(endpointString, " \t\r\n");
            if (args == null)
            {
                throw new FormatException($"mismatched quote in endpoint `{endpointString}'");
            }

            if (args.Length == 0)
            {
                throw new FormatException("no non-whitespace character in endpoint string");
            }

            string transport = args[0];

            if (transport == "default")
            {
                transport = communicator.DefaultTransport;
            }

            var options = new Dictionary <string, string?>();

            // Parse args into options (and skip transport at args[0])
            for (int n = 1; n < args.Length; ++n)
            {
                // Any option with < 2 characters or that does not start with - is illegal
                string option = args[n];
                if (option.Length < 2 || option[0] != '-')
                {
                    throw new FormatException($"invalid option `{option}' in endpoint `{endpointString}'");
                }

                // Extract the argument given to the current option, if any
                string?argument = null;
                if (n + 1 < args.Length && args[n + 1][0] != '-')
                {
                    argument = args[++n];
                }

                try
                {
                    options.Add(option, argument);
                }
                catch (ArgumentException)
                {
                    throw new FormatException($"duplicate option `{option}' in endpoint `{endpointString}'");
                }
            }

            if (communicator.FindEndpointFactory(transport) is IEndpointFactory factory)
            {
                Endpoint endpoint = factory.Create(endpointString, options, oaEndpoint);
                if (options.Count > 0)
                {
                    throw new FormatException(
                              $"unrecognized option(s) `{ToString(options)}' in endpoint `{endpointString}'");
                }
                return(endpoint);
            }

            // If the stringified endpoint is opaque, create an unknown endpoint, then see whether the type matches one
            // of the known endpoints.
            if (!oaEndpoint && transport == "opaque")
            {
                var opaqueEndpoint = new OpaqueEndpoint(endpointString, options);
                if (options.Count > 0)
                {
                    throw new FormatException(
                              $"unrecognized option(s) `{ToString(options)}' in endpoint `{endpointString}'");
                }

                if (opaqueEndpoint.Encoding.IsSupported &&
                    communicator.FindEndpointFactory(opaqueEndpoint.Type) != null)
                {
                    // We may be able to unmarshal this endpoint, so we first marshal it into a byte buffer and then
                    // unmarshal it from this buffer.
                    var bufferList = new List <ArraySegment <byte> >
                    {
                        // 8 = size of short + size of encapsulation header with 1.1 encoding
                        new byte[8 + opaqueEndpoint.Bytes.Length]
                    };

                    var ostr = new OutputStream(Ice1Definitions.Encoding, bufferList);
                    ostr.WriteEndpoint(opaqueEndpoint);
                    OutputStream.Position tail = ostr.Save();
                    Debug.Assert(bufferList.Count == 1);
                    Debug.Assert(tail.Segment == 0 && tail.Offset == 8 + opaqueEndpoint.Bytes.Length);

                    return(new InputStream(communicator, Ice1Definitions.Encoding, bufferList[0]).ReadEndpoint());
                }
                else
                {
                    return(opaqueEndpoint);
                }
            }

            throw new FormatException($"unknown transport `{transport}' in endpoint `{endpointString}'");
        }