public static GroupListOverlay <T> Factory( IBinaryReadStream stream, ReadOnlyMemorySlice <byte> data, BinaryOverlayFactoryPackage package, ObjectType objectType, int offset) { List <int> locations = new List <int>(); stream.Position -= package.MetaData.Constants.GroupConstants.HeaderLength; var groupMeta = stream.GetGroup(package); var finalPos = stream.Position + groupMeta.TotalLength; stream.Position += package.MetaData.Constants.GroupConstants.HeaderLength; // Parse locations while (stream.Position < finalPos) { VariableHeader meta = package.MetaData.Constants.Constants(objectType).VariableMeta(stream.RemainingMemory); locations.Add(checked ((int)stream.Position - offset)); stream.Position += checked ((int)meta.TotalLength); } return(new GroupListOverlay <T>( locations, data, package)); }
public static void FillModTypes( IBinaryReadStream stream, ModTypeFillWrapper fill, BinaryOverlayFactoryPackage package) { int? lastParsed = null; ModHeader headerMeta = stream.GetModHeader(package); var minimumFinalPos = checked ((int)(stream.Position + headerMeta.TotalLength)); fill( stream: stream, finalPos: minimumFinalPos, offset: 0, type: headerMeta.RecordType, lastParsed: lastParsed, recordTypeConverter: null); stream.Position = (int)headerMeta.TotalLength; while (!stream.Complete) { GroupHeader groupMeta = stream.GetGroup(package); if (!groupMeta.IsGroup) { throw new ArgumentException("Did not see GRUP header as expected."); } if (groupMeta.ContentLength == 0) { stream.Position += groupMeta.TotalLength; continue; } minimumFinalPos = checked ((int)(stream.Position + groupMeta.TotalLength)); var parsed = fill( stream: stream, finalPos: minimumFinalPos, offset: 0, type: groupMeta.ContainedRecordType, lastParsed: lastParsed, recordTypeConverter: null); if (!parsed.KeepParsing) { break; } if (!parsed.KeepParsing) { break; } if (minimumFinalPos > stream.Position) { stream.Position = checked ((int)minimumFinalPos); } lastParsed = parsed.ParsedIndex; } }
public static GroupMajorRecordCacheWrapper <T> Factory( IBinaryReadStream stream, ReadOnlyMemorySlice <byte> data, BinaryOverlayFactoryPackage package, int offset) { Dictionary <FormKey, int> locationDict = new Dictionary <FormKey, int>(); stream.Position -= package.MetaData.Constants.GroupConstants.HeaderLength; var groupMeta = stream.GetGroup(package.MetaData); var finalPos = stream.Position + groupMeta.TotalLength; stream.Position += package.MetaData.Constants.GroupConstants.HeaderLength; // Parse MajorRecord locations ObjectType?lastParsed = default; while (stream.Position < finalPos) { VariableHeader varMeta = package.MetaData.Constants.NextRecordVariableMeta(stream.RemainingMemory); if (varMeta.IsGroup) { if (lastParsed != ObjectType.Record) { throw new DataMisalignedException("Unexpected Group encountered which was not after a major record: " + GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE); } stream.Position += checked ((int)varMeta.TotalLength); lastParsed = ObjectType.Group; } else { MajorRecordHeader majorMeta = package.MetaData.Constants.MajorRecord(stream.RemainingMemory); if (majorMeta.RecordType != GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE) { throw new DataMisalignedException("Unexpected type encountered when parsing MajorRecord locations: " + majorMeta.RecordType); } var formKey = FormKey.Factory(package.MetaData.MasterReferences !, majorMeta.FormID.Raw); locationDict.Add(formKey, checked ((int)(stream.Position - offset))); stream.Position += checked ((int)majorMeta.TotalLength); lastParsed = ObjectType.Record; } } return(new GroupMajorRecordCacheWrapper <T>( locationDict, data, package)); }