private void UpdateParents(ModelDelta token, ITableRun parent, int segmentIndex, int newValue, IReadOnlyList <int> pointerSources)
        {
            var segmentOffset = parent.ElementContent.Take(segmentIndex).Sum(segment => segment.Length);
            var segmentLength = parent.ElementContent[segmentIndex].Length;

            foreach (var source in pointerSources)
            {
                var offsets = parent.ConvertByteOffsetToArrayOffset(source);
                if (offsets.ElementIndex < 0 || offsets.ElementIndex > parent.ElementCount)
                {
                    continue;
                }
                if (model.ReadMultiByteValue(parent.Start + offsets.ElementIndex * parent.ElementLength + segmentOffset, segmentLength) != newValue)
                {
                    model.WriteMultiByteValue(parent.Start + offsets.ElementIndex * parent.ElementLength + segmentOffset, segmentLength, token, newValue);
                }
            }
        }
Beispiel #2
0
 public ModelArrayElement(IDataModel model, int address, int index)
 {
     (this.model, arrayAddress, arrayIndex) = (model, address, index);
     table = (ITableRun)model.GetNextRun(arrayAddress);
 }
        public static int ParseValue(IDataModel model, ITableRun table, int elementIndex, string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                return(0);
            }
            if (int.TryParse(content, out int simpleValue))
            {
                return(simpleValue);
            }
            if (content == "last")
            {
                return(table.ElementCount - 1);
            }

            if (table != null && table.ElementContent.Any(seg => seg.Name == content))
            {
                return(table.ReadValue(model, elementIndex, content));
            }

            if (content.MatchesPartial("(/=)/"))
            {
                var parts   = content.Split("(/=)".ToCharArray());
                var message = $"Expected {content} to fit the form (table/field=local)/field. But it didn't.";
                if (parts.Length != 6)
                {
                    throw new NotImplementedException(message);
                }
                if (!string.IsNullOrEmpty(parts[0]) || !string.IsNullOrEmpty(parts[4]))
                {
                    throw new NotImplementedException(message);
                }
                var matchTableName  = parts[1];
                var matchTableField = parts[2];
                var matchLocalField = parts[3];
                var localFieldValue = ParseValue(model, table, elementIndex, matchLocalField);
                var valueField      = parts[5];
                var matchTable      = model.GetTable(matchTableName);
                if (matchTable == null)
                {
                    return(0);
                }
                for (int i = 0; i < matchTable.ElementCount; i++)
                {
                    if (matchTable.ReadValue(model, i, matchTableField) != localFieldValue)
                    {
                        continue;
                    }
                    return(ParseValue(model, matchTable, i, valueField));
                }
                return(ParseValue(model, matchTable, matchTable.ElementCount - 1, valueField));
            }
            if (content.MatchesPartial("//"))
            {
                var parts   = content.Split("/");
                var message = $"Expected {content} to fit the form field/index/field. But it didn't.";
                if (parts.Length != 3)
                {
                    throw new NotImplementedException(message);
                }
                var destination = table.ReadPointer(model, elementIndex, parts[0]);
                if (destination == Pointer.NULL)
                {
                    return(0);
                }
                var childTable = model.GetNextRun(destination) as ITableRun;
                if (childTable == null)
                {
                    throw new NotImplementedException(message);
                }
                var childTableIndex = ParseValue(model, childTable, elementIndex, parts[1]);
                return(ParseValue(model, childTable, childTableIndex, parts[2]));
            }

            throw new NotImplementedException();
        }
Beispiel #4
0
        protected ArrayRunPointerSegment GetSegment(ITableRun table, int pointerAddress)
        {
            var offsets = table.ConvertByteOffsetToArrayOffset(pointerAddress);

            return((ArrayRunPointerSegment)table.ElementContent[offsets.SegmentIndex]);
        }