mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:34:13 +08:00
mdbx++: refine/simplify wchar_t
support for pathnames.
This commit is contained in:
parent
c8b1392cbe
commit
0287a00ee3
224
src/mdbx.c++
224
src/mdbx.c++
@ -203,49 +203,35 @@ __cold bug::~bug() noexcept {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
|
||||
template <> struct path_to_pchar<std::wstring> {
|
||||
std::string str;
|
||||
path_to_pchar(const std::wstring &path) {
|
||||
if (!path.empty()) {
|
||||
const auto chars = mdbx_w2mb(nullptr, 0, path.data(), path.size());
|
||||
if (chars < 1)
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
str.append(chars, '\0');
|
||||
if (!mdbx_w2mb(const_cast<char *>(str.data()), chars, path.data(),
|
||||
path.size()))
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
}
|
||||
std::string w2mb(const std::wstring &in) {
|
||||
std::string out;
|
||||
if (!in.empty()) {
|
||||
const auto out_len = mdbx_w2mb(nullptr, 0, in.data(), in.size());
|
||||
if (out_len < 1)
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
out.append(out_len, '\0');
|
||||
if (out_len != mdbx_w2mb(const_cast<char *>(out.data()), out_len, in.data(),
|
||||
in.size()))
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
}
|
||||
operator const char *() const { return str.c_str(); }
|
||||
};
|
||||
return out;
|
||||
}
|
||||
|
||||
template <>
|
||||
MDBX_MAYBE_UNUSED std::wstring pchar_to_path<std::wstring>(const char *c_str) {
|
||||
std::wstring wstr;
|
||||
if (c_str && *c_str) {
|
||||
const auto c_str_len = strlen(c_str);
|
||||
const auto wchars = mdbx_mb2w(nullptr, 0, c_str, c_str_len);
|
||||
if (wchars < 1)
|
||||
std::wstring mb2w(const char *in) {
|
||||
std::wstring out;
|
||||
if (in && *in) {
|
||||
const auto in_len = strlen(in);
|
||||
const auto out_len = mdbx_mb2w(nullptr, 0, in, in_len);
|
||||
if (out_len < 1)
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
wstr.append(wchars, '\0');
|
||||
if (!mdbx_mb2w(const_cast<wchar_t *>(wstr.data()), wchars, c_str,
|
||||
c_str_len))
|
||||
out.append(out_len, '\0');
|
||||
if (out_len !=
|
||||
mdbx_mb2w(const_cast<wchar_t *>(out.data()), out_len, in, in_len))
|
||||
mdbx::error::throw_exception(GetLastError());
|
||||
}
|
||||
return wstr;
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif /* Windows */
|
||||
@ -1230,31 +1216,14 @@ 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,
|
||||
bool force_dynamic_size) {
|
||||
const path_to_pchar<MDBX_STD_FILESYSTEM_PATH> utf8(destination);
|
||||
env &env::copy(filehandle fd, bool compactify, bool force_dynamic_size) {
|
||||
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_copy2fd(handle_, fd,
|
||||
(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;
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
env &env::copy(const char *destination, bool compactify,
|
||||
bool force_dynamic_size) {
|
||||
@ -1271,38 +1240,32 @@ env &env::copy(const ::std::string &destination, bool compactify,
|
||||
return copy(destination.c_str(), compactify, force_dynamic_size);
|
||||
}
|
||||
|
||||
env &env::copy(filehandle fd, bool compactify, bool force_dynamic_size) {
|
||||
error::success_or_throw(
|
||||
::mdbx_env_copy2fd(handle_, fd,
|
||||
(compactify ? MDBX_CP_COMPACT : MDBX_CP_DEFAULTS) |
|
||||
(force_dynamic_size ? MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||
: MDBX_CP_DEFAULTS)));
|
||||
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 */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
||||
const path_to_pchar<::std::wstring> utf8(pathname);
|
||||
return error::boolean_or_throw(
|
||||
::mdbx_env_delete(utf8, MDBX_env_delete_mode_t(mode)));
|
||||
env &env::copy(const ::std::wstring &destination, bool compactify,
|
||||
bool force_dynamic_size) {
|
||||
return copy(w2mb(destination), compactify, force_dynamic_size);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
path env::get_path() const {
|
||||
const char *c_str;
|
||||
error::success_or_throw(::mdbx_env_get_path(handle_, &c_str));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
static_assert(sizeof(path::value_type) == sizeof(wchar_t), "Oops");
|
||||
return path(mb2w(c_str));
|
||||
#else
|
||||
static_assert(sizeof(path::value_type) == sizeof(char), "Oops");
|
||||
return path(c_str);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool env::remove(const char *pathname, const remove_mode mode) {
|
||||
return error::boolean_or_throw(
|
||||
::mdbx_env_delete(pathname, MDBX_env_delete_mode_t(mode)));
|
||||
@ -1312,6 +1275,19 @@ 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 */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
bool env::remove(const ::std::wstring &pathname, const remove_mode mode) {
|
||||
return remove(w2mb(pathname), mode);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static inline MDBX_env *create_env() {
|
||||
@ -1348,68 +1324,6 @@ __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,
|
||||
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));
|
||||
|
||||
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 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));
|
||||
|
||||
if (op.options.nested_write_transactions &&
|
||||
!get_options().nested_write_transactions)
|
||||
MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
__cold env_managed::env_managed(const char *pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(create_env()) {
|
||||
@ -1446,6 +1360,28 @@ __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 */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
__cold env_managed::env_managed(const ::std::wstring &pathname,
|
||||
const operate_parameters &op, bool accede)
|
||||
: env_managed(w2mb(pathname), 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(w2mb(pathname), cp, op, accede) {}
|
||||
#endif /* Windows */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
txn_managed txn::start_nested() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user