public virtual void BrowseNext(
OperationContext context,
bool releaseContinuationPoints,
ByteStringCollection continuationPoints,
out BrowseResultCollection results,
out DiagnosticInfoCollection diagnosticInfos)
{
if (context == null) throw new ArgumentNullException("context");
if (continuationPoints == null) throw new ArgumentNullException("continuationPoints");
bool diagnosticsExist = false;
results = new BrowseResultCollection(continuationPoints.Count);
diagnosticInfos = new DiagnosticInfoCollection(continuationPoints.Count);
uint continuationPointsAssigned = 0;
for (int ii = 0; ii < continuationPoints.Count; ii++)
{
ContinuationPoint cp = null;
// check if request has timed out or been cancelled.
if (StatusCode.IsBad(context.OperationStatus))
{
// release all allocated continuation points.
foreach (BrowseResult current in results)
{
if (current != null && current.ContinuationPoint != null && current.ContinuationPoint.Length > 0)
{
cp = context.Session.RestoreContinuationPoint(current.ContinuationPoint);
cp.Dispose();
}
}
throw new ServiceResultException(context.OperationStatus);
}
// find the continuation point.
cp = context.Session.RestoreContinuationPoint(continuationPoints[ii]);
// initialize result.
BrowseResult result = new BrowseResult();
result.StatusCode = StatusCodes.Good;
results.Add(result);
// check if simply releasing the continuation point.
if (releaseContinuationPoints)
{
if (cp != null)
{
cp.Dispose();
cp = null;
}
continue;
}
ServiceResult error = null;
// check if continuation point has expired.
if (cp == null)
{
error = StatusCodes.BadContinuationPointInvalid;
}
if (cp != null)
{
// need to trap unexpected exceptions to handle bugs in the node managers.
try
{
ReferenceDescriptionCollection references = result.References;
error = FetchReferences(
context,
continuationPointsAssigned < m_maxContinuationPointsPerBrowse,
ref cp,
ref references);
result.References = references;
}
catch (Exception e)
{
error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Unexpected error browsing node.");
}
// check for continuation point.
if (result.ContinuationPoint != null && result.ContinuationPoint.Length > 0)
{
continuationPointsAssigned++;
}
}
// check for error.
result.StatusCode = error.StatusCode;
if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
{
DiagnosticInfo diagnosticInfo = null;
if (error != null && error.Code != StatusCodes.Good)
{
diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
diagnosticsExist = true;
}
diagnosticInfos.Add(diagnosticInfo);
}
// check for continuation point.
if (cp != null)
{
result.StatusCode = StatusCodes.Good;
result.ContinuationPoint = cp.Id.ToByteArray();
continue;
}
}
// clear the diagnostics array if no diagnostics requested or no errors occurred.
UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos);
}