示例#1
0
        public void FillTypelessSubrecordTypes(
            OverlayStream stream,
            int finalPos,
            int offset,
            RecordTypeConverter?recordTypeConverter,
            RecordTypeFillWrapper fill)
        {
            int?lastParsed = null;

            while (!stream.Complete && stream.Position < finalPos)
            {
                SubrecordHeader subMeta         = stream.GetSubrecord();
                var             minimumFinalPos = stream.Position + subMeta.TotalLength;
                var             parsed          = fill(
                    stream: stream,
                    finalPos: finalPos,
                    offset: offset,
                    type: subMeta.RecordType,
                    lastParsed: lastParsed,
                    recordTypeConverter: recordTypeConverter);
                if (parsed.Failed)
                {
                    break;
                }
                if (minimumFinalPos > stream.Position)
                {
                    stream.Position = minimumFinalPos;
                }
                lastParsed = parsed.Value;
            }
        }
示例#2
0
 /// <summary>
 /// Factory
 /// </summary>
 /// <param name="header">Existing SubrecordHeader struct</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 /// <param name="pinLocation">Location pin tracker relative to parent MajorRecordFrame</param>
 public static SubrecordPinFrame FactoryNoTrim(SubrecordHeader header, ReadOnlyMemorySlice <byte> span, int pinLocation)
 {
     return(new SubrecordPinFrame(
                SubrecordFrame.FactoryNoTrim(header, span),
                span,
                pinLocation));
 }
示例#3
0
 public bool TryGetSubrecord(IBinaryReadStream stream, RecordType targetType, out SubrecordHeader meta)
 {
     if (stream.Remaining < SubConstants.HeaderLength)
     {
         meta = default;
         return(false);
     }
     meta = GetSubrecord(stream);
     return(targetType == meta.RecordType);
 }
示例#4
0
 public bool TryGetSubrecord(IBinaryReadStream stream, out SubrecordHeader meta, int offset = 0)
 {
     if (stream.Remaining < SubConstants.HeaderLength + offset)
     {
         meta = default;
         return(false);
     }
     meta = GetSubrecord(stream, offset);
     return(true);
 }
示例#5
0
        public SubrecordFrame SubrecordFrame(ReadOnlySpan <byte> span, RecordType targetType)
        {
            var meta = new SubrecordHeader(this, span);

            if (meta.RecordType != targetType)
            {
                throw new ArgumentException($"Unexpected header type: {meta.RecordType}");
            }
            return(new SubrecordFrame(meta, span));
        }
示例#6
0
        public SubrecordHeader Subrecord(ReadOnlyMemorySlice <byte> span, RecordType targetType)
        {
            var meta = new SubrecordHeader(this, span);

            if (meta.RecordType != targetType)
            {
                throw new ArgumentException($"Unexpected header type: {meta.RecordType}");
            }
            return(meta);
        }
示例#7
0
 public bool TryReadSubrecord(IBinaryReadStream stream, out SubrecordHeader meta)
 {
     if (stream.Remaining < SubConstants.HeaderLength)
     {
         meta = default;
         return(false);
     }
     meta = ReadSubrecord(stream);
     return(true);
 }
示例#8
0
        /// <summary>
        /// Iterates a MajorRecordFrame's subrecords and locates the first occurance of the desired type
        /// </summary>
        /// <param name="majorFrame">Frame to read from</param>
        /// <param name="type">Type to search for</param>
        /// <param name="header">SubrecordHeader if found</param>
        /// <param name="loc">Location of the subrecord, relative to the parent record's RecordType data</param>
        /// <returns>True if matching subrecord is found</returns>
        public static bool TryLocateSubrecord(this MajorRecordFrame majorFrame, RecordType type, int offset, out SubrecordHeader header, out int loc)
        {
            var find = UtilityTranslation.FindFirstSubrecord(majorFrame.Content.Slice(offset - majorFrame.HeaderLength), majorFrame.Meta, type, navigateToContent: false);

            if (find == null)
            {
                header = default;
                loc    = default;
                return(false);
            }
            header = new SubrecordHeader(majorFrame.Meta, majorFrame.Content.Slice(find.Value + offset - majorFrame.HeaderLength));
            loc    = find.Value + offset;
            return(true);
        }
示例#9
0
 public bool TrySubrecord(ReadOnlyMemorySlice <byte> span, RecordType targetType, out SubrecordHeader header)
 {
     if (span.Length < this.SubConstants.HeaderLength)
     {
         header = default;
         return(false);
     }
     header = new SubrecordHeader(this, span);
     if (header.RecordType != targetType)
     {
         header = default;
         return(false);
     }
     return(true);
 }
示例#10
0
        public bool TrySubrecordFrame(ReadOnlyMemorySlice <byte> span, RecordType targetType, out SubrecordFrame header)
        {
            if (span.Length < this.SubConstants.HeaderLength)
            {
                header = default;
                return(false);
            }
            var meta = new SubrecordHeader(this, span);

            if (meta.RecordType != targetType)
            {
                header = default;
                return(false);
            }
            header = Binary.SubrecordFrame.Factory(meta, span);
            return(true);
        }
