public bool HasSameSegments(ArrayRun other)
 {
     if (other == null)
     {
         return(false);
     }
     if (other.ElementContent.Count != ElementContent.Count)
     {
         return(false);
     }
     for (int i = 0; i < ElementContent.Count; i++)
     {
         var mine   = ElementContent[i];
         var theirs = other.ElementContent[i];
         if (mine.Type != theirs.Type || mine.Length != theirs.Length)
         {
             return(false);
         }
         if (mine is ArrayRunEnumSegment enumSegment)
         {
             if (!(theirs is ArrayRunEnumSegment enumSegment2))
             {
                 return(false);
             }
             if (enumSegment.EnumName != enumSegment2.EnumName)
             {
                 return(false);
             }
         }
         if (mine is ArrayRunPointerSegment pointerSegment)
         {
             if (!(theirs is ArrayRunPointerSegment pointerSegment2))
             {
                 return(false);
             }
             if (pointerSegment.InnerFormat != pointerSegment2.InnerFormat)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
 public TableStreamRun(
     IDataModel model,
     int start,
     SortedSpan <int> sources,
     string formatString,
     IReadOnlyList <ArrayRunElementSegment> parsedSegments,
     IStreamEndStrategy endStream,
     int elementCountOverride
     ) : base(start, sources)
 {
     if (parsedSegments == null)
     {
         parsedSegments = ArrayRun.ParseSegments(formatString.Substring(1, formatString.Length - 2), model);
     }
     this.model     = model;
     ElementContent = parsedSegments;
     this.endStream = endStream;
     ElementLength  = parsedSegments.Sum(segment => segment.Length);
     ElementCount   = elementCountOverride >= 0 ? elementCountOverride : endStream.GetCount(start, ElementLength, sources);
     Length         = ElementLength * ElementCount + endStream.ExtraLength;
     FormatString   = formatString;
 }
Exemple #3
0
        public HeaderRow(ArrayRun source, int byteStart, int length)
        {
            var headers = new List <ColumnHeader>();
            // we know which 'byte' to start at, but we want to know what 'index' to start at
            // basically, count off each element to figure out how big it is
            int currentByte = 0;
            int startIndex  = 0;

            while (currentByte < byteStart)
            {
                currentByte += source.ElementContent[startIndex % source.ElementContent.Count].Length;
                startIndex++;
            }
            int initialPartialSegmentLength = currentByte - byteStart;

            if (initialPartialSegmentLength > 0)
            {
                startIndex--;
            }
            currentByte = 0;
            for (int i = 0; currentByte < length; i++)
            {
                var segment = source.ElementContent[(startIndex + i) % source.ElementContent.Count];
                if (initialPartialSegmentLength != 0)
                {
                    headers.Add(new ColumnHeader(segment.Name, initialPartialSegmentLength));
                    currentByte += initialPartialSegmentLength;
                }
                else
                {
                    headers.Add(new ColumnHeader(segment.Name, segment.Length));
                    currentByte += segment.Length;
                }
                initialPartialSegmentLength = 0;
            }
            ColumnHeaders = headers;
        }
        public static bool TrySearch(IDataModel data, ModelDelta changeToken, string originalFormat, out ArrayRun self, Func <IFormattedRun, bool> runFilter = null)
        {
            self = null;
            var format = originalFormat;
            var allowPointersToEntries = format.StartsWith(AnchorStart.ToString());

            if (allowPointersToEntries)
            {
                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);
            var elementContent = ParseSegments(segments, data);

            if (elementContent.Count == 0)
            {
                return(false);
            }
            var elementLength = elementContent.Sum(e => e.Length);

            using (ModelCacheScope.CreateScope(data)) {
                if (string.IsNullOrEmpty(length))
                {
                    var bestAddress = StandardSearch(data, elementContent, elementLength, out int bestLength, runFilter);
                    if (bestAddress == Pointer.NULL)
                    {
                        return(false);
                    }
                    self = new ArrayRun(data, originalFormat + bestLength, string.Empty, bestAddress, bestLength, elementContent, data.GetNextRun(bestAddress).PointerSources, null);
                }
                else
                {
                    var bestAddress = KnownLengthSearch(data, elementContent, elementLength, length, out int bestLength, runFilter);
                    if (bestAddress == Pointer.NULL)
                    {
                        return(false);
                    }
                    var lengthFromAnchor = int.TryParse(length, out var _) ? string.Empty : length;
                    self = new ArrayRun(data, originalFormat, lengthFromAnchor, bestAddress, bestLength, elementContent, data.GetNextRun(bestAddress).PointerSources, null);
                }
            }

            if (allowPointersToEntries)
            {
                self = self.AddSourcesPointingWithinArray(changeToken);
            }
            return(true);
        }
        public static ErrorInfo TryParse(IDataModel data, string format, int start, IReadOnlyList <int> pointerSources, out ArrayRun self)
        {
            try {
                using (ModelCacheScope.CreateScope(data)) {
                    self = new ArrayRun(data, format, start, pointerSources);
                }
            } catch (ArrayRunParseException e) {
                self = null;
                return(new ErrorInfo(e.Message));
            }

            return(ErrorInfo.NoError);
        }