diff --git a/include/bit7z/bitpropvariant.hpp b/include/bit7z/bitpropvariant.hpp index d0e3ce55..edd546ea 100644 --- a/include/bit7z/bitpropvariant.hpp +++ b/include/bit7z/bitpropvariant.hpp @@ -311,6 +311,12 @@ struct BitPropVariant final : public PROPVARIANT { */ BIT7Z_NODISCARD auto getNativeString() const -> native_string; + /** + * @return the raw string value of this variant + * (it throws an exception if the variant is not a string). + */ + BIT7Z_NODISCARD auto getRawString() const -> sevenzip_string; + /** * @return the 8-bit unsigned integer value of this variant * (it throws an exception if the variant is not an 8-bit unsigned integer). diff --git a/include/bit7z/bittypes.hpp b/include/bit7z/bittypes.hpp index 33fb67b7..102123b9 100644 --- a/include/bit7z/bittypes.hpp +++ b/include/bit7z/bittypes.hpp @@ -62,6 +62,12 @@ struct StringTraits< wchar_t > { }; /** @endcond */ +/** + * The string type used internally by 7-Zip. + * @Note 7-Zip always uses wide strings on all platforms. + */ +using sevenzip_string = std::wstring; + /** * Native string type of the system. * @note On Windows, it is an alias of `std::wstring`. diff --git a/src/bitpropvariant.cpp b/src/bitpropvariant.cpp index b08a05f7..cf3bb8b8 100644 --- a/src/bitpropvariant.cpp +++ b/src/bitpropvariant.cpp @@ -251,25 +251,32 @@ auto BitPropVariant::getBool() const -> bool { } auto BitPropVariant::getString() const -> tstring { +#if defined( BIT7Z_USE_NATIVE_STRING ) && defined( _WIN32 ) + return getRawString(); +#else if ( vt != VT_BSTR ) { throw BitException( "BitPropVariant is not a string", make_error_code( BitError::RequestedWrongVariantType ) ); } // Note: a nullptr BSTR is semantically equivalent to an empty string. - return bstrVal == nullptr ? tstring{} : BSTR_TO_TSTRING( bstrVal ); + return bstrVal == nullptr ? tstring{} : bit7z::narrow( bstrVal, SysStringLen( bstrVal ) ); +#endif } auto BitPropVariant::getNativeString() const -> native_string { #ifdef _WIN32 - if ( vt != VT_BSTR ) { - throw BitException( "BitPropVariant is not a string", make_error_code( BitError::RequestedWrongVariantType ) ); - } - // Note: a nullptr BSTR is semantically equivalent to an empty string. - return bstrVal == nullptr ? native_string{} : native_string{ bstrVal, ::SysStringLen( bstrVal ) }; + return getRawString(); #else return getString(); #endif } +auto BitPropVariant::getRawString() const -> sevenzip_string { + if ( vt != VT_BSTR ) { + throw BitException( "BitPropVariant is not a string", make_error_code( BitError::RequestedWrongVariantType ) ); + } + return bstrVal == nullptr ? sevenzip_string{} : sevenzip_string{ bstrVal, ::SysStringLen( bstrVal ) }; +} + auto BitPropVariant::getUInt8() const -> uint8_t { switch ( vt ) { case VT_UI1: