public Endpoint ReadEndpoint(InputStream istr) { lock (this) { var type = (EndpointType)istr.ReadShort(); IEndpointFactory?factory = GetEndpointFactory(type); Endpoint? e = null; (Encoding encoding, int size) = istr.StartEndpointEncapsulation(); if (factory != null) { e = factory.Read(istr); } // 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 == null) { byte[] data = new byte[size]; size = istr.ReadSpan(data); if (size < data.Length) { throw new InvalidDataException(@$ "not enough bytes available reading opaque endpoint, requested { data.Length} bytes, but there was only {size} bytes remaining"); } e = new OpaqueEndpoint(type, encoding, data); } istr.EndEndpointEncapsulation(); return(e); }
public Endpoint?CreateEndpoint(string endpointString, 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 = 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}'"); } } IEndpointFactory?factory = null; lock (this) { for (int i = 0; i < _endpointFactories.Count; i++) { IEndpointFactory f = _endpointFactories[i]; if (f.Transport() == transport) { factory = f; } } } if (factory != null) { Endpoint?e = factory.Create(endpointString, options, oaEndpoint); if (options.Count > 0) { throw new FormatException( $"unrecognized option(s) `{ToString(options)}' in endpoint `{endpointString}'"); } return(e); } // // If the stringified endpoint is opaque, create an unknown endpoint, // then see whether the type matches one of the known endpoints. // if (transport == "opaque") { Endpoint ue = new OpaqueEndpoint(endpointString, options); if (options.Count > 0) { throw new FormatException( $"unrecognized option(s) `{ToString(options)}' in endpoint `{endpointString}'"); } factory = GetEndpointFactory(ue.Type); if (factory != null) { // // 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. // var ostr = new OutputStream(Ice1Definitions.Encoding, new List <ArraySegment <byte> >()); ostr.WriteShort((short)ue.Type); ue.IceWrite(ostr); // TODO avoid copy OutputStream buffers var iss = new InputStream(this, ostr.ToArray()); iss.Pos = 0; iss.ReadShort(); // type iss.StartEndpointEncapsulation(); Endpoint?e = factory.Read(iss); iss.EndEndpointEncapsulation(); return(e); } return(ue); // Endpoint is opaque, but we don't have a factory for its type. } return(null); }
public Endpoint?CreateEndpoint(string endpointString, 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 = 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}'"); } } IEndpointFactory?factory = null; lock (this) { for (int i = 0; i < _endpointFactories.Count; i++) { IEndpointFactory f = _endpointFactories[i]; if (f.Transport() == transport) { factory = f; } } } if (factory != null) { 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 (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 && GetEndpointFactory(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 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(this, bufferList[0]).ReadEndpoint()); } else { return(opaqueEndpoint); } } return(null); }