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); }
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;
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(); } }
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)); } }
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); }
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] =
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; } }