Browse Source

Make conversion from multi byte to wide string generic

sendfile
Martchus 4 years ago
parent
commit
8e3c40abb5
  1. 4
      CMakeLists.txt
  2. 39
      conversion/stringconversion.cpp
  3. 5
      conversion/stringconversion.h
  4. 14
      io/nativefilestream.cpp
  5. 2
      tests/testutils.cpp

4
CMakeLists.txt

@ -136,8 +136,8 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parser, IO and conversion utilities")
set(META_FEATURES_FOR_COMPILER_DETECTION_HEADER cxx_thread_local)
set(META_VERSION_MAJOR 4)
set(META_VERSION_MINOR 15)
set(META_VERSION_PATCH 1)
set(META_VERSION_MINOR 16)
set(META_VERSION_PATCH 0)
# find required 3rd party libraries
include(3rdParty)

39
conversion/stringconversion.cpp

@ -8,12 +8,17 @@
#include <cstdlib>
#include <iomanip>
#include <limits>
#include <memory>
#include <sstream>
#include <errno.h>
#include <iconv.h>
#ifdef PLATFORM_WINDOWS
#include <windows.h>
#endif
using namespace std;
/*!
@ -192,6 +197,40 @@ StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferS
return descriptor.convertString(inputBuffer, inputBufferSize);
}
#ifdef PLATFORM_WINDOWS
/*!
* \brief Converts the specified multi-byte string to a wide string using the WinAPI.
* \remarks
* - Only available under Windows.
* - If \a inputBufferSize is -1, \a inputBuffer is considered null-terminated.
*/
std::unique_ptr<wchar_t[]> convertMultiByteToWide(const char *inputBuffer, int inputBufferSize)
{
// calculate required size
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, inputBuffer, inputBufferSize, nullptr, 0);
std::unique_ptr<wchar_t[]> widePath;
if (requiredSize <= 0) {
return widePath;
}
// do the actual conversion
widePath = make_unique<wchar_t[]>(static_cast<size_t>(requiredSize));
requiredSize = MultiByteToWideChar(CP_UTF8, 0, inputBuffer, inputBufferSize, widePath.get(), requiredSize);
if (requiredSize <= 0) {
widePath.reset();
}
return widePath;
}
/*!
* \brief Converts the specified multi-byte string to a wide string using the WinAPI.
* \remarks Only available under Windows.
*/
std::unique_ptr<wchar_t[]> convertMultiByteToWide(const std::string &inputBuffer)
{
return convertMultiByteToWide(inputBuffer.data(), inputBuffer.size() < numeric_limits<int>::max() ? static_cast<int>(inputBuffer.size()) : -1);
}
#endif
/*!
* \brief Truncates all characters after the first occurrence of the
* specified \a terminationChar and the termination character as well.

5
conversion/stringconversion.h

@ -47,6 +47,11 @@ CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, st
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize);
#ifdef PLATFORM_WINDOWS
CPP_UTILITIES_EXPORT std::unique_ptr<wchar_t[]> convertMultiByteToWide(const char *inputBuffer, int inputBufferSize = -1);
CPP_UTILITIES_EXPORT std::unique_ptr<wchar_t[]> convertMultiByteToWide(const std::string &inputBuffer);
#endif
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
/*!

14
io/nativefilestream.cpp

@ -3,6 +3,10 @@
#ifdef CPP_UTILITIES_USE_NATIVE_FILE_BUFFER
#include "./catchiofailure.h"
#ifdef PLATFORM_WINDOWS
#include "../conversion/stringconversion.h"
#endif
// include header files for file buffer implementation
#if defined(CPP_UTILITIES_USE_GNU_CXX_STDIO_FILEBUF)
#include <ext/stdio_filebuf.h>
@ -262,7 +266,6 @@ std::unique_ptr<std::basic_streambuf<char>> NativeFileStream::makeFileBuffer(int
// compute native params
const NativeFileParams nativeParams(openMode);
#ifdef CPP_UTILITIES_USE_GNU_CXX_STDIO_FILEBUF
// open file handle to initialize stdio_filebuf
#ifdef PLATFORM_WINDOWS
@ -291,13 +294,8 @@ std::unique_ptr<std::basic_streambuf<char>> NativeFileStream::makeFileBuffer(int
#ifdef PLATFORM_WINDOWS
std::unique_ptr<wchar_t[]> NativeFileStream::makeWidePath(const std::string &path)
{
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, nullptr, 0);
if (requiredSize <= 0) {
::IoUtilities::throwIoFailure("Unable to calculate buffer size for conversion of path to UTF-16");
}
auto widePath = make_unique<wchar_t[]>(static_cast<size_t>(requiredSize));
requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.data(), -1, widePath.get(), requiredSize);
if (requiredSize <= 0) {
auto widePath = ::ConversionUtilities::convertMultiByteToWide(path);
if (!widePath) {
::IoUtilities::throwIoFailure("Unable to convert path to UTF-16");
}
return widePath;

2
tests/testutils.cpp

@ -6,8 +6,8 @@
#include "../io/ansiescapecodes.h"
#include "../io/catchiofailure.h"
#include "../io/misc.h"
#include "../io/path.h"
#include "../io/nativefilestream.h"
#include "../io/path.h"
#include <cerrno>
#include <cstdlib>

Loading…
Cancel
Save