コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }