mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add SaveDataFile resizing
This commit is contained in:
parent
5c84f5c2a4
commit
8914d89b32
3 changed files with 66 additions and 15 deletions
|
@ -6,7 +6,7 @@ namespace LibHac.IO.Save
|
|||
{
|
||||
private IStorage BaseStorage { get; }
|
||||
private int BlockSize { get; }
|
||||
private int InitialBlock { get; }
|
||||
internal int InitialBlock { get; private set; }
|
||||
private AllocationTable Fat { get; }
|
||||
|
||||
private long _length;
|
||||
|
@ -18,7 +18,7 @@ namespace LibHac.IO.Save
|
|||
Fat = table;
|
||||
InitialBlock = initialBlock;
|
||||
|
||||
_length = table.GetListLength(initialBlock) * blockSize;
|
||||
_length = initialBlock == -1 ? 0 : table.GetListLength(initialBlock) * blockSize;
|
||||
}
|
||||
|
||||
protected override void ReadImpl(Span<byte> destination, long offset)
|
||||
|
@ -81,5 +81,44 @@ namespace LibHac.IO.Save
|
|||
}
|
||||
|
||||
public override long GetSize() => _length;
|
||||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
int oldBlockCount = (int)Util.DivideByRoundUp(_length, BlockSize);
|
||||
int newBlockCount = (int)Util.DivideByRoundUp(size, BlockSize);
|
||||
|
||||
if (oldBlockCount == newBlockCount) return;
|
||||
|
||||
if (oldBlockCount == 0)
|
||||
{
|
||||
InitialBlock = Fat.Allocate(newBlockCount);
|
||||
_length = newBlockCount * BlockSize;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (newBlockCount == 0)
|
||||
{
|
||||
Fat.Free(InitialBlock);
|
||||
|
||||
InitialBlock = -1;
|
||||
_length = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (newBlockCount > oldBlockCount)
|
||||
{
|
||||
int newBlocks = Fat.Allocate(newBlockCount - oldBlockCount);
|
||||
Fat.Join(InitialBlock, newBlocks);
|
||||
}
|
||||
else
|
||||
{
|
||||
int oldBlocks = Fat.Trim(InitialBlock, newBlockCount);
|
||||
Fat.Free(oldBlocks);
|
||||
}
|
||||
|
||||
_length = newBlockCount * BlockSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace LibHac.IO.Save
|
||||
{
|
||||
public class SaveDataFile : FileBase
|
||||
{
|
||||
private AllocationTableStorage BaseStorage { get; }
|
||||
private long Offset { get; }
|
||||
private long Size { get; }
|
||||
private string Path { get; }
|
||||
private HierarchicalSaveFileTable FileTable { get; }
|
||||
private long Size { get; set; }
|
||||
|
||||
public SaveDataFile(AllocationTableStorage baseStorage, long offset, long size, OpenMode mode)
|
||||
public SaveDataFile(AllocationTableStorage baseStorage, string path, HierarchicalSaveFileTable fileTable, long size, OpenMode mode)
|
||||
{
|
||||
Mode = mode;
|
||||
BaseStorage = baseStorage;
|
||||
Offset = offset;
|
||||
Path = path;
|
||||
FileTable = fileTable;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
|
@ -20,8 +23,7 @@ namespace LibHac.IO.Save
|
|||
{
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
|
||||
long storageOffset = Offset + offset;
|
||||
BaseStorage.Read(destination.Slice(0, toRead), storageOffset);
|
||||
BaseStorage.Read(destination.Slice(0, toRead), offset);
|
||||
|
||||
return toRead;
|
||||
}
|
||||
|
@ -45,7 +47,22 @@ namespace LibHac.IO.Save
|
|||
|
||||
public override void SetSize(long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (size < 0) throw new ArgumentOutOfRangeException(nameof(size));
|
||||
if (Size == size) return;
|
||||
|
||||
BaseStorage.SetSize(size);
|
||||
|
||||
if (!FileTable.TryOpenFile(Path, out SaveFileInfo fileInfo))
|
||||
{
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
fileInfo.StartBlock = BaseStorage.InitialBlock;
|
||||
fileInfo.Length = size;
|
||||
|
||||
FileTable.AddFile(Path, ref fileInfo);
|
||||
|
||||
Size = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,14 +86,9 @@ namespace LibHac.IO.Save
|
|||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
if (file.StartBlock < 0)
|
||||
{
|
||||
return new NullFile();
|
||||
}
|
||||
|
||||
AllocationTableStorage storage = OpenFatStorage(file.StartBlock);
|
||||
|
||||
return new SaveDataFile(storage, 0, file.Length, mode);
|
||||
return new SaveDataFile(storage, path, FileTable, file.Length, mode);
|
||||
}
|
||||
|
||||
public void RenameDirectory(string srcPath, string dstPath)
|
||||
|
|
Loading…
Reference in a new issue