private ServiceResult Browse(
OperationContext context,
ViewDescription view,
uint maxReferencesPerNode,
bool assignContinuationPoint,
BrowseDescription nodeToBrowse,
BrowseResult result)
{
Debug.Assert(context != null);
Debug.Assert(nodeToBrowse != null);
Debug.Assert(result != null);
// find node manager that owns the node.
INodeManager nodeManager = null;
object handle = GetManagerHandle(nodeToBrowse.NodeId, out nodeManager);
if (handle == null)
{
return StatusCodes.BadNodeIdUnknown;
}
if (!NodeId.IsNull(nodeToBrowse.ReferenceTypeId) && !m_server.TypeTree.IsKnown(nodeToBrowse.ReferenceTypeId))
{
return StatusCodes.BadReferenceTypeIdInvalid;
}
if (nodeToBrowse.BrowseDirection < BrowseDirection.Forward || nodeToBrowse.BrowseDirection > BrowseDirection.Both)
{
return StatusCodes.BadBrowseDirectionInvalid;
}
// create a continuation point.
ContinuationPoint cp = new ContinuationPoint();
cp.Manager = nodeManager;
cp.View = view;
cp.NodeToBrowse = handle;
cp.MaxResultsToReturn = maxReferencesPerNode;
cp.BrowseDirection = nodeToBrowse.BrowseDirection;
cp.ReferenceTypeId = nodeToBrowse.ReferenceTypeId;
cp.IncludeSubtypes = nodeToBrowse.IncludeSubtypes;
cp.NodeClassMask = nodeToBrowse.NodeClassMask;
cp.ResultMask = (BrowseResultMask)nodeToBrowse.ResultMask;
cp.Index = 0;
cp.Data = null;
// check if reference type left unspecified.
if (NodeId.IsNull(cp.ReferenceTypeId))
{
cp.ReferenceTypeId = ReferenceTypeIds.References;
cp.IncludeSubtypes = true;
}
// loop until browse is complete or max results.
ReferenceDescriptionCollection references = result.References;
ServiceResult error = FetchReferences(context, assignContinuationPoint, ref cp, ref references);
result.References = references;
// save continuation point.
if (cp != null)
{
result.StatusCode = StatusCodes.Good;
result.ContinuationPoint = cp.Id.ToByteArray();
}
// all is good.
return error;
}