HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
stringapiset.hpp
1// Copyright Take Vos 2024.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../macros.hpp"
8#include "win32_error_intf.hpp"
9#include <string>
10#include <expected>
11#include <vector>
12#include <Windows.h>
13#include <stringapiset.h>
14
15hi_export_module(hikogui.win32 : stringapiset);
16
17hi_export namespace hi { inline namespace v1 {
18
26[[nodiscard]] inline std::expected<std::string, win32_error> win32_WideCharToMultiByte(std::wstring_view s, unsigned int code_page = CP_UTF8, uint32_t flags = 0) noexcept
27{
28 if (s.empty()) {
29 // WideCharToMultiByte() does not handle empty strings, if it can not also convert the null-character.
30 return std::string{};
31 }
32
33 auto s_len = static_cast<int>(static_cast<unsigned int>(s.size()));
34 auto r_len = ::WideCharToMultiByte(code_page, flags, s.data(), s_len, nullptr, 0, nullptr, nullptr);
35 if (r_len == 0) {
36 return std::unexpected{win32_GetLastError()};
37 }
38
39 auto r = std::string(static_cast<size_t>(static_cast<std::make_signed_t<size_t>>(r_len)), '\0');
40 r.resize_and_overwrite(r_len, [&](char *p, size_t count) {
41 return ::WideCharToMultiByte(code_page, flags, s.data(), s_len, p, static_cast<int>(count), nullptr, nullptr);
42 });
43
44 if (r.empty()) {
45 return std::unexpected{win32_GetLastError()};
46 }
47
48 return r;
49}
50
58[[nodiscard]] inline std::expected<std::wstring, win32_error> win32_MultiByteToWideChar(std::string_view s, unsigned int code_page = CP_UTF8, uint32_t flags = 0) noexcept
59{
60 if (s.empty()) {
61 // MultiByteToWideChar() does not handle empty strings, if it can not also convert the null-character.
62 return std::wstring{};
63 }
64
65 auto s_len = static_cast<int>(static_cast<unsigned int>(s.size()));
66 auto r_len = ::MultiByteToWideChar(code_page, flags, s.data(), s_len, nullptr, 0);
67 if (r_len == 0) {
68 return std::unexpected{win32_GetLastError()};
69 }
70
71 auto r = std::wstring{};
72 r.resize_and_overwrite(r_len, [&](wchar_t *p, size_t count) {
73 return ::MultiByteToWideChar(code_page, flags, s.data(), s_len, p, static_cast<int>(count));
74 });
75
76 if (r.empty()) {
77 return std::unexpected{win32_GetLastError()};
78 }
79
80 return r;
81}
82
92[[nodiscard]] inline std::expected<std::vector<std::string>, win32_error> win32_MultiSZToStringVector(wchar_t const *first, wchar_t const *last) noexcept
93{
94 auto r = std::vector<std::string>{};
95
96 while (first != last) {
97 auto it_zero = std::find(first, last, wchar_t{0});
98 if (it_zero == last) {
99 // No termination found.
100 return std::unexpected{win32_error::invalid_data};
101 }
102
103 auto const ws = std::wstring_view{first, static_cast<std::size_t>(it_zero - first)};
104 if (ws.empty()) {
105 // The list is terminated with an empty string.
106 break;
107 }
108
109 if (auto s = win32_WideCharToMultiByte(ws)) {
110 r.push_back(*s);
111 } else {
112 return std::unexpected{s.error()};
113 }
114
115 // Continue after the zero terminator.
116 first = it_zero + 1;
117 }
118
119 return r;
120}
121
122}}
The HikoGUI namespace.
Definition array_generic.hpp:20
std::expected< std::string, win32_error > win32_WideCharToMultiByte(std::wstring_view s, unsigned int code_page=CP_UTF8, uint32_t flags=0) noexcept
Convert a win32-API compatible std::wstring to a multi-byte std::string.
Definition stringapiset.hpp:26
std::expected< std::vector< std::string >, win32_error > win32_MultiSZToStringVector(wchar_t const *first, wchar_t const *last) noexcept
Convert a win32 zero terminated list of zero terminated strings.
Definition stringapiset.hpp:92
std::expected< std::wstring, win32_error > win32_MultiByteToWideChar(std::string_view s, unsigned int code_page=CP_UTF8, uint32_t flags=0) noexcept
Convert a win32-API compatible std::wstring to a multi-byte std::string.
Definition stringapiset.hpp:58
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
T find(T... args)
T unexpected(T... args)