-
-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add some handy filesystem related code for plugins
Signed-off-by: falkTX <[email protected]>
- Loading branch information
Showing
1 changed file
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* DISTRHO Plugin Framework (DPF) | ||
* Copyright (C) 2012-2025 Filipe Coelho <[email protected]> | ||
* | ||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | ||
* or without fee is hereby granted, provided that the above copyright notice and this | ||
* permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | ||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | ||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | ||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
#ifndef DISTRHO_FILESYSTEM_UTILS_HPP_INCLUDED | ||
#define DISTRHO_FILESYSTEM_UTILS_HPP_INCLUDED | ||
|
||
#include "String.hpp" | ||
|
||
#include <cstdio> | ||
|
||
#ifdef DISTRHO_OS_WINDOWS | ||
# include <stringapiset.h> | ||
#endif | ||
|
||
START_NAMESPACE_DISTRHO | ||
|
||
// -------------------------------------------------------------------------------------------------------------------- | ||
// filesystem related calls | ||
|
||
/* | ||
* Wrapper around `fopen` call, needed on Windows because its C standard functions use ASCII instead of UTF-8. | ||
*/ | ||
static inline | ||
FILE* d_fopen(const char* const pathname, const char* const mode) | ||
{ | ||
#ifdef DISTRHO_OS_WINDOWS | ||
WCHAR lpathname[MAX_PATH]; | ||
WCHAR lmode[4]; | ||
if (MultiByteToWideChar(CP_UTF8, 0, pathname, -1, lpathname, ARRAY_SIZE(lpathname)) != 0 && | ||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, lmode, ARRAY_SIZE(lmode)) != 0) | ||
return _wfopen(lpathname, lmode); | ||
#endif | ||
|
||
return fopen(pathname, mode); | ||
} | ||
|
||
// -------------------------------------------------------------------------------------------------------------------- | ||
// filesystem related classes | ||
|
||
/** | ||
Handy class to help write files in a safe way, which does: | ||
- open pathname + ".tmp" instead of opening a file directly (so partial writes are safe) | ||
- on close, flush data to disk and rename file to remove ".tmp" | ||
To use it, create a local variable (on the stack) and call ok() or manually check @a fd variable. | ||
@code | ||
if (const SafeFileWriter file("/path/to/file.txt"); file.ok()) | ||
file.write("Success!"); | ||
@endcode | ||
*/ | ||
struct SafeFileWriter | ||
{ | ||
/** Parameters from the run function, adjusted for event sync */ | ||
String filename; | ||
FILE* const fd; | ||
|
||
/** | ||
Constructor, opening @a pathname + ".tmp" for writing. | ||
*/ | ||
SafeFileWriter(const char* const pathname, const char* const mode = "w") | ||
: filename(pathname), | ||
fd(d_fopen(filename + ".tmp", mode)) {} | ||
|
||
/** | ||
Destructor, will flush file data contents, close and rename file. | ||
*/ | ||
~SafeFileWriter() | ||
{ | ||
if (fd == nullptr) | ||
return; | ||
|
||
std::fflush(fd); | ||
std::fclose(fd); | ||
std::rename(filename + ".tmp", filename); | ||
} | ||
|
||
/** Check if the file was opened successfully. */ | ||
inline bool ok() const noexcept | ||
{ | ||
return fd != nullptr; | ||
} | ||
|
||
/** Wrapper around `fwrite`, purely for convenience. */ | ||
inline size_t write(const void* const ptr, const size_t size, const size_t nmemb = 1) const | ||
{ | ||
return std::fwrite(ptr, size, nmemb, fd); | ||
} | ||
}; | ||
|
||
// -------------------------------------------------------------------------------------------------------------------- | ||
|
||
END_NAMESPACE_DISTRHO | ||
|
||
#endif // DISTRHO_FILESYSTEM_UTILS_HPP_INCLUDED |