Add SaveDataFile resizing

This commit is contained in:
Alex Barney 2019-04-20 14:15:00 -04:00
parent 5c84f5c2a4
commit 8914d89b32
3 changed files with 66 additions and 15 deletions

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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)