Skip to content

Commit

Permalink
cleanup ifilesystem
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotr7 committed Nov 25, 2024
1 parent 66fd083 commit d06a8c8
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 75 deletions.
102 changes: 102 additions & 0 deletions src/StarBreaker.P4k/P4kFile.FileSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using StarBreaker.FileSystem;

namespace StarBreaker.P4k;

public sealed partial class P4kFile : IFileSystem
{
public IEnumerable<string> GetDirectories(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');
var current = Root;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current.Children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
yield break;
}

current = value;
}

foreach (var child in current.Children.Values.Where(x => x.ZipEntry == null))
{
yield return child.Name;
}
}

public IEnumerable<string> GetFiles(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');

var current = Root;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current.Children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
yield break;
}

current = value;
}

foreach (var child in current.Children.Values.Where(x => x.ZipEntry != null))
{
yield return child.Name;
}
}

public bool Exists(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');
var current = Root;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current.Children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
return false;
}

current = value;
}

return current.ZipEntry != null;
}

public Stream OpenRead(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');
var current = Root;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current.Children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
throw new FileNotFoundException();
}

current = value;
}

if (current.ZipEntry == null)
{
throw new FileNotFoundException();
}

return Open(current.ZipEntry);
}
}
7 changes: 4 additions & 3 deletions src/StarBreaker.P4k/P4kFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace StarBreaker.P4k;

public sealed class P4kFile
public sealed partial class P4kFile
{
private readonly Aes _aes;

Expand Down Expand Up @@ -67,6 +67,7 @@ public static P4kFile FromFile(string filePath, IProgress<double>? progress = nu

var entries = new ZipEntry[eocd64.TotalEntries];

//use a channel so we can read entries and build the file system in parallel
var channel = Channel.CreateUnbounded<ZipEntry>();

var channelInsertTask = Task.Run(async () =>
Expand Down Expand Up @@ -224,7 +225,7 @@ public void Extract(string outputDir, string? filter = null, IProgress<double>?

public Stream Open(ZipEntry entry)
{
var p4kStream = new FileStream(P4KPath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 131072, useAsync: false);
var p4kStream = new FileStream(P4KPath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: (int)entry.UncompressedSize, useAsync: false);

p4kStream.Seek((long)entry.Offset, SeekOrigin.Begin);
if (p4kStream.Read<uint>() is not 0x14034B50 and not 0x04034B50)
Expand Down Expand Up @@ -312,4 +313,4 @@ public static List<ZipExtraField> ReadExtraFields(BinaryReader br, ushort length

return fields;
}
}
}
1 change: 1 addition & 0 deletions src/StarBreaker.P4k/StarBreaker.P4k.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
<ItemGroup>
<ProjectReference Include="..\StarBreaker.Common\StarBreaker.Common.csproj" />
<ProjectReference Include="..\StarBreaker.CryXmlB\StarBreaker.CryXmlB.csproj" />
<ProjectReference Include="..\StarBreaker.FileSystem\StarBreaker.FileSystem.csproj" />
</ItemGroup>
</Project>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
78 changes: 13 additions & 65 deletions src/StarBreaker.P4k/ZipNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,30 @@ namespace StarBreaker.P4k;
public sealed class ZipNode
{
private static readonly Dictionary<int, ZipNode> _empty = new();
private readonly string _name;
private readonly ZipEntry? _zipEntry;
private readonly Dictionary<int, ZipNode> _children;

public string Name => _name;
public ZipEntry? ZipEntry => _zipEntry;
public Dictionary<int, ZipNode> Children => _children;
public string Name { get; }
public ZipEntry? ZipEntry { get; }
public Dictionary<int, ZipNode> Children { get; }

public ZipNode(string name)
{
_name = name;
_zipEntry = null;
_children = [];
Name = name;
ZipEntry = null;
Children = [];
}

public ZipNode(ZipEntry file, string name)
{
_name = name;
_zipEntry = file;
_children = _empty;
Name = name;
ZipEntry = file;
Children = _empty;
}

public void Insert(ZipEntry zipEntry)
{
var current = this;
var name = zipEntry.Name.AsSpan();

foreach (var range in name.Split('\\'))
{
var part = name[range];
Expand All @@ -41,66 +38,17 @@ public void Insert(ZipEntry zipEntry)
if (range.End.Value == name.Length)
{
// If this is the last part, we're at the file
current._children[partHashCode] = new ZipNode(zipEntry, part.ToString());
current.Children[partHashCode] = new ZipNode(zipEntry, part.ToString());
return;
}

if (!current._children.TryGetValue(partHashCode, out var value))
if (!current.Children.TryGetValue(partHashCode, out var value))
{
value = new ZipNode(part.ToString());
current._children[partHashCode] = value;
}

current = value;
}
}

public IEnumerable<string> GetDirectories(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');
var current = this;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current._children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
yield break;
}

current = value;
}

foreach (var child in current._children.Values.Where(x => x.ZipEntry == null))
{
yield return child.Name;
}
}

public IEnumerable<string> GetFiles(string path)
{
Span<Range> ranges = stackalloc Range[20];
var span = path.AsSpan();
var partsCount = span.Split(ranges, '\\');

var current = this;

for (var index = 0; index < partsCount; index++)
{
var part = ranges[index];
if (!current._children.TryGetValue(string.GetHashCode(span[part]), out var value))
{
yield break;
current.Children[partHashCode] = value;
}

current = value;
}

foreach (var child in current._children.Values.Where(x => x.ZipEntry != null))
{
yield return child.Name;
}
}
}
12 changes: 5 additions & 7 deletions src/StarBreaker/Screens/Tabs/DataCore/DataCoreTabViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ public DataCoreTabViewModel(IP4kService p4kService)

private void Initialize()
{
// //TODO: use IFileSystem for this
// var entry = _p4KService.P4kFile.Entries.FirstOrDefault(e => e.Name == dataCorePath);
// var stream = _p4KService.P4kFile.Open(entry);
// var forge = new DataForge(stream);
// stream.Dispose();
//
// Dispatcher.UIThread.InvokeAsync(() => Forge = forge);
var entry = _p4KService.P4kFile.OpenRead(dataCorePath);
var forge = new DataForge(entry);
entry.Dispose();

Dispatcher.UIThread.InvokeAsync(() => Forge = forge);
}

[ObservableProperty]
Expand Down

0 comments on commit d06a8c8

Please sign in to comment.