private StatusCode ApplyMultiRange(ref object value)
{
Array array = value as Array;
TypeInfo typeInfo = null;
// check for matrix.
if (array == null)
{
Matrix matrix = value as Matrix;
if (matrix == null || matrix.Dimensions.Length != m_subranges.Length)
{
value = null;
return StatusCodes.BadIndexRangeNoData;
}
array = matrix.ToArray();
}
typeInfo = TypeInfo.Construct(array);
// check for matching dimensions.
NumericRange? finalRange = null;
if (m_subranges.Length > typeInfo.ValueRank)
{
if (typeInfo.BuiltInType == BuiltInType.ByteString || typeInfo.BuiltInType == BuiltInType.String)
{
if (m_subranges.Length == typeInfo.ValueRank + 1)
{
finalRange = m_subranges[m_subranges.Length - 1];
}
}
if (finalRange == null)
{
value = null;
return StatusCodes.BadIndexRangeNoData;
}
}
// create the dimensions of the target.
int[] dimensions = new int[typeInfo.ValueRank];
for (int ii = 0; ii < dimensions.Length; ii++)
{
if (m_subranges.Length > ii)
{
if (m_subranges[ii].m_begin >= array.GetLength(ii))
{
value = null;
return StatusCodes.BadIndexRangeNoData;
}
dimensions[ii] = m_subranges[ii].Count;
}
else
{
dimensions[ii] = array.GetLength(ii);
}
}
Array subset = TypeInfo.CreateArray(typeInfo.BuiltInType, dimensions);
int length = subset.Length;
int[] dstIndexes = new int[dimensions.Length];
int[] srcIndexes = new int[dimensions.Length];
bool dataFound = false;
for (int ii = 0; ii < length; ii++)
{
int divisor = subset.Length;
bool outOfRange = false;
for (int jj = 0; jj < dstIndexes.Length; jj++)
{
divisor /= dimensions[jj];
dstIndexes[jj] = (ii / divisor) % dimensions[jj];
srcIndexes[jj] = dstIndexes[jj] + m_subranges[jj].m_begin;
if (array.GetLength(jj) <= srcIndexes[jj])
{
outOfRange = true;
break;
}
}
if (outOfRange)
{
continue;
}
object element = array.GetValue(srcIndexes);
if (element != null)
{
if (finalRange != null)
{
StatusCode result = finalRange.Value.ApplyRange(ref element);
if (StatusCode.IsBad(result))
{
if (result != StatusCodes.BadIndexRangeNoData)
{
value = null;
return result;
}
continue;
}
}
dataFound = true;
subset.SetValue(element, dstIndexes);
}
}
if (!dataFound)
{
value = null;
return StatusCodes.BadIndexRangeNoData;
}
value = subset;
return StatusCodes.Good;
}