protected RecordGroup ReadGRUP(Header header, bool loadAll, ProxySink.DataInfo info) { var headerBytes = _r.ReadAbsoluteBytes(header.HeaderPosition, (int)(header.Position - header.HeaderPosition)); var nextPosition = _r.Position + header.DataSize; var label = header.Label; info?.AddGroup(label, headerBytes); if (GroupByLabel == null) { GroupByLabel = new Dictionary <string, RecordGroup>(); } if (!GroupByLabel.TryGetValue(label, out var group)) { GroupByLabel.Add(label, group = new RecordGroup(_proxySink, _r, FilePath, Format, RecordLevel, Depth + 1)); } else { group = new RecordGroup(_proxySink, _r, FilePath, Format, RecordLevel, Depth + 1) { Next = group } }; group.AddHeader(header, info); _r.Position = nextPosition; if (loadAll || info != null) { group.Load(loadAll, info); } //Log($"Grup: {string.Join("/", GetHeaderPath(new List<string>(), parentHeader).ToArray())} {parentHeader.GroupType}"); return(group); }
public void Write(BinaryFileWriter w, GameFormat format) { w.WriteASCIIString(Type, 4); if (Type == "GRUP") { w.Write(DataSize + (format == GameFormat.TES4 ? 20 : 24)); w.Write(RecordGroup.FromLabel(Group.Depth == 0, Label), 0, 4); w.Write((int)GroupType); w.Write(0U); // stamp | stamp + uknown if (format != GameFormat.TES4) { w.Write(0U); // version + uknown } return; } w.Write(DataSize); if (format == GameFormat.TES3) { w.Write(0U); // unknown } w.Write((uint)Flags); if (format == GameFormat.TES3) { return; } // tes4 w.Write(FormId); w.Write(0U); if (format == GameFormat.TES4) { return; } // tes5 w.Write(0U); }
void ReadTES3Transform(RecordGroup group, ProxySink.DataInfo info) => GroupByLabel = group.Records.GroupBy(x => x.Header.Type) .ToDictionary(x => x.Key, x => { var s = new RecordGroup(_proxySink, _r, FilePath, Format, RecordLevel, Depth + 1) { Records = x.ToList() }; s.AddHeader(new Header { Label = x.Key }, info); return(s); });
public Header(RecordGroup group, BinaryFileReader r, GameFormat format) { Group = group; HeaderPosition = r.Position; Type = r.ReadASCIIString(4); if (Type == "GRUP") { DataSize = (uint)(r.ReadUInt32() - (format == GameFormat.TES4 ? 20 : 24)); Label = RecordGroup.ToLabel(Group.Depth == 0, r.ReadBytes(4)); GroupType = (HeaderGroupType)r.ReadInt32(); r.ReadUInt32(); // stamp | stamp + uknown if (format != GameFormat.TES4) { r.ReadUInt32(); // version + uknown } Position = r.Position; return; } DataSize = r.ReadUInt32(); if (format == GameFormat.TES3) { r.ReadUInt32(); // unknown } Flags = (HeaderFlags)r.ReadUInt32(); if (format == GameFormat.TES3) { Position = r.Position; return; } // tes4 FormId = r.ReadUInt32(); r.ReadUInt32(); if (format == GameFormat.TES4) { Position = r.Position; return; } // tes5 r.ReadUInt32(); Position = r.Position; }
protected RecordGroup ReadGRUP(ProxySink.DataInfo info, string path) { var stack = new Stack <RecordGroup>(); if (GroupByLabel == null) { GroupByLabel = new Dictionary <string, RecordGroup>(); } var groupByLabel = GroupByLabel; var r = new BinaryFileReader(new MemoryStream()); var depth = 0; RecordGroup group = this; info.Decoder( group: (label, headerData) => { var filePath = ToPath(stack.Reverse().Select(x => x.Label).Concat(new[] { label }).ToArray()); // write data if (path != null) { var bytes = LoadDataLabelAsync(filePath).Result(); File.WriteAllBytes(Path.Combine(path, filePath), bytes); return; } if (Format != GameFormat.TES3) { if (!groupByLabel.TryGetValue(label, out group)) { groupByLabel.Add(label, group = new RecordGroup(_proxySink, null, filePath, Format, RecordLevel, depth)); } else { group = new RecordGroup(_proxySink, null, filePath, Format, RecordLevel, depth) { Next = group } } } ; r.Position = 0; r.BaseStream.Write(headerData, 0, headerData.Length); r.Position = 0; var header = new Header(group, r, Format) { DataSize = 0, Position = 0 }; group.AddHeader(header, null); }, enterGroup: () => { stack.Push(group); if (path == null) { groupByLabel = group.GroupByLabel = new Dictionary <string, RecordGroup>(); } depth++; }, leaveGroup: () => { group = stack.Pop(); if (path == null) { groupByLabel = group.GroupByLabel; } depth--; } ); if (Format == GameFormat.TES3) { group.Load(true, info); ReadTES3Transform(group, info); } return(this); }