/// <summary> /// Processes the index - traverse thru array or sets path to undefined. When memory location contains /// no array and undefined value new array is created. /// </summary> /// <param name="segment">The segment.</param> /// <param name="parentIndex">Index of the parent.</param> /// <param name="visitor">The visitor to process scalar values.</param> /// <param name="isMust">if set to <c>true</c> [is must].</param> private void processIndex(PathSegment segment, MemoryIndex parentIndex, IndexLocationVisitor visitor, bool isMust) { AssociativeArray arrayValue = null; bool processOtherValues = false; MemoryEntry entry; if (snapshot.Data.TryGetMemoryEntry(parentIndex, out entry)) { if (snapshot.Structure.TryGetArray(parentIndex, out arrayValue)) { processOtherValues = entry.Count > 1; } else if (entry.Count > 0) { processOtherValues = true; } else { entry = snapshot.Data.EmptyEntry; processOtherValues = true; } } else { entry = snapshot.Data.EmptyEntry; processOtherValues = true; snapshot.Structure.TryGetArray(parentIndex, out arrayValue); } if (processOtherValues) { visitor.ProcessValues(parentIndex, entry.PossibleValues, isMust); ReadIndexVisitor valueVisitor = visitor.LastValueVisitor; bool removeUndefined = isMust; if (valueVisitor.ContainsDefinedValue || valueVisitor.ContainsAnyValue) { isMust = false; } if (valueVisitor.ContainsUndefinedValue) { if (arrayValue == null) { arrayValue = snapshot.CreateArray(parentIndex, isMust, removeUndefined); } else if (removeUndefined) { snapshot.Structure.Data.RemoveUndefined(parentIndex); } } } if (arrayValue != null) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); creatorVisitor.ArrayValue = arrayValue; processSegment(segment, descriptor, isMust); } }
private IEnumerable <Tuple <Snapshot, ArrayDescriptor> > getArrayDescriptor(AssociativeArray array) { List <Tuple <Snapshot, ArrayDescriptor> > results = new List <Tuple <Snapshot, ArrayDescriptor> >(); ArrayDescriptor descriptor; IEnumerable <Snapshot> snapshots; if (targetSnapshot.Structure.TryGetDescriptor(array, out descriptor)) { results.Add(new Tuple <Snapshot, ArrayDescriptor>(targetSnapshot, descriptor)); } else if (targetSnapshot.Structure.TryGetCallArraySnapshot(array, out snapshots)) { foreach (Snapshot snapshot in snapshots) { ArrayDescriptor snapDescriptor = snapshot.Structure.GetDescriptor(array); results.Add(new Tuple <Snapshot, ArrayDescriptor>(snapshot, snapDescriptor)); } } else { throw new Exception("Missing array descriptor"); } return(results); }
/// <summary> /// Prepares operation for every descendant index of target array. /// </summary> /// <param name="operation">The operation.</param> /// <returns>Array where the input arrays is merged into.</returns> private void mergeArrays(MergeOperation operation) { AssociativeArray targetArray = Structure.GetArray(operation.TargetIndex); ArrayDescriptor targetDescriptor = Structure.GetDescriptor(targetArray); ContainerOperations collectIndexes = new ContainerOperations(this, targetDescriptor.Builder(), operation.TargetIndex, targetDescriptor.UnknownIndex); foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(index, out arrayValue)) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); collectIndexes.AddContainer(descriptor, snapshot); } else { collectIndexes.SetUndefined(); } } collectIndexes.MergeContainers(); }
/// <summary> /// Processes the index - traverse thru array or sets path to undefined. /// </summary> /// <param name="parentIndex">Index of the parent.</param> /// <param name="indexSegment">The index segment.</param> /// <param name="visitor">The visitor to process scalar values.</param> private void processIndex(MemoryIndex parentIndex, IndexPathSegment indexSegment, ProcessValueAsLocationVisitor visitor) { MemoryEntry entry; if (snapshot.Data.TryGetMemoryEntry(parentIndex, out entry)) { bool processOtherValues = false; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(parentIndex, out arrayValue)) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); process(indexSegment, descriptor); processOtherValues = entry.Count > 1; } else if (entry.Count > 0) { processOtherValues = true; } else { IsDefined = false; } if (processOtherValues) { visitor.ProcessValues(parentIndex, entry.PossibleValues, true); } } else { IsDefined = false; } }
/// <summary> /// Prepares operation for every descendant index and merge the array into one which will be /// stored in the target memory entry. /// </summary> /// <param name="operation">The operation.</param> /// <returns>Array where the input arrays is merged into.</returns> private Value mergeArrays(MergeOperation operation) { ArrayDescriptorBuilder builder = new ArrayDescriptorBuilder(); builder.SetParentVariable(operation.TargetIndex); builder.SetUnknownField(operation.TargetIndex.CreateUnknownIndex()); ContainerOperations collectVariables = new ContainerOperations(this, builder, operation.TargetIndex, builder.UnknownIndex); // Collecting possible indexes of merged array AssociativeArray targetArray = null; foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(index, out arrayValue)) { // Target array value will be the firs one if (targetArray == null) { if (index.Equals(operation.TargetIndex)) { targetArray = arrayValue; } } ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); collectVariables.CollectIndexes(snapshot, index, descriptor); } else { collectVariables.SetUndefined(); } } if (targetArray == null) { targetArray = targetSnapshot.CreateArray(); } builder.SetArrayValue(targetArray); collectVariables.MergeContainers(); Structure.SetArray(operation.TargetIndex, targetArray); Structure.SetDescriptor(targetArray, builder.Build()); return(targetArray); }
/// <summary> /// Returns identifiers of all indexes of arrays which was found in memory entry. /// </summary> /// <param name="snapshot">The snapshot.</param> /// <returns>Identifiers of all indexes of arrays which was found in memory entry</returns> public IEnumerable <MemberIdentifier> CollectIndexes(Snapshot snapshot) { HashSet <MemberIdentifier> indexes = new HashSet <MemberIdentifier>(); foreach (AssociativeArray arrayValue in Arrays) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); foreach (string index in descriptor.Indexes.Keys) { indexes.Add(new MemberIdentifier(index)); } } return(indexes); }
/// <summary> /// Initializes a new instance of the <see cref="ArrayDescriptorBuilder"/> class from the given array descriptor. /// </summary> /// <param name="arrayDescriptor">The array descriptor.</param> public ArrayDescriptorBuilder(ArrayDescriptor arrayDescriptor) { IDictionary <string, MemoryIndex> collection = arrayDescriptor.Indexes as IDictionary <string, MemoryIndex>; if (collection != null) { Indexes = new Dictionary <string, MemoryIndex>(collection); } else { Indexes = new Dictionary <string, MemoryIndex>(); } ParentVariable = arrayDescriptor.ParentVariable; UnknownIndex = arrayDescriptor.UnknownIndex; ArrayValue = arrayDescriptor.ArrayValue; }
/// <summary> /// Processes the array value - create new copy of this level of memory tree. /// </summary> /// <param name="targetIndex">Index of the target.</param> /// <param name="value">The value.</param> /// <returns>Array value which should be inserted into target location.</returns> internal AssociativeArray ProcessArrayValue(MemoryIndex targetIndex, AssociativeArray value) { AssociativeArray arrayValue = snapshot.CreateArray(targetIndex, isMust); ArrayDescriptor sourceDescriptor = snapshot.Structure.GetDescriptor(value); ArrayDescriptor targetDescriptor = snapshot.Structure.GetDescriptor(arrayValue); CopyAliasState oldState = AliasState; AliasState = CopyAliasState.OnlyAliases; Copy(sourceDescriptor.UnknownIndex, targetDescriptor.UnknownIndex); AliasState = CopyAliasState.LinkWithIndex; foreach (var index in sourceDescriptor.Indexes) { MemoryIndex newIndex = snapshot.CreateIndex(index.Key, arrayValue, false, false); Copy(index.Value, newIndex); } AliasState = oldState; return(arrayValue); }
private AssociativeArray mergeArrays( MemoryIndex targetIndex, HashSet <AssociativeArray> arrays, bool includeUndefined) { AssociativeArray arrayValue; if (!targetSnapshot.Structure.TryGetArray(targetIndex, out arrayValue)) { arrayValue = targetSnapshot.CreateArray(targetIndex); } ArrayDescriptor newDescriptor = targetSnapshot.Structure.GetDescriptor(arrayValue); MergeOperation unknownMerge = new MergeOperation(newDescriptor.UnknownIndex); unknownMerge.SetUndefined(); addOperation(unknownMerge); HashSet <string> indexNames = new HashSet <string>(); foreach (AssociativeArray array in arrays) { foreach (Tuple <Snapshot, ArrayDescriptor> item in getArrayDescriptor(array)) { Snapshot snapshot = item.Item1; ArrayDescriptor descriptor = item.Item2; unknownMerge.Add(descriptor.UnknownIndex, snapshot); foreach (var index in descriptor.Indexes) { indexNames.Add(index.Key); } } } foreach (string indexName in indexNames) { MergeOperation operation = new MergeOperation(); if (includeUndefined) { operation.SetUndefined(); } foreach (var array in arrays) { foreach (Tuple <Snapshot, ArrayDescriptor> item in getArrayDescriptor(array)) { Snapshot snapshot = item.Item1; ArrayDescriptor descriptor = item.Item2; MemoryIndex sourceIndex; if (descriptor.Indexes.TryGetValue(indexName, out sourceIndex)) { operation.Add(sourceIndex, snapshot); } else { operation.Add(descriptor.UnknownIndex, snapshot); } } } MemoryIndex arrayIndex; if (!newDescriptor.Indexes.TryGetValue(indexName, out arrayIndex)) { arrayIndex = targetSnapshot.CreateIndex(indexName, arrayValue, true, false); } operation.SetTargetIndex(arrayIndex); addOperation(operation); } return(arrayValue); }
/// <summary> /// Sets the array descriptor which contains information about defined indexes in the specified array. /// </summary> /// <param name="arrayvalue">The arrayvalue.</param> /// <param name="descriptor">The descriptor.</param> internal void SetDescriptor(AssociativeArray arrayvalue, ArrayDescriptor descriptor) { lockedTest(); ArrayDescriptors[arrayvalue] = descriptor; }
/// <summary> /// Tries to get array descriptor which contains information about defined indexes in the specified array. /// </summary> /// <param name="arrayValue">The array value.</param> /// <param name="descriptor">The descriptor.</param> /// <returns>Array descriptor which contains information about defined indexes in the specified array.</returns> internal bool TryGetDescriptor(AssociativeArray arrayValue, out ArrayDescriptor descriptor) { return(ArrayDescriptors.TryGetValue(arrayValue, out descriptor)); }