|
|
@@ -0,0 +1,107 @@ |
|
|
|
/* |
|
|
|
* DISTRHO Plugin Framework (DPF) |
|
|
|
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com> |
|
|
|
* |
|
|
|
* 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 |