public static int[] ParseRecordLocationsByCount( OverlayStream stream, uint count, RecordType trigger, RecordHeaderConstants constants, bool skipHeader) { List <int> ret = new List <int>(); var startingPos = stream.Position; for (uint i = 0; i < count; i++) { var varMeta = constants.GetVariableMeta(stream); var recType = varMeta.RecordType; if (trigger == recType) { if (skipHeader) { stream.Position += varMeta.HeaderLength; ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.RecordLength; } else { ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.TotalLength; } } else { stream.Position += (int)varMeta.TotalLength; } } return(ret.ToArray()); }
public static int[] ParseRecordLocations( OverlayStream stream, ICollectionGetter <RecordType> triggers, RecordHeaderConstants constants, bool skipHeader, RecordTypeConverter?recordTypeConverter = null) { List <int> ret = new List <int>(); var startingPos = stream.Position; while (!stream.Complete) { var varMeta = constants.GetVariableMeta(stream); var recType = recordTypeConverter.ConvertToStandard(varMeta.RecordType); if (!triggers.Contains(recType)) { break; } if (skipHeader) { stream.Position += varMeta.HeaderLength; ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.RecordLength; } else { ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.TotalLength; } } return(ret.ToArray()); }
private HeaderExport( MutagenWriter writer, long sizePosition, RecordHeaderConstants recordConstants) { this.Writer = writer; this.RecordConstants = recordConstants; this.SizePosition = sizePosition; }
public GameConstants( GameConstants rhs, GameRelease releaseOverride) { Release = releaseOverride; ModHeaderLength = rhs.ModHeaderLength; ModHeaderFluffLength = rhs.ModHeaderFluffLength; GroupConstants = rhs.GroupConstants; MajorConstants = rhs.MajorConstants; SubConstants = rhs.SubConstants; }
/// <summary> /// Finds locations of a number of records given by count that match a set of record types. /// A new location is marked each time a record type that has already been encounterd is seen /// </summary> /// <param name="stream">Stream to read and progress</param> /// <param name="count">Number of expected records</param> /// <param name="trigger">Set of record types expected within one record</param> /// <param name="constants">Metadata for reference</param> /// <param name="skipHeader">Whether to skip the header in the return location values</param> /// <returns>Array of located positions relative to the stream's position at the start</returns> public static int[] ParseRecordLocationsByCount( OverlayStream stream, uint count, ICollectionGetter <RecordType> trigger, RecordHeaderConstants constants, bool skipHeader) { var ret = new List <int>(); var set = new HashSet <RecordType>(); var startingPos = stream.Position; while (!stream.Complete) { var varMeta = constants.GetVariableMeta(stream); var recType = varMeta.RecordType; if (trigger.Contains(recType)) { // If new record type we haven't seen before in our current record, just continue if (set.Add(recType) && ret.Count > 0) { stream.Position += (int)varMeta.TotalLength; continue; } // Otherwise mark as a new record location if (skipHeader) { stream.Position += varMeta.HeaderLength; ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.RecordLength; } else { ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.TotalLength; } // Clear set of seen types set.Clear(); set.Add(recType); } else if (ret.Count == count) { break; } else { throw new ArgumentException($"Unexpected record encountered: {recType}. Was expecting: {string.Join(", ", trigger)}"); } } return(ret.ToArray()); }
/// <summary> /// Constructor /// </summary> /// <param name="gameMode">GameMode to associate with the constants</param> /// <param name="modHeaderLength">Length of the ModHeader</param> /// <param name="modHeaderFluffLength">Length of the ModHeader excluding initial recordtype and length bytes.</param> /// <param name="groupConstants">Constants defining Groups</param> /// <param name="majorConstants">Constants defining Major Records</param> /// <param name="subConstants">Constants defining Sub Records</param> public GameConstants( GameMode gameMode, sbyte modHeaderLength, sbyte modHeaderFluffLength, RecordHeaderConstants groupConstants, MajorRecordConstants majorConstants, RecordHeaderConstants subConstants) { GameMode = gameMode; ModHeaderLength = modHeaderLength; ModHeaderFluffLength = modHeaderFluffLength; GroupConstants = groupConstants; MajorConstants = majorConstants; SubConstants = subConstants; }
/// <summary> /// Constructor /// </summary> /// <param name="release">Game Release to associate with the constants</param> /// <param name="modHeaderLength">Length of the ModHeader</param> /// <param name="modHeaderFluffLength">Length of the ModHeader excluding initial recordtype and length bytes.</param> /// <param name="groupConstants">Constants defining Groups</param> /// <param name="majorConstants">Constants defining Major Records</param> /// <param name="subConstants">Constants defining Sub Records</param> public GameConstants( GameRelease release, sbyte modHeaderLength, sbyte modHeaderFluffLength, RecordHeaderConstants groupConstants, MajorRecordConstants majorConstants, RecordHeaderConstants subConstants) { Release = release; ModHeaderLength = modHeaderLength; ModHeaderFluffLength = modHeaderFluffLength; GroupConstants = groupConstants; MajorConstants = majorConstants; SubConstants = subConstants; }
public static int[] ParseRecordLocations( OverlayStream stream, long finalPos, RecordType trigger, RecordType includeTrigger, RecordHeaderConstants constants, bool skipHeader) { List <int> ret = new List <int>(); var startingPos = stream.Position; while (!stream.Complete && stream.Position < finalPos) { var varMeta = constants.GetVariableMeta(stream); var recType = varMeta.RecordType; var isTrigger = trigger == recType; var isIncludeTrigger = includeTrigger == recType; if (!isTrigger && !isIncludeTrigger) { break; } if (isTrigger) { if (skipHeader) { stream.Position += varMeta.HeaderLength; ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.RecordLength; } else { ret.Add(stream.Position - startingPos); stream.Position += (int)varMeta.TotalLength; } } else { stream.Position += (int)varMeta.TotalLength; } } return(ret.ToArray()); }
/// <summary> /// Constructor /// </summary> /// <param name="constants">Record constants to use as reference for alignment</param> /// <param name="span">Span to overlay on, aligned to the start of the header</param> public VariableHeader(RecordHeaderConstants constants, ReadOnlySpan <byte> span) { this.Constants = constants; this.Span = span.Slice(0, constants.HeaderLength); }