All files / src/Ice EndpointFactoryManager.js

96.36% Statements 106/110
93.33% Branches 28/30
100% Functions 5/5
96.36% Lines 106/110

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 11141x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 67x 67x 67x 41x 41x 268x 268x 268x 41x 41x 438x 438x 41x 41x 188x 188x 2x 2x 186x 186x 188x     186x 186x 186x 186x 188x 16x 16x 188x 256x 163x 163x     163x 163x 256x 23x 23x 23x 23x 23x 66x 22x 22x 22x 1x 1x 11x 22x 23x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 23x 2x 2x 1x 1x 188x 41x 41x 438x 438x 438x 438x 438x 438x 437x 437x 438x 438x 438x 438x 438x 438x 438x 1x 1x 1x 438x 438x 438x 41x  
// Copyright (c) ZeroC, Inc.
 
import { ParseException } from "./LocalExceptions.js";
import { StringUtil } from "./StringUtil.js";
import { OpaqueEndpointI } from "./OpaqueEndpoint.js";
import { Protocol } from "./Protocol.js";
import { OutputStream } from "./OutputStream.js";
import { InputStream } from "./InputStream.js";
 
export class EndpointFactoryManager {
    constructor(instance) {
        this._instance = instance;
        this._factories = [];
    }
 
    add(factory) {
        console.assert(this._factories.find(f => factory.type() == f.type()) === undefined);
        this._factories.push(factory);
    }
 
    get(type) {
        return this._factories.find(f => type == f.type()) || null;
    }
 
    create(str, oaEndpoint) {
        const s = str.trim();
        if (s.length === 0) {
            throw new ParseException("value has no non-whitespace characters");
        }
 
        const arr = StringUtil.splitString(s, " \t\n\r");
        if (arr.length === 0) {
            throw new ParseException("value has no non-whitespace characters");
        }
 
        let protocol = arr[0];
        arr.splice(0, 1);
 
        if (protocol === "default") {
            protocol = this._instance.defaultsAndOverrides().defaultProtocol;
        }
        for (let i = 0, length = this._factories.length; i < length; ++i) {
            if (this._factories[i].protocol() === protocol) {
                const e = this._factories[i].create(arr, oaEndpoint);
                if (arr.length > 0) {
                    throw new ParseException(`unrecognized argument '${arr[0]}' in endpoint '${str}'`);
                }
                return e;
            }
        }
 
        //
        // If the stringified endpoint is opaque, create an unknown endpoint,
        // then see whether the type matches one of the known endpoints.
        //
        if (protocol === "opaque") {
            const ue = new OpaqueEndpointI();
            ue.initWithOptions(arr);
            if (arr.length > 0) {
                throw new ParseException(`unrecognized argument '${arr[0]}' in endpoint '${str}'`);
            }
 
            for (let i = 0, length = this._factories.length; i < length; ++i) {
                if (this._factories[i].type() == ue.type()) {
                    //
                    // 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.
                    //
                    const os = new OutputStream();
                    os.writeShort(ue.type());
                    ue.streamWrite(os);
                    const is = new InputStream(this._instance, Protocol.currentProtocolEncoding, os.buffer);
                    is.pos = 0;
                    is.readShort(); // type
                    is.startEncapsulation();
                    const e = this._factories[i].read(is);
                    is.endEncapsulation();
                    return e;
                }
            }
            return ue; // Endpoint is opaque, but we don't have a factory for its type.
        }
 
        return null;
    }
 
    read(s) {
        const type = s.readShort();
 
        const factory = this.get(type);
        let e = null;
        s.startEncapsulation();
        if (factory) {
            e = factory.read(s);
        }
        //
        // 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) {
            e = new OpaqueEndpointI(type);
            e.initWithStream(s);
        }
        s.endEncapsulation();
        return e;
    }
}