IFileSystem1.h#

Fully qualified name: carb/filesystem/detail/IFileSystem1.h

File members: carb/filesystem/detail/IFileSystem1.h

// SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#ifndef carb_filesystem_IFileSystem_latest
#    error Must include via ../IFileSystem.h
#endif

#if CARB_VERSION_ATLEAST(carb_filesystem_IFileSystem, 2, 0)
#    error Version too high to be included
#endif

#include "../../DocUtils.h"

#include <memory>

namespace carb::filesystem
{
inline namespace v1
{

struct IFileSystem;

struct File DOXYGEN_EMPTY_CLASS;

namespace v1_detail
{
struct FileReleaser
{
    IFileSystem* fs;
    void operator()(File* f);
};
} // namespace v1_detail

using ScopedFile = std::unique_ptr<File, v1_detail::FileReleaser>;

struct DirectoryItemInfo : public FileInfo
{
    const char* path;
};

struct IFileSystem
{
    // 1.3: Eliminated error/warning logging and made use of ErrorApi for error codes
    CARB_PLUGIN_INTERFACE_EX("carb::filesystem::IFileSystem",
                             carb_filesystem_IFileSystem_latest,
                             carb_filesystem_IFileSystem)

    const char*(CARB_ABI* getExecutablePath)();

    const char*(CARB_ABI* getExecutableDirectoryPath)();

    const char*(CARB_ABI* getAppDirectoryPath)();

    void(CARB_ABI* setAppDirectoryPath)(const char* path);

    const char*(CARB_ABI* getCurrentDirectoryPath)();

    bool(CARB_ABI* setCurrentDirectoryPath)(const char* path);

    bool(CARB_ABI* exists)(const char* path);

    bool(CARB_ABI* isWritable)(const char* path);

    bool(CARB_ABI* isDirectory)(const char* path);

    size_t(CARB_ABI* makeCanonicalPathEx)(const char* path, const char* base, char* buffer, size_t bufferSize);

    std::string makeCanonicalPath(const char* path,
                                  const char* base = nullptr,
                                  CanonicalFlags flags = fCanonicalFlagCheckExists);

    File*(CARB_ABI* openFileToRead)(const char* path);

    File*(CARB_ABI* openFileToWrite)(const char* path);

    File*(CARB_ABI* openFileToAppend)(const char* path);

    void(CARB_ABI* closeFile)(File* file);

    size_t(CARB_ABI* getFileSize)(File* file);

    time_t(CARB_ABI* getFileModTime)(File* file);

    time_t(CARB_ABI* getModTime)(const char* path);

    time_t(CARB_ABI* getFileCreateTime)(File* file);

    time_t(CARB_ABI* getCreateTime)(const char* path);

    size_t(CARB_ABI* readFileChunk)(File* file, void* chunk, size_t chunkSize);

    size_t(CARB_ABI* writeFileChunk)(File* file, const void* chunk, const size_t chunkSize);

    char*(CARB_ABI* readFileLine)(File* file, char* line, size_t maxLineSize);

    bool(CARB_ABI* writeFileLine)(File* file, const char* line);

    void(CARB_ABI* flushFile)(File* file);

    bool(CARB_ABI* removeFile)(const char* path);

    bool(CARB_ABI* makeTempDirectory)(char* pathBuffer, size_t bufferSize);

    bool(CARB_ABI* makeDirectory)(const char* path);

    bool(CARB_ABI* makeDirectories)(const char* path);

    bool(CARB_ABI* removeDirectory)(const char* path);

    bool(CARB_ABI* copy)(const char* from, const char* to);

    bool(CARB_ABI* move)(const char* from, const char* to);

    using OnDirectoryItemFn = WalkAction (*)(const DirectoryItemInfo* const info, void* userData);

    void(CARB_ABI* forEachDirectoryItem)(const char* path, OnDirectoryItemFn onDirectoryItem, void* userData);

    void(CARB_ABI* forEachDirectoryItemRecursive)(const char* path, OnDirectoryItemFn onDirectoryItem, void* userData);

    SubscriptionId(CARB_ABI* subscribeToChangeEvents)(const char* path, OnChangeEventFn onChangeEvent, void* userData);

    void(CARB_ABI* unsubscribeToChangeEvents)(SubscriptionId subscriptionId);

    int64_t(CARB_ABI* getFilePosition)(File* file);

    bool(CARB_ABI* setFilePosition)(File* file, int64_t offsetFromWhence, FileWhence whence);

    bool(CARB_ABI* truncateFileAtCurrentPosition)(File* file);

    bool setFilePositionBegin(File* file);

    bool setFilePositionEnd(File* file);

    File*(CARB_ABI* openFileToReadWrite)(const char* path);

    FileStatus(CARB_ABI* getFileStatus)(File* file);

    bool(CARB_ABI* getFileInfo)(const char* path, FileInfo* info);

    time_t(CARB_ABI* getCurrentTime)();

    bool(CARB_ABI* isReadable)(const char* path);

    size_t(CARB_ABI* makeCanonicalPathEx2)(
        const char* path, const char* base, CanonicalFlags flags, char* buffer, size_t bufferSize);
};

inline std::string IFileSystem::makeCanonicalPath(const char* path, const char* base, CanonicalFlags flags)
{
    std::string str(128, '\0');
    size_t bytes = this->makeCanonicalPathEx2(path, base, flags, &str[0], str.size());
    if (bytes == 0)
        return {};
    if (bytes > str.size())
    {
        str.resize(bytes);
        bytes = this->makeCanonicalPathEx2(path, base, flags, &str[0], str.size());
        CARB_ASSERT(bytes != 0 && str.size() >= bytes);
    }
    str.resize(bytes - 1); // Bytes includes the NUL terminator, so remove it here
    return str;
}

inline bool IFileSystem::setFilePositionBegin(File* file)
{
    return setFilePosition(file, 0, FileWhence::eBegin);
}

inline bool IFileSystem::setFilePositionEnd(File* file)
{
    return setFilePosition(file, 0, FileWhence::eEnd);
}

namespace v1_detail
{
inline void FileReleaser::operator()(File* f)
{
    fs->closeFile(f);
}
} // namespace v1_detail

} // namespace v1
} // namespace carb::filesystem