Beispiel #1
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 = PluginUtilityTranslation.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);
        }
Beispiel #2
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;
            }
        }
Beispiel #3
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;
            }
        }
Beispiel #4
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 _));
 }
            public static BodyTemplate ParseBodt(ushort version, IMutagenReadStream frame, SubrecordHeader subrecordHeader)
            {
                var len = subrecordHeader.ContentLength;

                if (version == 44 && len <= 8)
                {
                    throw SubrecordException.Create("BODT can not be parsed on versions == 44 if length is <= 8", RecordTypes.BODT);
                }

                var item = new BodyTemplate();

                item.FirstPersonFlags = EnumBinaryTranslation <BipedObjectFlag, IMutagenReadStream, MutagenWriter> .Instance.Parse(
                    reader : frame,
                    length : 4);

                if (len == 8)
                {
                    if (version < 22)
                    {
                        item.Flags = EnumBinaryTranslation <BodyTemplate.Flag, IMutagenReadStream, MutagenWriter> .Instance.Parse(
                            reader : frame,
                            length : 4);
                    }
                    else
                    {
                        item.ArmorType = EnumBinaryTranslation <ArmorType, IMutagenReadStream, MutagenWriter> .Instance.Parse(
                            reader : frame,
                            length : 4);
                    }
                }
                else
                {
                    item.Flags = EnumBinaryTranslation <BodyTemplate.Flag, IMutagenReadStream, MutagenWriter> .Instance.Parse(
                        reader : frame,
                        length : 4);

                    item.ArmorType = EnumBinaryTranslation <ArmorType, IMutagenReadStream, MutagenWriter> .Instance.Parse(
                        reader : frame,
                        length : 4);
                }
                return(item);
            }