Пример #1
0
        public static M SubrecordParse <M>(
            M record,
            MutagenFrame frame,
            RecordTypeConverter?recordTypeConverter,
            RecordStructFill <M> fillStructs,
            SubrecordFill <M> fillTyped)
        {
            fillStructs?.Invoke(
                record: record,
                frame: frame);
            int?lastParsed = null;

            while (!frame.Complete)
            {
                var subMeta  = frame.GetSubrecord();
                var finalPos = frame.Position + subMeta.TotalLength;
                var parsed   = fillTyped(
                    record: record,
                    frame: frame,
                    lastParsed: lastParsed,
                    nextRecordType: subMeta.RecordType,
                    contentLength: subMeta.ContentLength,
                    recordTypeConverter: recordTypeConverter);
                if (parsed.Failed)
                {
                    break;
                }
                if (frame.Position < finalPos)
                {
                    frame.Position = finalPos;
                }
                lastParsed = parsed.Value;
            }
            return(record);
        }
Пример #2
0
 public static M MajorRecordParse <M>(
     M record,
     MutagenFrame frame,
     RecordTypeConverter?recordTypeConverter,
     RecordStructFill <M> fillStructs,
     RecordTypeFill <M> fillTyped)
     where M : IMajorRecordCommonGetter
 {
     frame = frame.SpawnWithFinalPosition(HeaderTranslation.ParseRecord(frame.Reader));
     fillStructs(
         record: record,
         frame: frame);
     if (fillTyped == null)
     {
         return(record);
     }
     try
     {
         MutagenFrame targetFrame = frame;
         if (record.IsCompressed)
         {
             targetFrame = frame.Decompress();
         }
         Dictionary <RecordType, int>?recordParseCount = null;
         frame.MetaData.FormVersion = record.FormVersion;
         while (!targetFrame.Complete)
         {
             var         subMeta  = targetFrame.GetSubrecord();
             var         finalPos = targetFrame.Position + subMeta.TotalLength;
             ParseResult parsed;
             try
             {
                 parsed = fillTyped(
                     record: record,
                     frame: targetFrame,
                     recordParseCount: recordParseCount,
                     nextRecordType: subMeta.RecordType,
                     contentLength: subMeta.ContentLength,
                     recordTypeConverter: recordTypeConverter);
             }
             catch (Exception ex)
             {
                 throw new SubrecordException(
                           subMeta.RecordType,
                           record.FormKey,
                           modKey: frame.Reader.MetaData.ModKey,
                           edid: record.EditorID,
                           innerException: ex);
             }
             if (!parsed.KeepParsing)
             {
                 break;
             }
             if (parsed.DuplicateParseMarker != null)
             {
                 if (recordParseCount == null)
                 {
                     recordParseCount = new Dictionary <RecordType, int>();
                 }
                 recordParseCount[parsed.DuplicateParseMarker !.Value] = recordParseCount.GetOrAdd(parsed.DuplicateParseMarker !.Value) + 1;
Пример #3
0
        static void ParseRegionData(MutagenFrame frame, IRegionInternal item)
        {
            var rdatFrame = frame.GetSubrecordFrame();

            RegionData.RegionDataType dataType = (RegionData.RegionDataType)BinaryPrimitives.ReadUInt32LittleEndian(rdatFrame.Content);
            var subMeta = frame.GetSubrecord(offset: rdatFrame.TotalLength);
            int len     = rdatFrame.TotalLength;

            if (IsExpected(dataType, subMeta.RecordType))
            {
                len += subMeta.TotalLength;
            }
            switch (dataType)
            {
            case RegionData.RegionDataType.Object:
                item.Objects = RegionObjects.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Map:
                item.MapName = RegionMap.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Grass:
                item.Grasses = RegionGrasses.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Sound:
                if (frame.Reader.TryGetSubrecord(out var nextRec, offset: len) &&
                    (nextRec.RecordType.Equals(RDSD) || nextRec.RecordType.Equals(RDMD)))
                {
                    len += nextRec.TotalLength;
                }
                item.Sounds = RegionSounds.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Weather:
                item.Weather = RegionWeather.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Icon:
                frame.Position += frame.MetaData.Constants.SubConstants.HeaderLength + rdatFrame.TotalLength;
                len             = len - frame.MetaData.Constants.SubConstants.HeaderLength - rdatFrame.TotalLength;
                if (StringBinaryTranslation.Instance.Parse(
                        frame.SpawnWithLength(len, checkFraming: false),
                        out var iconVal))
                {
                    item.Icon = iconVal;
                }
                else
                {
                    item.Icon = null;
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }
Пример #4
0
            public static WaterData CreateCustom(MutagenFrame frame)
            {
                var subHeader = frame.GetSubrecord();

                if (subHeader.ContentLength == 2)
                {
                    return(new WaterData()
                    {
                        Versioning = WaterData.VersioningBreaks.Break0
                    });
                }
                else
                {
                    return(WaterData.CreateFromBinary(frame));
                }
            }
Пример #5
0
        public static M MajorRecordParse <M>(
            M record,
            MutagenFrame frame,
            RecordTypeConverter?recordTypeConverter,
            RecordStructFill <M> fillStructs,
            RecordTypeFill <M> fillTyped)
            where M : IMajorRecordCommonGetter
        {
            frame = frame.SpawnWithFinalPosition(HeaderTranslation.ParseRecord(frame.Reader));
            fillStructs(
                record: record,
                frame: frame);
            if (fillTyped == null)
            {
                return(record);
            }
            MutagenFrame targetFrame = frame;

            if (record.IsCompressed)
            {
                targetFrame = frame.Decompress();
            }
            while (!targetFrame.Complete)
            {
                var subMeta  = targetFrame.GetSubrecord();
                var finalPos = targetFrame.Position + subMeta.TotalLength;
                var parsed   = fillTyped(
                    record: record,
                    frame: targetFrame,
                    nextRecordType: subMeta.RecordType,
                    contentLength: subMeta.ContentLength,
                    recordTypeConverter: recordTypeConverter);
                if (parsed.Failed)
                {
                    break;
                }
                if (targetFrame.Position < finalPos)
                {
                    targetFrame.Position = finalPos;
                }
            }
            frame.SetToFinalPosition();
            return(record);
        }
Пример #6
0
        public static M MajorRecordParse <M>(
            M record,
            MutagenFrame frame,
            TypedParseParams?translationParams,
            RecordStructFill <M> fillStructs,
            MajorRecordFill <M> fillTyped)
            where M : IMajorRecordGetter
        {
            frame = frame.SpawnWithFinalPosition(HeaderTranslation.ParseRecord(frame.Reader));
            fillStructs(
                record: record,
                frame: frame);
            try
            {
                MutagenFrame targetFrame = frame;
                if (record.IsCompressed)
                {
                    targetFrame = frame.Decompress();
                }

                Dictionary <RecordType, int>?recordParseCount = null;
                frame.MetaData.FormVersion = record.FormVersion;
                var lastParsed = new PreviousParse();
                while (!targetFrame.Complete)
                {
                    var         subMeta  = targetFrame.GetSubrecord();
                    var         finalPos = targetFrame.Position + subMeta.TotalLength;
                    ParseResult parsed;
                    try
                    {
                        parsed = fillTyped(
                            record: record,
                            frame: targetFrame,
                            lastParsed: lastParsed,
                            recordParseCount: recordParseCount,
                            nextRecordType: subMeta.RecordType,
                            contentLength: lastParsed.LengthOverride ?? subMeta.ContentLength,
                            translationParams: translationParams);
                    }
                    catch (Exception ex)
                    {
                        throw new SubrecordException(
                                  subMeta.RecordType,
                                  record.FormKey,
                                  majorRecordType: record.Registration.ClassType,
                                  modKey: frame.Reader.MetaData.ModKey,
                                  edid: record.EditorID,
                                  innerException: ex);
                    }

                    if (!parsed.KeepParsing)
                    {
                        break;
                    }
                    if (parsed.DuplicateParseMarker != null)
                    {
                        if (recordParseCount == null)
                        {
                            recordParseCount = new Dictionary <RecordType, int>();
                        }

                        recordParseCount[parsed.DuplicateParseMarker !.Value] =
Пример #7
0
        public static void FillBinaryPointToPointConnections(MutagenFrame frame, IPathGridInternal item)
        {
            if (!frame.TryReadSubrecord(RecordTypes.DATA, out var subMeta))
            {
                return;
            }

            uint ptCount = frame.Reader.ReadUInt16();

            if (!frame.Reader.TryReadSubrecord(PGRP, out subMeta))
            {
                return;
            }
            var pointDataSpan = frame.Reader.ReadSpan(subMeta.ContentLength);
            var bytePointsNum = pointDataSpan.Length / POINT_LEN;

            if (bytePointsNum != ptCount)
            {
                throw new ArgumentException($"Unexpected point byte length, when compared to expected point count. {pointDataSpan.Length} bytes: {bytePointsNum} != {ptCount} points.");
            }

            bool readPGRR = false;

            for (int recAttempt = 0; recAttempt < 2; recAttempt++)
            {
                if (frame.Reader.Complete)
                {
                    break;
                }
                subMeta = frame.GetSubrecord();
                switch (subMeta.RecordType.TypeInt)
                {
                case 0x47414750:     //"PGAG":
                    frame.Reader.Position += subMeta.HeaderLength;
                    if (ByteArrayBinaryTranslation <MutagenFrame, MutagenWriter> .Instance.Parse(
                            frame.SpawnWithLength(subMeta.ContentLength, checkFraming: false),
                            item: out var unknownBytes))
                    {
                        item.PGAG = unknownBytes;
                    }
                    else
                    {
                        item.PGAG = default;
                    }
                    break;

                case 0x52524750:     // "PGRR":
                    frame.Reader.Position += subMeta.HeaderLength;
                    var             connectionInts = frame.Reader.ReadSpan(subMeta.ContentLength).AsInt16Span();
                    int             numPts         = pointDataSpan.Length / POINT_LEN;
                    PathGridPoint[] pathGridPoints = new PathGridPoint[numPts];
                    for (int i = 0; i < numPts; i++)
                    {
                        var pt = ReadPathGridPoint(pointDataSpan, out var numConn);
                        pt.Connections.AddRange(connectionInts.Slice(0, numConn).ToArray());
                        pathGridPoints[i] = pt;
                        pointDataSpan     = pointDataSpan.Slice(16);
                        connectionInts    = connectionInts.Slice(numConn);
                    }
                    item.PointToPointConnections = pathGridPoints.ToExtendedList();
                    readPGRR = true;
                    break;

                default:
                    break;
                }
            }

            if (!readPGRR)
            {
                ExtendedList <PathGridPoint> list = new ExtendedList <PathGridPoint>();
                while (pointDataSpan.Length > 0)
                {
                    list.Add(
                        ReadPathGridPoint(pointDataSpan, out var numConn));
                    pointDataSpan = pointDataSpan.Slice(16);
                }
                item.PointToPointConnections = list;
            }
        }