< Summary

Information
Class: Ice.Internal.EndpointFactoryManager
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/Internal/EndpointFactoryManager.cs
Tag: 71_18251537082
Line coverage
98%
Covered lines: 68
Uncovered lines: 1
Coverable lines: 69
Total lines: 173
Line coverage: 98.5%
Branch coverage
90%
Covered branches: 27
Total branches: 30
Branch coverage: 90%
Method coverage
100%
Covered methods: 6
Total methods: 6
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
initialize()100%22100%
add(...)100%11100%
get(...)100%44100%
create(...)90%20.012097.5%
read(...)75%44100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/Internal/EndpointFactoryManager.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4
 5namespace Ice.Internal;
 6
 7public sealed class EndpointFactoryManager
 8{
 19    internal EndpointFactoryManager(Instance instance)
 10    {
 111        _instance = instance;
 112        _factories = new List<EndpointFactory>();
 113    }
 14
 15    public void initialize()
 16    {
 117        foreach (EndpointFactory f in _factories)
 18        {
 119            f.initialize();
 20        }
 121    }
 22
 23    public void add(EndpointFactory factory)
 24    {
 125        lock (_mutex)
 26        {
 27            Debug.Assert(!_factories.Any(f => f.type() == factory.type()));
 128            _factories.Add(factory);
 129        }
 130    }
 31
 32    public EndpointFactory get(short type)
 33    {
 134        lock (_mutex)
 35        {
 136            foreach (EndpointFactory f in _factories)
 37            {
 138                if (f.type() == type)
 39                {
 140                    return f;
 41                }
 42            }
 143            return null;
 44        }
 145    }
 46
 47    public EndpointI create(string str, bool oaEndpoint)
 48    {
 149        string[] arr = Ice.UtilInternal.StringUtil.splitString(str, " \t\r\n") ??
 150            throw new ParseException($"Failed to parse endpoint '{str}': mismatched quote");
 151        if (arr.Length == 0)
 52        {
 153            throw new ParseException($"Failed to parse endpoint '{str}': value has no non-whitespace characters");
 54        }
 55
 156        var v = new List<string>(arr);
 157        string protocol = v[0];
 158        v.RemoveAt(0);
 59
 160        if (protocol == "default")
 61        {
 162            protocol = _instance.defaultsAndOverrides().defaultProtocol;
 63        }
 64
 165        EndpointFactory factory = null;
 66
 167        lock (_mutex)
 68        {
 169            for (int i = 0; i < _factories.Count; i++)
 70            {
 171                EndpointFactory f = _factories[i];
 172                if (f.protocol().Equals(protocol, StringComparison.Ordinal))
 73                {
 174                    factory = f;
 75                }
 76            }
 177        }
 78
 179        if (factory != null)
 80        {
 181            EndpointI e = factory.create(v, oaEndpoint);
 182            if (v.Count > 0)
 83            {
 084                throw new ParseException($"Failed to parse endpoint '{str}': unrecognized argument '{v[0]}'");
 85            }
 186            return e;
 87
 88            // Code below left in place for debugging.
 89
 90            /*
 91            EndpointI e = f.create(s.Substring(m.Index + m.Length), oaEndpoint);
 92            BasicStream bs = new BasicStream(_instance, true);
 93            e.streamWrite(bs);
 94            Buffer buf = bs.getBuffer();
 95            buf.b.position(0);
 96            short type = bs.readShort();
 97            EndpointI ue = new Ice.Internal.OpaqueEndpointI(type, bs);
 98            System.Console.Error.WriteLine("Normal: " + e);
 99            System.Console.Error.WriteLine("Opaque: " + ue);
 100            return e;
 101            */
 102        }
 103
 104        //
 105        // If the stringified endpoint is opaque, create an unknown endpoint,
 106        // then see whether the type matches one of the known endpoints.
 107        //
 1108        if (protocol == "opaque")
 109        {
 1110            EndpointI ue = new OpaqueEndpointI(v);
 1111            if (v.Count > 0)
 112            {
 1113                throw new ParseException($"Failed to parse endpoint '{str}': unrecognized argument '{v[0]}'");
 114            }
 1115            factory = get(ue.type());
 1116            if (factory != null)
 117            {
 118                //
 119                // Make a temporary stream, write the opaque endpoint data into the stream,
 120                // and ask the factory to read the endpoint data from that stream to create
 121                // the actual endpoint.
 122                //
 1123                var os = new Ice.OutputStream(Ice.Util.currentProtocolEncoding);
 1124                os.writeShort(ue.type());
 1125                ue.streamWrite(os);
 1126                var iss =
 1127                    new Ice.InputStream(_instance, Ice.Util.currentProtocolEncoding, os.getBuffer(), true);
 1128                iss.pos(0);
 1129                iss.readShort(); // type
 1130                iss.startEncapsulation();
 1131                EndpointI e = factory.read(iss);
 1132                iss.endEncapsulation();
 1133                return e;
 134            }
 1135            return ue; // Endpoint is opaque, but we don't have a factory for its type.
 136        }
 137
 1138        return null;
 139    }
 140
 141    public EndpointI read(Ice.InputStream s)
 142    {
 1143        lock (_mutex)
 144        {
 1145            short type = s.readShort();
 146
 1147            EndpointFactory factory = get(type);
 1148            EndpointI e = null;
 149
 1150            s.startEncapsulation();
 151
 1152            if (factory != null)
 153            {
 1154                e = factory.read(s);
 155            }
 156            //
 157            // If the factory failed to read the endpoint, return an opaque endpoint. This can
 158            // occur if for example the factory delegates to another factory and this factory
 159            // isn't available. In this case, the factory needs to make sure the stream position
 160            // is preserved for reading the opaque endpoint.
 161            //
 1162            e ??= new OpaqueEndpointI(type, s);
 163
 1164            s.endEncapsulation();
 165
 1166            return e;
 167        }
 1168    }
 169
 170    private readonly Instance _instance;
 171    private readonly List<EndpointFactory> _factories;
 1172    private readonly object _mutex = new();
 173}