]>
Commit | Line | Data |
---|---|---|
7998ae5a | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
7998ae5a PB |
3 | * |
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. | |
6 | */ | |
7 | ||
11d51ca6 | 8 | #include "utf-conv.h" |
11d51ca6 | 9 | |
cceae9a2 ET |
10 | GIT_INLINE(void) git__set_errno(void) |
11 | { | |
12 | if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) | |
13 | errno = ENAMETOOLONG; | |
14 | else | |
15 | errno = EINVAL; | |
16 | } | |
17 | ||
c2c81615 PK |
18 | /** |
19 | * Converts a UTF-8 string to wide characters. | |
20 | * | |
21 | * @param dest The buffer to receive the wide string. | |
22 | * @param dest_size The size of the buffer, in characters. | |
23 | * @param src The UTF-8 string to convert. | |
24 | * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure | |
25 | */ | |
26 | int git__utf8_to_16(wchar_t *dest, size_t dest_size, const char *src) | |
27 | { | |
cceae9a2 ET |
28 | int len; |
29 | ||
c2c81615 PK |
30 | /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to |
31 | * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's | |
32 | * length. MultiByteToWideChar never returns int's minvalue, so underflow is not possible */ | |
cceae9a2 ET |
33 | if ((len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size) - 1) < 0) |
34 | git__set_errno(); | |
35 | ||
36 | return len; | |
c2c81615 PK |
37 | } |
38 | ||
39 | /** | |
40 | * Converts a wide string to UTF-8. | |
41 | * | |
42 | * @param dest The buffer to receive the UTF-8 string. | |
43 | * @param dest_size The size of the buffer, in bytes. | |
44 | * @param src The wide string to convert. | |
45 | * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure | |
46 | */ | |
aaefbdee | 47 | int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src) |
7998ae5a | 48 | { |
cceae9a2 ET |
49 | int len; |
50 | ||
c2c81615 PK |
51 | /* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to |
52 | * turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's | |
53 | * length. WideCharToMultiByte never returns int's minvalue, so underflow is not possible */ | |
494e61b8 | 54 | if ((len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size, NULL, NULL) - 1) < 0) |
cceae9a2 ET |
55 | git__set_errno(); |
56 | ||
57 | return len; | |
c2c81615 PK |
58 | } |
59 | ||
60 | /** | |
61 | * Converts a UTF-8 string to wide characters. | |
62 | * Memory is allocated to hold the converted string. | |
63 | * The caller is responsible for freeing the string with git__free. | |
64 | * | |
65 | * @param dest Receives a pointer to the wide string. | |
66 | * @param src The UTF-8 string to convert. | |
67 | * @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure | |
68 | */ | |
69 | int git__utf8_to_16_alloc(wchar_t **dest, const char *src) | |
70 | { | |
71 | int utf16_size; | |
72 | ||
73 | *dest = NULL; | |
74 | ||
75 | /* Length of -1 indicates NULL termination of the input string */ | |
76 | utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0); | |
77 | ||
cceae9a2 ET |
78 | if (!utf16_size) { |
79 | git__set_errno(); | |
c2c81615 | 80 | return -1; |
cceae9a2 | 81 | } |
c2c81615 | 82 | |
3603cb09 | 83 | if (!(*dest = git__mallocarray(utf16_size, sizeof(wchar_t)))) { |
cceae9a2 | 84 | errno = ENOMEM; |
c2c81615 | 85 | return -1; |
cceae9a2 | 86 | } |
c2c81615 PK |
87 | |
88 | utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, *dest, utf16_size); | |
89 | ||
90 | if (!utf16_size) { | |
cceae9a2 ET |
91 | git__set_errno(); |
92 | ||
c2c81615 PK |
93 | git__free(*dest); |
94 | *dest = NULL; | |
c2c81615 PK |
95 | } |
96 | ||
97 | /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL | |
98 | * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue, | |
99 | * so underflow is not possible */ | |
100 | return utf16_size - 1; | |
101 | } | |
102 | ||
103 | /** | |
104 | * Converts a wide string to UTF-8. | |
105 | * Memory is allocated to hold the converted string. | |
106 | * The caller is responsible for freeing the string with git__free. | |
107 | * | |
108 | * @param dest Receives a pointer to the UTF-8 string. | |
109 | * @param src The wide string to convert. | |
110 | * @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure | |
111 | */ | |
112 | int git__utf16_to_8_alloc(char **dest, const wchar_t *src) | |
113 | { | |
114 | int utf8_size; | |
c2c81615 PK |
115 | |
116 | *dest = NULL; | |
117 | ||
118 | /* Length of -1 indicates NULL termination of the input string */ | |
494e61b8 | 119 | utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL); |
c2c81615 | 120 | |
cceae9a2 ET |
121 | if (!utf8_size) { |
122 | git__set_errno(); | |
c2c81615 | 123 | return -1; |
cceae9a2 | 124 | } |
c2c81615 PK |
125 | |
126 | *dest = git__malloc(utf8_size); | |
127 | ||
cceae9a2 ET |
128 | if (!*dest) { |
129 | errno = ENOMEM; | |
c2c81615 | 130 | return -1; |
cceae9a2 | 131 | } |
c2c81615 | 132 | |
494e61b8 | 133 | utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, *dest, utf8_size, NULL, NULL); |
c2c81615 PK |
134 | |
135 | if (!utf8_size) { | |
cceae9a2 ET |
136 | git__set_errno(); |
137 | ||
c2c81615 PK |
138 | git__free(*dest); |
139 | *dest = NULL; | |
c2c81615 PK |
140 | } |
141 | ||
142 | /* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL | |
143 | * terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue, | |
144 | * so underflow is not possible */ | |
145 | return utf8_size - 1; | |
7998ae5a | 146 | } |