mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-11 21:03:05 +08:00
+ chg: INI file read/write using synchronous file locking (shared read / exclusive write)
This commit is contained in:
parent
44c946cccd
commit
e8db035a26
@ -1 +1 @@
|
||||
2
|
||||
1
|
||||
|
||||
@ -1 +1 @@
|
||||
216
|
||||
217
|
||||
|
||||
@ -294,6 +294,7 @@ enum class SI_Error : int {
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define SI_HAS_WIDE_FILE
|
||||
# define SI_USE_LOCKING_WIDE_FILE
|
||||
# define SI_WCHAR_T wchar_t
|
||||
#elif defined(SI_CONVERT_ICU)
|
||||
# define SI_HAS_WIDE_FILE
|
||||
@ -412,10 +413,29 @@ public:
|
||||
fputs(a_pBuf, m_file);
|
||||
}
|
||||
private:
|
||||
FileWriter() = delete;
|
||||
FileWriter(const FileWriter &); // disable
|
||||
FileWriter & operator=(const FileWriter &); // disable
|
||||
};
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
class FileHndlWriter : public OutputWriter {
|
||||
HANDLE m_file;
|
||||
public:
|
||||
FileHndlWriter(HANDLE a_file) : m_file(a_file) {};
|
||||
~FileHndlWriter() { FlushFileBuffers(m_file); }
|
||||
void Write(const char* a_pBuf) override {
|
||||
DWORD nBytesWritten = 0UL;
|
||||
DWORD const nBytesToWrite = static_cast<DWORD>(strlen(a_pBuf));
|
||||
WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, NULL);
|
||||
}
|
||||
private:
|
||||
FileHndlWriter() = delete;
|
||||
FileHndlWriter(const FileHndlWriter&) = delete; // disable
|
||||
FileHndlWriter& operator=(const FileHndlWriter&) = delete; // disable
|
||||
};
|
||||
#endif
|
||||
|
||||
/** OutputWriter class to write the INI data to a string */
|
||||
class StringWriter : public OutputWriter {
|
||||
std::string & m_string;
|
||||
@ -610,9 +630,11 @@ public:
|
||||
|
||||
@return SI_Error See error definitions
|
||||
*/
|
||||
SI_Error LoadFile(
|
||||
FILE * a_fpFile
|
||||
);
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize);
|
||||
#else
|
||||
SI_Error LoadFile( FILE * a_fpFile );
|
||||
#endif
|
||||
|
||||
#ifdef SI_SUPPORT_IOSTREAMS
|
||||
/** Load INI file data from an istream.
|
||||
@ -698,11 +720,17 @@ public:
|
||||
|
||||
@return SI_Error See error definitions
|
||||
*/
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
SI_Error SaveFile(
|
||||
HANDLE a_hFile,
|
||||
bool a_bAddSignature = false
|
||||
) const;
|
||||
#else
|
||||
SI_Error SaveFile(
|
||||
FILE * a_pFile,
|
||||
bool a_bAddSignature = false
|
||||
) const;
|
||||
|
||||
#endif
|
||||
/** Save the INI data. The data will be written to the output device
|
||||
in a format appropriate to the current data, selected by:
|
||||
|
||||
@ -1392,6 +1420,46 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
}
|
||||
|
||||
#ifdef SI_HAS_WIDE_FILE
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
const SI_WCHAR_T* a_pwszFile
|
||||
)
|
||||
{
|
||||
HANDLE hFile = CreateFile(a_pwszFile,
|
||||
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
DWORD dwFileSizeHigh = 0UL;
|
||||
DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
|
||||
if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) {
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
SI_Error rc = SI_Error::SI_FILE;
|
||||
|
||||
DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK
|
||||
OVERLAPPED OvrLpd = { 0 };
|
||||
|
||||
if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) {
|
||||
|
||||
rc = LoadFile(hFile, dwFileSize);
|
||||
|
||||
UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
@ -1415,8 +1483,43 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
return LoadFile(szFile);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
#endif // SI_USE_LOCKING_WIDE_FILE
|
||||
|
||||
#endif // SI_HAS_WIDE_FILE
|
||||
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
HANDLE a_hFile, DWORD dwFileSize
|
||||
)
|
||||
{
|
||||
// allocate and ensure NULL terminated
|
||||
auto* pData = new(std::nothrow) char[dwFileSize + 1];
|
||||
if (!pData) {
|
||||
return SI_Error::SI_NOMEM;
|
||||
}
|
||||
pData[dwFileSize] = '\0';
|
||||
|
||||
// load the raw file data
|
||||
DWORD nBytesRead = 0UL;
|
||||
BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL);
|
||||
if ((result == FALSE) || (nBytesRead != dwFileSize)) {
|
||||
delete[] pData;
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
// convert the raw data to unicode
|
||||
SI_Error const rc = LoadData(pData, (size_t)nBytesRead);
|
||||
delete[] pData;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
@ -1457,6 +1560,8 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadData(
|
||||
@ -2515,11 +2620,49 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
#endif // __STDC_WANT_SECURE_LIB__
|
||||
if (!fp) return SI_FILE;
|
||||
SI_Error rc = SaveFile(fp, a_bAddSignature);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SI_HAS_WIDE_FILE
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::SaveFile(
|
||||
const SI_WCHAR_T* a_pwszFile,
|
||||
bool a_bAddSignature
|
||||
) const
|
||||
{
|
||||
HANDLE hFile = CreateFile(a_pwszFile,
|
||||
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK; // LOCK SHARED READ/WRITE(!) ~ LOCKFILE_FAIL_IMMEDIATELY
|
||||
OVERLAPPED OvrLpd = { 0 };
|
||||
SI_Error rc = SI_Error::SI_FILE;
|
||||
|
||||
if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) {
|
||||
|
||||
rc = SaveFile(hFile, a_bAddSignature);
|
||||
|
||||
FlushFileBuffers(hFile);
|
||||
|
||||
UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd);
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
@ -2536,6 +2679,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
#endif // __STDC_WANT_SECURE_LIB__
|
||||
if (!fp) return SI_Error::SI_FILE;
|
||||
SI_Error rc = SaveFile(fp, a_bAddSignature);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
return rc;
|
||||
#else // !_WIN32 (therefore SI_CONVERT_ICU)
|
||||
@ -2544,8 +2688,24 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
return SaveFile(szFile, a_bAddSignature);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
#endif // SI_USE_LOCKING_WIDE_FILE
|
||||
|
||||
#endif // SI_HAS_WIDE_FILE
|
||||
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::SaveFile(
|
||||
HANDLE a_hFile,
|
||||
bool a_bAddSignature
|
||||
) const
|
||||
{
|
||||
FileHndlWriter writer(a_hFile);
|
||||
return Save(writer, a_bAddSignature);
|
||||
}
|
||||
#else
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
@ -2556,6 +2716,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
FileWriter writer(a_pFile);
|
||||
return Save(writer, a_bAddSignature);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
|
||||
@ -1 +1 @@
|
||||
"RC1"
|
||||
BETA
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
<assemblyIdentity
|
||||
name="Notepad3"
|
||||
processorArchitecture="*"
|
||||
version="5.20.216.2"
|
||||
version="5.20.217.1"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Notepad3 RC1</description>
|
||||
<description>Notepad3 BETA</description>
|
||||
</assembly>
|
||||
|
||||
@ -294,7 +294,7 @@ enum class SI_Error : int {
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define SI_HAS_WIDE_FILE
|
||||
//# define SI_USE_LOCKING_WIDE_FILE
|
||||
# define SI_USE_LOCKING_WIDE_FILE
|
||||
# define SI_WCHAR_T wchar_t
|
||||
#elif defined(SI_CONVERT_ICU)
|
||||
# define SI_HAS_WIDE_FILE
|
||||
@ -419,25 +419,20 @@ public:
|
||||
};
|
||||
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
class FileWriterLocking : public OutputWriter {
|
||||
class FileHndlWriter : public OutputWriter {
|
||||
HANDLE m_file;
|
||||
LPOVERLAPPED m_pOvrLpd;
|
||||
public:
|
||||
FileWriterLocking(HANDLE a_file, LPOVERLAPPED a_pOvrLpd)
|
||||
: m_file(a_file)
|
||||
, m_pOvrLpd(a_pOvrLpd) { }
|
||||
~FileWriterLocking() {
|
||||
FlushFileBuffers(m_file);
|
||||
}
|
||||
FileHndlWriter(HANDLE a_file) : m_file(a_file) {};
|
||||
~FileHndlWriter() { FlushFileBuffers(m_file); }
|
||||
void Write(const char* a_pBuf) override {
|
||||
DWORD nBytesWritten = 0UL;
|
||||
DWORD const nBytesToWrite = static_cast<DWORD>(strlen(a_pBuf));
|
||||
WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, m_pOvrLpd);
|
||||
WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, NULL);
|
||||
}
|
||||
private:
|
||||
FileWriterLocking() = delete;
|
||||
FileWriterLocking(const FileWriterLocking&) = delete; // disable
|
||||
FileWriterLocking& operator=(const FileWriterLocking&) = delete; // disable
|
||||
FileHndlWriter() = delete;
|
||||
FileHndlWriter(const FileHndlWriter&) = delete; // disable
|
||||
FileHndlWriter& operator=(const FileHndlWriter&) = delete; // disable
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -636,7 +631,7 @@ public:
|
||||
@return SI_Error See error definitions
|
||||
*/
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize, LPOVERLAPPED pOvrLpd);
|
||||
SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize);
|
||||
#else
|
||||
SI_Error LoadFile( FILE * a_fpFile );
|
||||
#endif
|
||||
@ -728,7 +723,6 @@ public:
|
||||
#ifdef SI_USE_LOCKING_WIDE_FILE
|
||||
SI_Error SaveFile(
|
||||
HANDLE a_hFile,
|
||||
LPOVERLAPPED a_pOvrLpd,
|
||||
bool a_bAddSignature = false
|
||||
) const;
|
||||
#else
|
||||
@ -1448,16 +1442,18 @@ CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) {
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
OVERLAPPED OvrLpd; ZeroMemory(&OvrLpd, sizeof(OVERLAPPED));
|
||||
|
||||
SI_Error rc = SI_Error::SI_FILE;
|
||||
|
||||
DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK
|
||||
LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
OVERLAPPED OvrLpd = { 0 };
|
||||
|
||||
SI_Error const rc = LoadFile(hFile, dwFileSize, &OvrLpd);
|
||||
if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) {
|
||||
|
||||
UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
rc = LoadFile(hFile, dwFileSize);
|
||||
|
||||
UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return rc;
|
||||
}
|
||||
@ -1498,7 +1494,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
HANDLE a_hFile, DWORD dwFileSize, LPOVERLAPPED pOvrLpd
|
||||
HANDLE a_hFile, DWORD dwFileSize
|
||||
)
|
||||
{
|
||||
// allocate and ensure NULL terminated
|
||||
@ -1510,7 +1506,7 @@ CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
|
||||
// load the raw file data
|
||||
DWORD nBytesRead = 0UL;
|
||||
BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, pOvrLpd);
|
||||
BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL);
|
||||
if ((result == FALSE) || (nBytesRead != dwFileSize)) {
|
||||
delete[] pData;
|
||||
return SI_Error::SI_FILE;
|
||||
@ -2642,27 +2638,25 @@ CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::SaveFile(
|
||||
{
|
||||
HANDLE hFile = CreateFile(a_pwszFile,
|
||||
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
return SI_Error::SI_FILE;
|
||||
}
|
||||
|
||||
DWORD dwFileSizeHigh = 0UL;
|
||||
DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
|
||||
if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) {
|
||||
return SI_Error::SI_FILE;
|
||||
DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK; // LOCK SHARED READ/WRITE(!) ~ LOCKFILE_FAIL_IMMEDIATELY
|
||||
OVERLAPPED OvrLpd = { 0 };
|
||||
SI_Error rc = SI_Error::SI_FILE;
|
||||
|
||||
if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) {
|
||||
|
||||
rc = SaveFile(hFile, a_bAddSignature);
|
||||
|
||||
FlushFileBuffers(hFile);
|
||||
|
||||
UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd);
|
||||
}
|
||||
|
||||
OVERLAPPED OvrLpd; ZeroMemory(&OvrLpd, sizeof(OVERLAPPED));
|
||||
|
||||
DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK
|
||||
LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
|
||||
SI_Error const rc = SaveFile(hFile, &OvrLpd, a_bAddSignature);
|
||||
|
||||
UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
|
||||
|
||||
CloseHandle(hFile);
|
||||
return rc;
|
||||
}
|
||||
@ -2705,11 +2699,10 @@ template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
SI_Error
|
||||
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::SaveFile(
|
||||
HANDLE a_hFile,
|
||||
LPOVERLAPPED a_pOvrLpd,
|
||||
bool a_bAddSignature
|
||||
) const
|
||||
{
|
||||
FileWriterLocking writer(a_hFile, a_pOvrLpd);
|
||||
FileHndlWriter writer(a_hFile);
|
||||
return Save(writer, a_bAddSignature);
|
||||
}
|
||||
#else
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
#define SAPPNAME "Notepad3"
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 20
|
||||
#define VERSION_REV 216
|
||||
#define VERSION_BUILD 2
|
||||
#define VERSION_REV 217
|
||||
#define VERSION_BUILD 1
|
||||
#define SCINTILLA_VER 430
|
||||
#define ONIGURUMA_REGEX_VER 6.9.4
|
||||
#define UCHARDET_VER 2018.09.27
|
||||
#define TINYEXPR_VER 2018.05.11
|
||||
#define UTHASH_VER 2.1.0
|
||||
#define VERSION_PATCH RC1
|
||||
#define VERSION_PATCH BETA
|
||||
#define VERSION_COMMIT_ID nebukadn
|
||||
|
||||
Loading…
Reference in New Issue
Block a user