pascalabcnet/Debugger.Core/Src/Variables/Values/Value-Array.cs
Бондарев Иван e6e67c193c initial commit
2015-05-14 21:35:07 +02:00

141 lines
3.5 KiB
C#

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 2185 $</version>
// </file>
using System;
using System.Collections.Generic;
using Debugger.Wrappers.CorDebug;
//TODO: Support for lower bound
namespace Debugger
{
// This part of the class provides support for arrays
public partial class Value
{
ICorDebugArrayValue CorArrayValue {
get {
if (IsArray) {
return CorValue.CastTo<ICorDebugArrayValue>();
} else {
throw new DebuggerException("Value is not an array");
}
}
}
// ICorDebugArrayValue CorArrayValue {
// get {
// if (IsNull) throw new GetValueException("Value is null");
// if (!this.Type.IsArray) throw new DebuggerException("Value is not an array");
//
// return this.CorValue.CastTo<ICorDebugReferenceValue>().Dereference().CastTo<ICorDebugArrayValue>();
// }
// }
/// <summary> Returns true if the value is an array </summary>
public bool IsArray {
get {
return !IsNull && this.Type.IsArray;
}
}
/// <summary>
/// Gets the number of elements the array can store.
/// eg new object[4,5] returns 20
/// </summary>
public uint ArrayLenght {
get {
return CorArrayValue.Count;
}
}
/// <summary>
/// Gets the number of dimensions of the array.
/// eg new object[4,5] returns 2
/// </summary>
public uint ArrayRank {
get {
return CorArrayValue.Rank;
}
}
/// <summary>
/// Gets the lengths of individual dimensions.
/// eg new object[4,5] returns {4,5};
/// </summary>
public uint[] ArrayDimensions {
get {
return CorArrayValue.Dimensions;
}
}
/// <summary> Returns an element of a single-dimensional array </summary>
public ArrayElement GetArrayElement(uint index)
{
return GetArrayElement(new uint[] {index});
}
/// <summary> Returns an element of an array </summary>
public ArrayElement GetArrayElement(uint[] elementIndices)
{
uint[] indices = (uint[])elementIndices.Clone();
return new ArrayElement(
indices,
Process,
new IExpirable[] {this},
new IMutable[] {this},
delegate { return GetCorValueOfArrayElement(indices); }
);
}
// May be called later
ICorDebugValue GetCorValueOfArrayElement(uint[] indices)
{
if (!IsArray) {
throw new CannotGetValueException("The value is not an array");
}
if (indices.Length != ArrayRank) {
throw new CannotGetValueException("Given indicies do not have the same dimension as array.");
}
for (int i = 0; i < indices.Length; i++) {
if (indices[i] > ArrayDimensions[i]) {
throw new CannotGetValueException("Given indices are out of range of the array");
}
}
return CorArrayValue.GetElement(indices);
}
/// <summary> Returns all elements in the array </summary>
public NamedValueCollection GetArrayElements()
{
return new NamedValueCollection(GetArrayElementsEnum());
}
IEnumerable<NamedValue> GetArrayElementsEnum()
{
uint[] indices = new uint[ArrayRank];
uint rank = ArrayRank;
uint[] dimensions = ArrayDimensions;
while(true) { // Go thought all combinations
for (uint i = rank - 1; i >= 1; i--) {
if (indices[i] >= dimensions[i]) {
indices[i] = 0;
indices[i-1]++;
}
}
if (indices[0] >= dimensions[0]) break; // We are done
yield return GetArrayElement(indices);
indices[rank - 1]++;
}
}
}
}