public virtual void HistoryRead(
OperationContext context,
HistoryReadDetails details,
TimestampsToReturn timestampsToReturn,
bool releaseContinuationPoints,
IList<HistoryReadValueId> nodesToRead,
IList<HistoryReadResult> results,
IList<ServiceResult> errors)
{
ServerSystemContext systemContext = m_systemContext.Copy(context);
IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
List<NodeHandle> nodesToProcess = new List<NodeHandle>();
lock (Lock)
{
for (int ii = 0; ii < nodesToRead.Count; ii++)
{
HistoryReadValueId nodeToRead = nodesToRead[ii];
// skip items that have already been processed.
if (nodeToRead.Processed)
{
continue;
}
// check for valid handle.
NodeHandle handle = GetManagerHandle(systemContext, nodeToRead.NodeId, operationCache);
if (handle == null)
{
continue;
}
// owned by this node manager.
nodeToRead.Processed = true;
// create an initial result.
HistoryReadResult result = results[ii] = new HistoryReadResult();
result.HistoryData = null;
result.ContinuationPoint = null;
result.StatusCode = StatusCodes.Good;
// check if the node is a area in memory.
if (handle.Node == null)
{
errors[ii] = StatusCodes.BadNodeIdUnknown;
// must validate node in a seperate operation
handle.Index = ii;
nodesToProcess.Add(handle);
continue;
}
errors[ii] = StatusCodes.BadHistoryOperationUnsupported;
// check for data history variable.
BaseVariableState variable = handle.Node as BaseVariableState;
if (variable != null)
{
if ((variable.AccessLevel & AccessLevels.HistoryRead) != 0)
{
handle.Index = ii;
nodesToProcess.Add(handle);
continue;
}
}
// check for event history object.
BaseObjectState notifier = handle.Node as BaseObjectState;
if (notifier != null)
{
if ((notifier.EventNotifier & EventNotifiers.HistoryRead) != 0)
{
handle.Index = ii;
nodesToProcess.Add(handle);
continue;
}
}
}
// check for nothing to do.
if (nodesToProcess.Count == 0)
{
return;
}
}
// validates the nodes (reads values from the underlying data source if required).
HistoryRead(
systemContext,
details,
timestampsToReturn,
releaseContinuationPoints,
nodesToRead,
results,
errors,
nodesToProcess,
operationCache);
}