public override IDataFormat CreateDataFormat(IDataModel data, int index) { var destinationAddress = data.ReadPointer(Start); var anchor = data.GetAnchorFromAddress(Start, destinationAddress); var pointer = new Pointer(Start, index - Start, destinationAddress, anchor); return(pointer); }
public override IDataFormat CreateDataFormat(IDataModel data, int index) { var offsets = ConvertByteOffsetToArrayOffset(index); var currentSegment = ElementContent[offsets.SegmentIndex]; if (currentSegment.Type == ElementContentType.PCS) { if (currentCachedStartIndex != offsets.SegmentStart || currentCachedIndex > offsets.SegmentOffset) { currentCachedStartIndex = offsets.SegmentStart; currentCachedIndex = offsets.SegmentOffset; cachedCurrentString = PCSString.Convert(data, offsets.SegmentStart, currentSegment.Length); } return(PCSRun.CreatePCSFormat(data, offsets.SegmentStart, index, cachedCurrentString)); } var position = index - offsets.SegmentStart; if (currentSegment.Type == ElementContentType.Integer) { if (currentSegment is ArrayRunEnumSegment enumSegment) { var value = enumSegment.ToText(data, index); return(new IntegerEnum(offsets.SegmentStart, position, value, currentSegment.Length)); } else { var value = ArrayRunElementSegment.ToInteger(data, offsets.SegmentStart, currentSegment.Length); return(new Integer(offsets.SegmentStart, position, value, currentSegment.Length)); } } if (currentSegment.Type == ElementContentType.Pointer) { var destination = data.ReadPointer(offsets.SegmentStart); var destinationName = data.GetAnchorFromAddress(offsets.SegmentStart, destination); return(new Pointer(offsets.SegmentStart, position, destination, destinationName)); } if (currentSegment.Type == ElementContentType.BitArray) { return(new BitArray(offsets.SegmentStart, position, currentSegment.Length)); } throw new NotImplementedException(); }
private ArrayRun(IDataModel data, string format, int start, IReadOnlyList <int> pointerSources) : base(start, pointerSources) { owner = data; FormatString = format; SupportsPointersToElements = format.StartsWith(AnchorStart.ToString()); if (SupportsPointersToElements) { format = format.Substring(1); } var closeArray = format.LastIndexOf(ArrayEnd.ToString()); if (!format.StartsWith(ArrayStart.ToString()) || closeArray == -1) { throw new ArrayRunParseException($"Array Content must be wrapped in {ArrayStart}{ArrayEnd}."); } var segments = format.Substring(1, closeArray - 1); var length = format.Substring(closeArray + 1); ElementContent = ParseSegments(segments, data); if (ElementContent.Count == 0) { throw new ArrayRunParseException("Array Content must not be empty."); } ElementLength = ElementContent.Sum(e => e.Length); FormatMatchFlags flags = default; if (ElementContent.Count == 1) { flags |= FormatMatchFlags.IsSingleSegment; } if (length.Length == 0) { var nextRun = owner.GetNextAnchor(Start + ElementLength); for (; true; nextRun = owner.GetNextAnchor(nextRun.Start + nextRun.Length)) { if (nextRun.Start > owner.Count) { break; } var anchorName = owner.GetAnchorFromAddress(-1, nextRun.Start); if (string.IsNullOrEmpty(anchorName)) { continue; } if ((nextRun.Start - Start) % ElementLength != 0) { break; } } var byteLength = 0; var elementCount = 0; while (Start + byteLength + ElementLength <= nextRun.Start && DataMatchesElementFormat(owner, Start + byteLength, ElementContent, flags, nextRun)) { byteLength += ElementLength; elementCount++; if (elementCount == 100) { flags |= FormatMatchFlags.AllowJunkAfterText; } } LengthFromAnchor = string.Empty; ElementCount = Math.Max(1, elementCount); // if the user said there's a format here, then there is, even if the format it wrong. FormatString += ElementCount; } else if (int.TryParse(length, out int result)) { // fixed length is easy LengthFromAnchor = string.Empty; ElementCount = Math.Max(1, result); } else { LengthFromAnchor = length; ElementCount = Math.Max(1, ParseLengthFromAnchor()); } Length = ElementLength * ElementCount; }