2021-09-27 12:42:46 +00:00
|
|
|
using System.Collections.Generic;
|
2020-07-10 22:59:39 +00:00
|
|
|
using System.IO;
|
2021-06-16 21:07:16 +00:00
|
|
|
using System.IO.Compression;
|
2021-01-05 22:09:32 +00:00
|
|
|
using System.Text;
|
2021-09-27 12:42:46 +00:00
|
|
|
using Wabbajack.DTOs.Texture;
|
|
|
|
using Wabbajack.Hashing.xxHash64;
|
|
|
|
using Wabbajack.Paths;
|
2020-01-09 22:56:29 +00:00
|
|
|
|
2021-09-27 12:42:46 +00:00
|
|
|
namespace Wabbajack.VFS
|
2020-01-09 22:56:29 +00:00
|
|
|
{
|
|
|
|
public class IndexedVirtualFile
|
|
|
|
{
|
2020-03-24 12:21:19 +00:00
|
|
|
public IPath Name { get; set; }
|
2020-03-22 15:50:53 +00:00
|
|
|
public Hash Hash { get; set; }
|
2021-09-27 12:42:46 +00:00
|
|
|
|
|
|
|
public ImageState? ImageState { get; set; }
|
2020-01-09 22:56:29 +00:00
|
|
|
public long Size { get; set; }
|
2021-06-16 05:16:25 +00:00
|
|
|
public List<IndexedVirtualFile> Children { get; set; } = new();
|
2020-07-10 22:59:39 +00:00
|
|
|
|
|
|
|
private void Write(BinaryWriter bw)
|
|
|
|
{
|
2021-09-27 12:42:46 +00:00
|
|
|
bw.Write(Name.ToString()!);
|
2020-07-10 22:59:39 +00:00
|
|
|
bw.Write((ulong)Hash);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-06-16 21:07:16 +00:00
|
|
|
if (ImageState == null)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-06-16 21:07:16 +00:00
|
|
|
bw.Write(false);
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
2021-06-16 21:07:16 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
bw.Write(true);
|
2021-09-27 12:42:46 +00:00
|
|
|
WriteImageState(bw, ImageState);
|
2021-06-16 21:07:16 +00:00
|
|
|
}
|
|
|
|
|
2020-07-10 22:59:39 +00:00
|
|
|
bw.Write(Size);
|
|
|
|
bw.Write(Children.Count);
|
|
|
|
foreach (var file in Children)
|
|
|
|
file.Write(bw);
|
|
|
|
}
|
|
|
|
|
2021-09-27 12:42:46 +00:00
|
|
|
private void WriteImageState(BinaryWriter bw, ImageState state)
|
|
|
|
{
|
|
|
|
bw.Write((ushort)state.Width);
|
|
|
|
bw.Write((ushort)state.Height);
|
|
|
|
bw.Write((byte)state.Format);
|
|
|
|
state.PerceptualHash.Write(bw);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ImageState ReadImageState(BinaryReader br)
|
|
|
|
{
|
|
|
|
return new ImageState
|
|
|
|
{
|
|
|
|
Width = br.ReadUInt16(),
|
|
|
|
Height = br.ReadUInt16(),
|
|
|
|
Format = (DXGI_FORMAT)br.ReadByte(),
|
|
|
|
PerceptualHash = PHash.Read(br)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-07-10 22:59:39 +00:00
|
|
|
public void Write(Stream s)
|
|
|
|
{
|
2021-09-27 12:42:46 +00:00
|
|
|
using var cs = new GZipStream(s, CompressionLevel.Optimal, true);
|
2021-06-16 21:07:16 +00:00
|
|
|
using var bw = new BinaryWriter(cs, Encoding.UTF8, true);
|
2021-07-17 05:32:37 +00:00
|
|
|
Write(bw);
|
2020-07-10 22:59:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private static IndexedVirtualFile Read(BinaryReader br)
|
|
|
|
{
|
|
|
|
var ivf = new IndexedVirtualFile
|
|
|
|
{
|
|
|
|
Name = (RelativePath)br.ReadString(),
|
2021-09-27 12:42:46 +00:00
|
|
|
Hash = Hash.FromULong(br.ReadUInt64())
|
2020-07-10 22:59:39 +00:00
|
|
|
};
|
2021-06-16 21:07:16 +00:00
|
|
|
|
2021-09-27 12:42:46 +00:00
|
|
|
if (br.ReadBoolean())
|
|
|
|
ivf.ImageState = ReadImageState(br);
|
|
|
|
|
2021-06-16 21:07:16 +00:00
|
|
|
ivf.Size = br.ReadInt64();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2020-07-10 22:59:39 +00:00
|
|
|
var lst = new List<IndexedVirtualFile>();
|
2020-07-15 03:04:31 +00:00
|
|
|
ivf.Children = lst;
|
2020-07-10 22:59:39 +00:00
|
|
|
var count = br.ReadInt32();
|
2021-09-27 12:42:46 +00:00
|
|
|
for (var x = 0; x < count; x++) lst.Add(Read(br));
|
2020-07-15 03:04:31 +00:00
|
|
|
|
2020-07-10 22:59:39 +00:00
|
|
|
return ivf;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static IndexedVirtualFile Read(Stream s)
|
|
|
|
{
|
2021-06-16 21:07:16 +00:00
|
|
|
using var cs = new GZipStream(s, CompressionMode.Decompress, true);
|
|
|
|
using var br = new BinaryReader(cs);
|
2021-07-17 05:32:37 +00:00
|
|
|
return Read(br);
|
2020-07-10 22:59:39 +00:00
|
|
|
}
|
2020-01-09 22:56:29 +00:00
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|