mirror of
https://github.com/isar/libmdbx.git
synced 2025-08-25 21:54:28 +08:00
mdbx: native wchar_t
pathname for Windows.
This commit is contained in:
188
src/mdbx.c++
188
src/mdbx.c++
@@ -201,64 +201,6 @@ __cold bug::~bug() noexcept {}
|
||||
|
||||
#endif /* Unused*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename PATH> struct path_to_pchar {
|
||||
const std::string str;
|
||||
path_to_pchar(const PATH &path) : str(path.generic_string()) {}
|
||||
operator const char *() const { return str.c_str(); }
|
||||
};
|
||||
|
||||
template <typename PATH>
|
||||
MDBX_MAYBE_UNUSED PATH pchar_to_path(const char *c_str) {
|
||||
return PATH(c_str);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#ifndef WC_ERR_INVALID_CHARS
|
||||
static const DWORD WC_ERR_INVALID_CHARS =
|
||||
(6 /* Windows Vista */ <= /* MajorVersion */ LOBYTE(LOWORD(GetVersion())))
|
||||
? 0x00000080
|
||||
: 0;
|
||||
#endif /* WC_ERR_INVALID_CHARS */
|
||||
|
||||
template <> struct path_to_pchar<std::wstring> {
|
||||
std::string str;
|
||||
path_to_pchar(const std::wstring &path) {
|
||||
if (!path.empty()) {
|
||||
const int chars =
|
||||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path.data(),
|
||||
int(path.size()), nullptr, 0, nullptr, nullptr);
|
||||
if (chars == 0)
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
str.append(chars, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path.data(),
|
||||
int(path.size()), const_cast<char *>(str.data()),
|
||||
chars, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
operator const char *() const { return str.c_str(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
MDBX_MAYBE_UNUSED std::wstring pchar_to_path<std::wstring>(const char *c_str) {
|
||||
std::wstring wstr;
|
||||
if (c_str && *c_str) {
|
||||
const int chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, c_str,
|
||||
int(strlen(c_str)), nullptr, 0);
|
||||
if (chars == 0)
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
wstr.append(chars, '\0');
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, c_str,
|
||||
int(strlen(c_str)), const_cast<wchar_t *>(wstr.data()),
|
||||
chars);
|
||||
}
|
||||
return wstr;
|
||||
}
|
||||
|
||||
#endif /* Windows */
|
||||
|
||||
} // namespace
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1239,29 +1181,20 @@ bool env::is_pristine() const {
|
||||
|
||||
bool env::is_empty() const { return get_stat().ms_leaf_pages == 0; }
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
env &env::copy(const MDBX_STD_FILESYSTEM_PATH &destination, bool compactify,
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
env &env::copy(const wchar_t *destination, bool compactify,
|
||||
bool force_dynamic_size) {
|
||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(destination);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_copy(handle_, utf8,
|
||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||
: MDBX_CP_DEFAULTS)));
|
||||
::mdbx_env_copyW(handle_, destination,
|
||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||
: MDBX_CP_DEFAULTS)));
|
||||
return *this;
|
||||
}
|
||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
env &env::copy(const ::std::wstring &destination, bool compactify,
|
||||
bool force_dynamic_size) {
|
||||
const path_to_pchar<::std::wstring> utf8(destination);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_copy(handle_, utf8,
|
||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||
: MDBX_CP_DEFAULTS)));
|
||||
return *this;
|
||||
return copy(destination.c_str(), compactify, force_dynamic_size);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
@@ -1289,26 +1222,33 @@ env &env::copy(filehandle fd, bool compactify, bool force_dynamic_size) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
path env::get_path() const {
|
||||
const char *c_str;
|
||||
error::success_or_throw(::mdbx_env_get_path(handle_, &c_str));
|
||||
return pchar_to_path<path>(c_str);
|
||||
}
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
bool env::remove(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const remove_mode mode) {
|
||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
||||
return error::boolean_or_throw(
|
||||
::mdbx_env_delete(utf8, MDBX_env_delete_mode_t(mode)));
|
||||
env &env::copy(const MDBX_STD_FILESYSTEM_PATH &destination, bool compactify,
|
||||
bool force_dynamic_size) {
|
||||
return copy(destination.native(), compactify, force_dynamic_size);
|
||||
}
|
||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||
|
||||
path env::get_path() const {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
||||
const wchar_t *c_wstr;
|
||||
error::success_or_throw(::mdbx_env_get_pathW(handle_, &c_wstr));
|
||||
return path(c_wstr);
|
||||
#else
|
||||
const char *c_str;
|
||||
error::success_or_throw(::mdbx_env_get_path(handle_, &c_str));
|
||||
return path(c_str);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
bool env::remove(const wchar_t *pathname, const remove_mode mode) {
|
||||
return error::boolean_or_throw(
|
||||
::mdbx_env_delete(utf8, MDBX_env_delete_mode_t(mode)));
|
||||
::mdbx_env_deleteW(pathname, MDBX_env_delete_mode_t(mode)));
|
||||
}
|
||||
|
||||
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
||||
return remove(pathname.c_str(), mode);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
@@ -1321,6 +1261,13 @@ bool env::remove(const ::std::string &pathname, const remove_mode mode) {
|
||||
return remove(pathname.c_str(), mode);
|
||||
}
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
bool env::remove(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const remove_mode mode) {
|
||||
return remove(pathname.native(), mode);
|
||||
}
|
||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static inline MDBX_env *create_env() {
|
||||
@@ -1357,66 +1304,42 @@ __cold void env_managed::setup(unsigned max_maps, unsigned max_readers) {
|
||||
error::success_or_throw(::mdbx_env_set_maxdbs(handle_, max_maps));
|
||||
}
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(create_env()) {
|
||||
setup(op.max_maps, op.max_readers);
|
||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede), 0));
|
||||
|
||||
if (op.options.nested_write_transactions &&
|
||||
!get_options().nested_write_transactions)
|
||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const env_managed::create_parameters &cp,
|
||||
const env::operate_parameters &op, bool accede)
|
||||
: env_managed(create_env()) {
|
||||
setup(op.max_maps, op.max_readers);
|
||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(pathname);
|
||||
set_geometry(cp.geometry);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede, cp.use_subdirectory),
|
||||
cp.file_mode_bits));
|
||||
|
||||
if (op.options.nested_write_transactions &&
|
||||
!get_options().nested_write_transactions)
|
||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||
__cold env_managed::env_managed(const wchar_t *pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(create_env()) {
|
||||
setup(op.max_maps, op.max_readers);
|
||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede), 0));
|
||||
::mdbx_env_openW(handle_, pathname, op.make_flags(accede), 0));
|
||||
|
||||
if (op.options.nested_write_transactions &&
|
||||
!get_options().nested_write_transactions)
|
||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||
__cold env_managed::env_managed(const wchar_t *pathname,
|
||||
const env_managed::create_parameters &cp,
|
||||
const env::operate_parameters &op, bool accede)
|
||||
: env_managed(create_env()) {
|
||||
setup(op.max_maps, op.max_readers);
|
||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
||||
set_geometry(cp.geometry);
|
||||
error::success_or_throw(
|
||||
::mdbx_env_open(handle_, utf8, op.make_flags(accede, cp.use_subdirectory),
|
||||
cp.file_mode_bits));
|
||||
error::success_or_throw(::mdbx_env_openW(
|
||||
handle_, pathname, op.make_flags(accede, cp.use_subdirectory),
|
||||
cp.file_mode_bits));
|
||||
|
||||
if (op.options.nested_write_transactions &&
|
||||
!get_options().nested_write_transactions)
|
||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(pathname.c_str(), op, accede) {}
|
||||
|
||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||
const env_managed::create_parameters &cp,
|
||||
const env::operate_parameters &op, bool accede)
|
||||
: env_managed(pathname.c_str(), cp, op, accede) {}
|
||||
#endif /* Windows */
|
||||
|
||||
__cold env_managed::env_managed(const char *pathname,
|
||||
@@ -1455,6 +1378,17 @@ __cold env_managed::env_managed(const ::std::string &pathname,
|
||||
const env::operate_parameters &op, bool accede)
|
||||
: env_managed(pathname.c_str(), cp, op, accede) {}
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(pathname.native(), op, accede) {}
|
||||
|
||||
__cold env_managed::env_managed(const MDBX_STD_FILESYSTEM_PATH &pathname,
|
||||
const env_managed::create_parameters &cp,
|
||||
const env::operate_parameters &op, bool accede)
|
||||
: env_managed(pathname.native(), cp, op, accede) {}
|
||||
#endif /* MDBX_STD_FILESYSTEM_PATH */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
txn_managed txn::start_nested() {
|
||||
|
Reference in New Issue
Block a user