/// <summary> /// Returns a unique handle for the node. /// </summary> protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache) { lock (Lock) { // quickly exclude nodes that are not in the namespace. if (!IsNodeIdInNamespace(nodeId)) { return(null); } var handle = new NodeHandle { NodeId = nodeId, Validated = true }; var id = (uint)nodeId.Identifier; // find register var registerId = (int)((id & 0xFF000000) >> 24); var index = (int)(id & 0x00FFFFFF); if (registerId == 0) { var register = _system.GetRegister(index); if (register == null) { return(null); } handle.Node = ModelUtils.GetRegister(register, NamespaceIndex); } // find register variable. else { var register = _system.GetRegister(registerId); if (register == null) { return(null); } // find register variable. var variable = ModelUtils.GetRegisterVariable(register, index, NamespaceIndex); if (variable == null) { return(null); } handle.Node = variable; } return(handle); } }
/// <summary> /// Does any initialization required before the address space can be used. /// </summary> /// <remarks> /// The externalReferences is an out parameter that allows the node manager to link to nodes /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and /// should have a reference to the root folder node(s) exposed by this node manager. /// </remarks> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { _system.Initialize(); var registers = _system.GetRegisters(); for (var ii = 0; ii < registers.Count; ii++) { var targetId = ModelUtils.GetRegisterId(registers[ii], NamespaceIndex); if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out var references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, targetId)); } } }
/// <summary> /// Returns the next child. /// </summary> private IReference NextChild() { var system = (UnderlyingSystem)SystemContext.SystemHandle; NodeId targetId = null; // check if a specific browse name is requested. if (!QualifiedName.IsNull(BrowseName)) { // browse name must be qualified by the correct namespace. if (_parent.BrowseName.NamespaceIndex != BrowseName.NamespaceIndex) { return(null); } // parse the browse name. var index = 0; for (var ii = 0; ii < BrowseName.Name.Length; ii++) { var ch = BrowseName.Name[ii]; if (!char.IsDigit(ch)) { return(null); } index *= 10; index += Convert.ToInt32(ch - '0'); } // check for valid browse name. if (index < 0 || index > _parent.Register.Size) { return(null); } // return target. targetId = ModelUtils.GetRegisterVariableId(_parent.Register, index, _parent.NodeId.NamespaceIndex); } // return the child at the next position. else { // look for next segment. if (_position >= _parent.Register.Size) { return(null); } // return target. targetId = ModelUtils.GetRegisterVariableId(_parent.Register, _position, _parent.NodeId.NamespaceIndex); _position++; } // create reference. if (targetId != null) { return(new NodeStateReference(ReferenceTypeIds.Organizes, false, targetId)); } return(null); }