protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) { path = PathTools.Normalize(path); if (size == 0) { var emptyFileEntry = new SaveFileInfo { StartBlock = int.MinValue, Length = size }; FileTable.AddFile(path, ref emptyFileEntry); return(Result.Success); } int blockCount = (int)Util.DivideByRoundUp(size, AllocationTable.Header.BlockSize); int startBlock = AllocationTable.Allocate(blockCount); if (startBlock == -1) { return(ResultFs.AllocationTableInsufficientFreeBlocks.Log()); } var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size }; FileTable.AddFile(path, ref fileEntry); return(Result.Success); }
public bool FindNextFile(ref SaveFindPosition position, out SaveFileInfo info, out string name) { if (position.NextFile == 0) { info = default; name = default; return(false); } Span <byte> nameBytes = stackalloc byte[FileTable.MaxNameLength]; bool success = FileTable.TryGetValue(position.NextFile, out TableEntry <SaveFileInfo> entry, ref nameBytes); // todo error message if (!success) { info = default; name = default; return(false); } position.NextFile = entry.NextSibling; info = entry.Value; name = StringUtils.NullTerminatedUtf8ToString(nameBytes); return(true); }
public void AddFile(U8Span path, ref SaveFileInfo fileInfo) { if (path.Length == 1 && path[0] == '/') { throw new ArgumentException("Path cannot be empty"); } CreateFileRecursive(path, ref fileInfo); }
public void AddFile(string path, ref SaveFileInfo fileInfo) { path = PathTools.Normalize(path); ReadOnlySpan <byte> pathBytes = Util.GetUtf8Bytes(path); if (path == "/") { throw new ArgumentException("Path cannot be empty"); } CreateFileRecursive(pathBytes, ref fileInfo); }
public bool TryOpenFile(U8Span path, out SaveFileInfo fileInfo) { if (!FindPathRecursive(path, out SaveEntryKey key)) { fileInfo = default; return(false); } if (FileTable.TryGetValue(ref key, out TableEntry <SaveFileInfo> value)) { fileInfo = value.Value; return(true); } fileInfo = default; return(false); }
protected override Result DoCreateFile(U8Span path, long size, CreateFileOptions options) { FsPath normalizedPath; unsafe { _ = &normalizedPath; } // workaround for CS0165 Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false); if (rc.IsFailure()) { return(rc); } if (size == 0) { var emptyFileEntry = new SaveFileInfo { StartBlock = int.MinValue, Length = size }; FileTable.AddFile(normalizedPath, ref emptyFileEntry); return(Result.Success); } int blockCount = (int)Utilities.DivideByRoundUp(size, AllocationTable.Header.BlockSize); int startBlock = AllocationTable.Allocate(blockCount); if (startBlock == -1) { return(ResultFs.AllocationTableInsufficientFreeBlocks.Log()); } var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size }; FileTable.AddFile(normalizedPath, ref fileEntry); return(Result.Success); }
protected override Result DoCreateFile(U8Span path, long size, CreateFileOptions options) { Unsafe.SkipInit(out FsPath normalizedPath); Result rc = PathNormalizer.Normalize(normalizedPath.Str, out _, path, false, false); if (rc.IsFailure()) { return(rc); } if (size == 0) { var emptyFileEntry = new SaveFileInfo { StartBlock = int.MinValue, Length = size }; FileTable.AddFile(normalizedPath, ref emptyFileEntry); return(Result.Success); } int blockCount = (int)BitUtil.DivideUp(size, AllocationTable.Header.BlockSize); int startBlock = AllocationTable.Allocate(blockCount); if (startBlock == -1) { return(ResultFs.AllocationTableFull.Log()); } var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size }; FileTable.AddFile(normalizedPath, ref fileEntry); return(Result.Success); }
private void CreateFileRecursive(ReadOnlySpan <byte> path, ref SaveFileInfo fileInfo) { var parser = new PathParser(path); var key = new SaveEntryKey(parser.GetCurrent(), 0); int parentIndex = CreateParentDirectoryRecursive(ref parser, ref key); int index = FileTable.GetIndexFromKey(ref key).Index; TableEntry <SaveFileInfo> fileEntry = default; // File already exists. Update file info. if (index >= 0) { FileTable.GetValue(index, out fileEntry); fileEntry.Value = fileInfo; FileTable.SetValue(index, ref fileEntry); return; } fileEntry.Value = fileInfo; index = FileTable.Add(ref key, ref fileEntry); LinkFileToParent(parentIndex, index); }