#include "bc/file/File.hpp" #include "bc/file/Filesystem.hpp" #include "bc/system/file/Stacked.hpp" #include #include namespace Blizzard { namespace File { // Functions void SetLastError(int32_t errorcode) { // TODO } void AddToLastErrorStack(int32_t errorcode, const char* msg, int32_t a3) { // TODO: use proper logging char empty[] = ""; if (!msg) { msg = empty; } fprintf(stderr, "[bc/file] %" PRIi32 ": '%s'\n", errorcode, msg); } // In BlizzardCore parlance, a file only exists if its path points to a regular file. (not a directory) // i.e. directories are not considered to be file objects. bool Exists(const char* path) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } FileInfo info = {}; System_File::Stacked::FileParms parms = {}; parms.filename = path; parms.info = &info; auto status = manager->Do(Filesystem::Call::Exists, &parms); return status; } bool Flush(StreamRecord* stream) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = stream; auto status = manager->Do(Filesystem::Call::Flush, &parms); return status; } // Alias of Exists. bool IsFile(const char* path) { return Exists(path); } // Calls Exists internally, only checking whether it has the directory attribute instead of normal attribute bool IsDirectory(const char* path) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } FileInfo info = {}; System_File::Stacked::FileParms parms = {}; parms.filename = path; parms.info = &info; auto status = manager->Do(Filesystem::Call::Exists, &parms); return info.attributes & BC_FILE_ATTRIBUTE_DIRECTORY; } // Delete a file. bool Delete(const char* path) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = path; auto status = manager->Do(Filesystem::Call::Delete, &parms); return status; } bool IsAbsolutePath(const char* path) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = path; return manager->Do(Filesystem::Call::IsAbsolutePath, &parms); } // Get file information about path, writing information to the passed info pointer. bool GetFileInfo(const char* path, FileInfo* info) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = path; parms.info = info; auto status = manager->Do(Filesystem::Call::GetFileInfo, &parms); return status; } // Get file information from a StreamRecord, writing information to the passed info pointer. bool GetFileInfo(StreamRecord* stream, FileInfo* info) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = stream; parms.info = info; return manager->Do(Filesystem::Call::GetFileInfo, &parms); } bool GetWorkingDirectory(char* path, size_t capacity) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.directory = path; parms.directorySize = capacity; return manager->Do(Filesystem::Call::GetWorkingDirectory, &parms); } bool SetWorkingDirectory(const char* path) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = path; return manager->Do(Filesystem::Call::SetWorkingDirectory, &parms); } // Get file information from a stream record, returning a file info pointer owned by StreamRecord // The FileInfo ptr returned is invalidated after a call to File::Close(stream) FileInfo* GetFileInfo(StreamRecord* stream) { static FileInfo s_noinfo = {}; auto manager = System_File::Stacked::Manager(); if (!manager) { return &s_noinfo; } System_File::Stacked::FileParms parms = {}; parms.stream = stream; parms.info = nullptr; auto status = manager->Do(Filesystem::Call::GetFileInfo, &parms); if (status) { return parms.info; } return &s_noinfo; } bool MakeAbsolutePath(const char* rel, char* result, int32_t capacity, bool unkflag) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = rel; parms.flag = unkflag; parms.directory = result; parms.directorySize = capacity; return manager->Do(Filesystem::Call::MakeAbsolutePath, &parms); } // Open a filename according to flags (see Defines.hpp) // if successful, will return true and referenced file object will be set bool Open(const char* filename, uint32_t flags, StreamRecord*& file) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = filename; parms.flag = flags; auto status = manager->Do(Filesystem::Call::Open, &parms); if (status) { file = parms.stream; } return status; } bool SetAttributes(const char* filename, uint32_t attributes) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = filename; parms.flag = static_cast(attributes); parms.mode = File::Mode::setperms; return manager->Do(Filesystem::Call::SetAttributes, &parms); } bool Close(StreamRecord* stream) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = stream; auto status = manager->Do(Filesystem::Call::Close, &parms); return status; } bool Copy(const char* source, const char* destination, bool overwrite) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = source; parms.destination = destination; return manager->Do(Filesystem::Call::Copy, &parms); } bool ProcessDirFast(const char* path, void* param, ProcessDirCallback callback, bool unkflag) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.filename = path; parms.param = param; parms.flag = unkflag; parms.callback = callback; return manager->Do(Filesystem::Call::ProcessDirFast, &parms); } bool Read(StreamRecord* file, void* buffer, size_t bytesToRead, size_t* bytesRead) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = file; parms.param = buffer; parms.size = bytesToRead; auto status = manager->Do(Filesystem::Call::Read, &parms); if (bytesRead) { *bytesRead = static_cast(parms.size); } return status; } bool Write(StreamRecord* file, void* buffer, size_t bytesToWrite, size_t* bytesWritten) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = file; parms.param = buffer; parms.size = bytesToWrite; auto status = manager->Do(Filesystem::Call::Write, &parms); if (bytesWritten) { *bytesWritten = static_cast(parms.size); } return status; } bool SetPos(StreamRecord* file, int64_t pos, int32_t whence) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = file; parms.position = pos; parms.whence = whence; return manager->Do(Filesystem::Call::SetPos, &parms); } bool GetPos(StreamRecord* file, int64_t& pos) { auto manager = System_File::Stacked::Manager(); if (!manager) { return false; } System_File::Stacked::FileParms parms = {}; parms.stream = file; parms.position = pos; auto status = manager->Do(Filesystem::Call::GetPos, &parms); if (status) { pos = parms.position; } return status; } } // namespace File } // namespace Blizzard