protected DataValue GetSimpleBound(DateTime timestamp, TimeSlice slice)
{
// choose the start point
LinkedListNode<DataValue> start = slice.EarlyBound;
if (start == null)
{
start = m_values.First;
}
// look for a raw value at or immediately before the timestamp.
LinkedListNode<DataValue> startBound = start;
for (LinkedListNode<DataValue> ii = start; ii != null; ii = ii.Next)
{
// check for an exact match.
if (CompareTimestamps(timestamp, ii) == 0)
{
return new DataValue(ii.Value);
}
// looking for an end bound.
if (CompareTimestamps(timestamp, ii) < 0)
{
// only can find an end bound.
if (ii.Previous == null)
{
return GetNoDataValue(timestamp);
}
startBound = ii.Previous;
break;
}
// update start bound.
startBound = ii;
}
// check if no data found or if start bound is bad..
if (startBound == null || !IsGood(startBound.Value))
{
return GetNoDataValue(timestamp);
}
// look for an end bound.
bool revertToStepped = false;
LinkedListNode<DataValue> endBound = startBound.Next;
if (!Stepped)
{
if (endBound != null)
{
// do sloped interpolation if two good bounds exist.
if (IsGood(endBound.Value))
{
return SlopedInterpolate(timestamp, startBound.Value, endBound.Value);
}
}
// have to use stepped because end bound is not good.
revertToStepped = true;
}
// check if end of data.
if (startBound.Next == null)
{
return GetNoDataValue(timestamp);
}
// do stepped interpolation for all other cases.
DataValue value = SteppedInterpolate(timestamp, startBound.Value);
// need to make it uncertain if interpolation was required but not used.
if (StatusCode.IsGood(value.StatusCode) && revertToStepped)
{
value.StatusCode = StatusCodes.UncertainDataSubNormal;
value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Interpolated);
}
return value;
}