示例#11
0
        internal static IEnumerable <SubrecordPinFrame> EnumerateSubrecords(ReadOnlyMemorySlice <byte> span, GameConstants meta, int loc, ICollection <RecordType> lengthOverflowTypes)
        {
            while (loc < span.Length)
            {
                var subFrame = new SubrecordPinFrame(meta, span.Slice(loc), loc);
                if (lengthOverflowTypes.Contains(subFrame.RecordType))
                { // Length overflow record
                    var nextLen = subFrame.AsUInt32();
                    loc += subFrame.TotalLength;
                    var nextSpan  = span.Slice(loc, checked ((int)(nextLen + meta.SubConstants.HeaderLength)));
                    var subHeader = new SubrecordHeader(meta, nextSpan);
                    yield return(SubrecordPinFrame.FactoryNoTrim(subHeader, nextSpan, loc));

                    loc += checked ((int)(subHeader.HeaderLength + nextLen));
                    continue;
                }
                yield return(subFrame);

                loc += subFrame.TotalLength;
            }
        }
示例#12
0
        /// <summary>
        /// Enumerates locations of the contained subrecords, while considering some specified RecordTypes as special length overflow subrecords.<br/>
        /// These length overflow subrecords will be skipped, and simply used to parse the next subrecord properly.<br />
        /// Locations are relative to the RecordType of the MajorRecordFrame.
        /// </summary>
        /// <param name="majorFrame">MajorRecordFrame to iterate</param>
        /// <param name="lengthOverflowTypes">Collection of known RecordTypes that signify a length overflow subrecord</param>
        public static IEnumerable <SubrecordPinFrame> EnumerateSubrecords(this MajorRecordFrame majorFrame, ICollection <RecordType> lengthOverflowTypes)
        {
            int loc = majorFrame.HeaderLength;

            while (loc < majorFrame.HeaderAndContentData.Length)
            {
                var subFrame = new SubrecordPinFrame(majorFrame.Meta, majorFrame.HeaderAndContentData.Slice(loc), loc);
                if (lengthOverflowTypes.Contains(subFrame.RecordType))
                { // Length overflow record
                    var nextLen = subFrame.AsUInt32();
                    loc += subFrame.TotalLength;
                    var span      = majorFrame.HeaderAndContentData.Slice(loc, checked ((int)(nextLen + majorFrame.Meta.SubConstants.HeaderLength)));
                    var subHeader = new SubrecordHeader(majorFrame.Meta, span);
                    yield return(SubrecordPinFrame.FactoryNoTrim(subHeader, span, loc));

                    continue;
                }
                yield return(subFrame);

                loc += subFrame.TotalLength;
            }
        }
示例#13
0
 /// <summary>
 /// Factory
 /// </summary>
 /// <param name="header">Existing SubrecordHeader struct</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 public static SubrecordFrame FactoryNoTrim(SubrecordHeader header, ReadOnlyMemorySlice <byte> span)
 {
     return(new SubrecordFrame(header, span));
 }
示例#14
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="header">Existing SubrecordHeader struct</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 public SubrecordMemoryFrame(SubrecordHeader header, ReadOnlyMemorySlice <byte> span)
 {
     this.Header = header;
     this.HeaderAndContentData = span.Slice(0, checked ((int)this.Header.TotalLength));
 }
示例#15
0
 public static bool TryGetSubrecord(this IMutagenReadStream stream, out SubrecordHeader meta, int offset = 0) => stream.MetaData.Constants.TryGetSubrecord(stream, out meta, offset);
示例#16
0
 /// <summary>
 /// Iterates a MajorRecordFrame's contents and locates the first occurance of the desired type
 /// </summary>
 /// <param name="majorFrame">Frame to read from</param>
 /// <param name="type">Type to search for</param>
 /// <param name="header">SubrecordHeader if found</param>
 /// <returns>True if matching subrecord is found</returns>
 public static bool TryLocateSubrecord(this MajorRecordFrame majorFrame, RecordType type, out SubrecordHeader header)
 {
     return(majorFrame.TryLocateSubrecord(type, header: out header, loc: out var _));
 }
示例#17
0
 public bool TryReadSubrecord(IBinaryReadStream stream, RecordType targetType, out SubrecordHeader meta)
 {
     if (stream.Remaining < SubConstants.HeaderLength)
     {
         meta = default;
         return(false);
     }
     meta = ReadSubrecord(stream);
     if (meta.RecordType != targetType)
     {
         stream.Position -= meta.HeaderLength;
         return(false);
     }
     return(true);
 }
示例#18
0
 private SubrecordFrame(SubrecordHeader header, ReadOnlyMemorySlice <byte> span)
 {
     this.Header = header;
     this.HeaderAndContentData = span;
 }
示例#19
0
 public static bool TryReadSubrecord(this IMutagenReadStream stream, RecordType targetType, out SubrecordHeader meta) => stream.MetaData.Constants.TryReadSubrecord(stream, targetType, out meta);
示例#20
0
 /// <summary>
 /// Factory
 /// </summary>
 /// <param name="header">Existing SubrecordHeader struct</param>
 /// <param name="span">Span to overlay on, aligned to the start of the header</param>
 public static SubrecordFrame Factory(SubrecordHeader header, ReadOnlyMemorySlice <byte> span)
 {
     return(new SubrecordFrame(header, span.Slice(0, header.TotalLength)));
 }