1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 namespace IceInternal 6 { 7 using System.Collections.Generic; 8 using System.Diagnostics; 9 10 public sealed class EndpointFactoryManager 11 { EndpointFactoryManager(Instance instance)12 internal EndpointFactoryManager(Instance instance) 13 { 14 _instance = instance; 15 _factories = new List<EndpointFactory>(); 16 } 17 initialize()18 public void initialize() 19 { 20 foreach(EndpointFactory f in _factories) 21 { 22 f.initialize(); 23 } 24 } 25 add(EndpointFactory factory)26 public void add(EndpointFactory factory) 27 { 28 lock(this) 29 { 30 foreach(EndpointFactory f in _factories) 31 { 32 if(f.type() == factory.type()) 33 { 34 Debug.Assert(false); 35 } 36 } 37 _factories.Add(factory); 38 } 39 } 40 get(short type)41 public EndpointFactory get(short type) 42 { 43 lock(this) 44 { 45 foreach(EndpointFactory f in _factories) 46 { 47 if(f.type() == type) 48 { 49 return f; 50 } 51 } 52 return null; 53 } 54 } 55 create(string str, bool oaEndpoint)56 public EndpointI create(string str, bool oaEndpoint) 57 { 58 string[] arr = IceUtilInternal.StringUtil.splitString(str, " \t\r\n"); 59 if(arr == null) 60 { 61 Ice.EndpointParseException e = new Ice.EndpointParseException(); 62 e.str = "mismatched quote"; 63 throw e; 64 } 65 66 if(arr.Length == 0) 67 { 68 Ice.EndpointParseException e = new Ice.EndpointParseException(); 69 e.str = "value has no non-whitespace characters"; 70 throw e; 71 } 72 73 List<string> v = new List<string>(arr); 74 string protocol = v[0]; 75 v.RemoveAt(0); 76 77 if(protocol.Equals("default")) 78 { 79 protocol = _instance.defaultsAndOverrides().defaultProtocol; 80 } 81 82 EndpointFactory factory = null; 83 84 lock(this) 85 { 86 for(int i = 0; i < _factories.Count; i++) 87 { 88 EndpointFactory f = _factories[i]; 89 if(f.protocol().Equals(protocol)) 90 { 91 factory = f; 92 } 93 } 94 } 95 96 if(factory != null) 97 { 98 EndpointI e = factory.create(v, oaEndpoint); 99 if(v.Count > 0) 100 { 101 Ice.EndpointParseException ex = new Ice.EndpointParseException(); 102 ex.str = "unrecognized argument `" + v[0] + "' in endpoint `" + str + "'"; 103 throw ex; 104 } 105 return e; 106 107 // Code below left in place for debugging. 108 109 /* 110 EndpointI e = f.create(s.Substring(m.Index + m.Length), oaEndpoint); 111 BasicStream bs = new BasicStream(_instance, true); 112 e.streamWrite(bs); 113 Buffer buf = bs.getBuffer(); 114 buf.b.position(0); 115 short type = bs.readShort(); 116 EndpointI ue = new IceInternal.OpaqueEndpointI(type, bs); 117 System.Console.Error.WriteLine("Normal: " + e); 118 System.Console.Error.WriteLine("Opaque: " + ue); 119 return e; 120 */ 121 } 122 123 // 124 // If the stringified endpoint is opaque, create an unknown endpoint, 125 // then see whether the type matches one of the known endpoints. 126 // 127 if(protocol.Equals("opaque")) 128 { 129 EndpointI ue = new OpaqueEndpointI(v); 130 if(v.Count > 0) 131 { 132 Ice.EndpointParseException ex = new Ice.EndpointParseException(); 133 ex.str = "unrecognized argument `" + v[0] + "' in endpoint `" + str + "'"; 134 throw ex; 135 } 136 factory = get(ue.type()); 137 if(factory != null) 138 { 139 // 140 // Make a temporary stream, write the opaque endpoint data into the stream, 141 // and ask the factory to read the endpoint data from that stream to create 142 // the actual endpoint. 143 // 144 Ice.OutputStream os = new Ice.OutputStream(_instance, Ice.Util.currentProtocolEncoding); 145 os.writeShort(ue.type()); 146 ue.streamWrite(os); 147 Ice.InputStream iss = 148 new Ice.InputStream(_instance, Ice.Util.currentProtocolEncoding, os.getBuffer(), true); 149 iss.pos(0); 150 iss.readShort(); // type 151 iss.startEncapsulation(); 152 EndpointI e = factory.read(iss); 153 iss.endEncapsulation(); 154 return e; 155 } 156 return ue; // Endpoint is opaque, but we don't have a factory for its type. 157 } 158 159 return null; 160 } 161 read(Ice.InputStream s)162 public EndpointI read(Ice.InputStream s) 163 { 164 lock(this) 165 { 166 short type = s.readShort(); 167 168 EndpointFactory factory = get(type); 169 EndpointI e = null; 170 171 s.startEncapsulation(); 172 173 if(factory != null) 174 { 175 e = factory.read(s); 176 } 177 // 178 // If the factory failed to read the endpoint, return an opaque endpoint. This can 179 // occur if for example the factory delegates to another factory and this factory 180 // isn't available. In this case, the factory needs to make sure the stream position 181 // is preserved for reading the opaque endpoint. 182 // 183 if(e == null) 184 { 185 e = new OpaqueEndpointI(type, s); 186 } 187 188 s.endEncapsulation(); 189 190 return e; 191 } 192 } 193 destroy()194 internal void destroy() 195 { 196 foreach(EndpointFactory f in _factories) 197 { 198 f.destroy(); 199 } 200 _factories.Clear(); 201 } 202 203 private readonly Instance _instance; 204 private readonly List<EndpointFactory> _factories; 205 } 206 207 } 208