forked from mutouyun/cpp-ipc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodecvt.h
More file actions
99 lines (90 loc) · 3.05 KB
/
codecvt.h
File metadata and controls
99 lines (90 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* \file libipc/platform/win/codecvt.h
* \author mutouyun (orz@orzz.org)
*/
#pragma once
#if defined(__MINGW32__)
#include <windows.h>
#else
#include <Windows.h>
#endif
#include "libipc/imp/codecvt.h"
#include "libipc/imp/detect_plat.h"
namespace ipc {
/**
* \see https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
* https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
*
* CP_ACP : The system default Windows ANSI code page.
* CP_MACCP : The current system Macintosh code page.
* CP_OEMCP : The current system OEM code page.
* CP_SYMBOL : Symbol code page (42).
* CP_THREAD_ACP: The Windows ANSI code page for the current thread.
* CP_UTF7 : UTF-7. Use this value only when forced by a 7-bit transport mechanism. Use of UTF-8 is preferred.
* CP_UTF8 : UTF-8.
*/
template <>
std::size_t cvt_cstr(char const *src, std::size_t slen, wchar_t *des, std::size_t dlen) noexcept {
if ((src == nullptr) || ((*src) == 0) || (slen == 0)) {
// source string is empty
return 0;
}
int cch_wc = (des == nullptr) ? 0 : (int)dlen;
int size_needed = ::MultiByteToWideChar(CP_ACP, 0, src, (int)slen, des, cch_wc);
if (size_needed <= 0) {
// failed: MultiByteToWideChar(CP_ACP).
return 0;
}
return size_needed;
}
template <>
std::size_t cvt_cstr(wchar_t const *src, std::size_t slen, char *des, std::size_t dlen) noexcept {
if ((src == nullptr) || ((*src) == 0) || (slen == 0)) {
// source string is empty
return 0;
}
int cb_mb = (des == nullptr) ? 0 : (int)dlen;
int size_needed = ::WideCharToMultiByte(CP_ACP, 0, src, (int)slen, des, cb_mb, NULL, NULL);
if (size_needed <= 0) {
// failed: WideCharToMultiByte(CP_ACP).
return 0;
}
return size_needed;
}
/**
* \brief Used for char8_t (since C++20) to wchar_t conversion.
*
* There is no ut to guarantee correctness (I'm a little lazy here),
* so if there are any bugs, please contact me in time.
*/
#if defined(LIBIMP_CPP_20)
template <>
std::size_t cvt_cstr(char8_t const *src, std::size_t slen, wchar_t *des, std::size_t dlen) noexcept {
if ((src == nullptr) || ((*src) == 0) || (slen == 0)) {
// source string is empty
return 0;
}
int cch_wc = (des == nullptr) ? 0 : (int)dlen;
int size_needed = ::MultiByteToWideChar(CP_UTF8, 0, (char *)src, (int)slen, des, cch_wc);
if (size_needed <= 0) {
// failed: MultiByteToWideChar(CP_UTF8).
return 0;
}
return size_needed;
}
template <>
std::size_t cvt_cstr(wchar_t const *src, std::size_t slen, char8_t *des, std::size_t dlen) noexcept {
if ((src == nullptr) || ((*src) == 0) || (slen == 0)) {
// source string is empty
return 0;
}
int cb_mb = (des == nullptr) ? 0 : (int)dlen;
int size_needed = ::WideCharToMultiByte(CP_UTF8, 0, src, (int)slen, (char *)des, cb_mb, NULL, NULL);
if (size_needed <= 0) {
// failed: WideCharToMultiByte(CP_UTF8).
return 0;
}
return size_needed;
}
#endif // defined(LIBIMP_CPP_20)
} // namespace ipc