2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
11 #ifndef WC_ERR_INVALID_CHARS
12 # define WC_ERR_INVALID_CHARS 0x80
15 GIT_INLINE(DWORD
) get_wc_flags(void)
17 static char inited
= 0;
20 /* Invalid code point check supported on Vista+ only */
22 flags
= git_has_win32_version(6, 0, 0) ? WC_ERR_INVALID_CHARS
: 0;
29 GIT_INLINE(void) git__set_errno(void)
31 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
38 * Converts a UTF-8 string to wide characters.
40 * @param dest The buffer to receive the wide string.
41 * @param dest_size The size of the buffer, in characters.
42 * @param src The UTF-8 string to convert.
43 * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
45 int git__utf8_to_16(wchar_t *dest
, size_t dest_size
, const char *src
)
49 /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
50 * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
51 * length. MultiByteToWideChar never returns int's minvalue, so underflow is not possible */
52 if ((len
= MultiByteToWideChar(CP_UTF8
, MB_ERR_INVALID_CHARS
, src
, -1, dest
, (int)dest_size
) - 1) < 0)
59 * Converts a wide string to UTF-8.
61 * @param dest The buffer to receive the UTF-8 string.
62 * @param dest_size The size of the buffer, in bytes.
63 * @param src The wide string to convert.
64 * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
66 int git__utf16_to_8(char *dest
, size_t dest_size
, const wchar_t *src
)
70 /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
71 * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
72 * length. WideCharToMultiByte never returns int's minvalue, so underflow is not possible */
73 if ((len
= WideCharToMultiByte(CP_UTF8
, get_wc_flags(), src
, -1, dest
, (int)dest_size
, NULL
, NULL
) - 1) < 0)
80 * Converts a UTF-8 string to wide characters.
81 * Memory is allocated to hold the converted string.
82 * The caller is responsible for freeing the string with git__free.
84 * @param dest Receives a pointer to the wide string.
85 * @param src The UTF-8 string to convert.
86 * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
88 int git__utf8_to_16_alloc(wchar_t **dest
, const char *src
)
94 /* Length of -1 indicates NULL termination of the input string */
95 utf16_size
= MultiByteToWideChar(CP_UTF8
, MB_ERR_INVALID_CHARS
, src
, -1, NULL
, 0);
102 *dest
= git__malloc(utf16_size
* sizeof(wchar_t));
109 utf16_size
= MultiByteToWideChar(CP_UTF8
, MB_ERR_INVALID_CHARS
, src
, -1, *dest
, utf16_size
);
118 /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
119 * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
120 * so underflow is not possible */
121 return utf16_size
- 1;
125 * Converts a wide string to UTF-8.
126 * Memory is allocated to hold the converted string.
127 * The caller is responsible for freeing the string with git__free.
129 * @param dest Receives a pointer to the UTF-8 string.
130 * @param src The wide string to convert.
131 * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
133 int git__utf16_to_8_alloc(char **dest
, const wchar_t *src
)
136 DWORD dwFlags
= get_wc_flags();
140 /* Length of -1 indicates NULL termination of the input string */
141 utf8_size
= WideCharToMultiByte(CP_UTF8
, dwFlags
, src
, -1, NULL
, 0, NULL
, NULL
);
148 *dest
= git__malloc(utf8_size
);
155 utf8_size
= WideCharToMultiByte(CP_UTF8
, dwFlags
, src
, -1, *dest
, utf8_size
, NULL
, NULL
);
164 /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
165 * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
166 * so underflow is not possible */
167 return utf8_size
- 1;