This commit is contained in:
gingerBill
2020-06-15 11:54:28 +01:00
3 changed files with 55 additions and 11 deletions
+1 -2
View File
@@ -282,8 +282,7 @@ get_current_directory :: proc() -> string {
intrinsics.atomic_store(&cwd_gate, false);
dir_utf8 := win32.utf16_to_utf8(dir_buf_wstr);
return dir_utf8[:len(dir_utf8)-1]; // NOTE(tetra): Remove the NUL.
return win32.utf16_to_utf8(dir_buf_wstr);
}
set_current_directory :: proc(path: string) -> (err: Errno) {
+10 -9
View File
@@ -813,9 +813,11 @@ wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator)
return "";
}
// NOTE: If N == -1 the call to wide_char_to_multi_byte assumes the wide string is null terminated,
// and will scan it for the first null terminated character. The resulting string is also null terminated.
// If N != -1 it assumes the wide string is not null terminated and the resulting string is not null terminated.
// If N == -1 the call to wide_char_to_multi_byte assume the wide string is null terminated
// and will scan it to find the first null terminated character. The resulting string will
// also null terminated.
// If N != -1 it assumes the wide string is not null terminated and the resulting string
// will not be null terminated, we therefore have to force it to be null terminated manually.
text := make([]byte, n+1 if N != -1 else n, allocator);
if n1 := wide_char_to_multi_byte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), cstring(&text[0]), n, nil, nil); n1 == 0 {
@@ -823,14 +825,13 @@ wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator)
return "";
}
if N > 0 {
// NOTE: The input string is not expected to be null terminated, so we strip excess zeros at the end.
text[n] = 0;
for n >= 1 && text[n-1] == 0 {
n -= 1;
for i in 0..<n {
if text[i] == 0 {
n = i;
break;
}
}
return string(text[:n]);
}
+44
View File
@@ -0,0 +1,44 @@
package win32_tests
import "core:fmt"
import "core:sys/win32"
main :: proc(){
test_utf16_to_utf8 :: proc(str: []u16, comparison: string, expected_result: bool, loc := #caller_location) {
result := win32.utf16_to_utf8(str[:]);
fmt.assertf((result == comparison) == expected_result,
"Incorrect utf16_to_utf8 conversion: %q %s %q\nloc = %#v\n",
result, "!=" if expected_result else "==", comparison, loc);
}
test_utf16_to_utf8([]u16{}, "", true);
test_utf16_to_utf8([]u16{0}, "", true);
test_utf16_to_utf8([]u16{0, 't', 'e', 's', 't'}, "", true);
test_utf16_to_utf8([]u16{0, 't', 'e', 's', 't', 0}, "", true);
test_utf16_to_utf8([]u16{'t', 'e', 's', 't'}, "test", true);
test_utf16_to_utf8([]u16{'t', 'e', 's', 't', 0}, "test", true);
test_utf16_to_utf8([]u16{'t', 'e', 0, 's', 't'}, "te", true);
test_utf16_to_utf8([]u16{'t', 'e', 0, 's', 't', 0}, "te", true);
test_wstring_to_utf8 :: proc(str: []u16, comparison: string, expected_result: bool, loc := #caller_location) {
result := win32.wstring_to_utf8(nil if len(str) == 0 else cast(win32.Wstring)&str[0], -1);
fmt.assertf((result == comparison) == expected_result,
"Incorrect wstring_to_utf8 conversion: %q %s %q\nloc = %#v\n",
result, "!=" if expected_result else "==", comparison, loc);
}
test_wstring_to_utf8([]u16{}, "", true);
test_wstring_to_utf8([]u16{0}, "", true);
test_wstring_to_utf8([]u16{0, 't', 'e', 's', 't'}, "", true);
test_wstring_to_utf8([]u16{0, 't', 'e', 's', 't', 0}, "", true);
test_wstring_to_utf8([]u16{'t', 'e', 's', 't', 0}, "test", true);
test_wstring_to_utf8([]u16{'t', 'e', 0, 's', 't'}, "te", true);
test_wstring_to_utf8([]u16{'t', 'e', 0, 's', 't', 0}, "te", true);
// WARNING: Passing a non-zero-terminated string to wstring_to_utf8 is dangerous,
// as it will go out of bounds looking for a zero.
// It will "fail" or "succeed" by having a zero just after the end of the input string or not.
test_wstring_to_utf8([]u16{'t', 'e', 's', 't'}, "test", false);
test_wstring_to_utf8([]u16{'t', 'e', 's', 't', 0}[:4], "test", true);
test_wstring_to_utf8([]u16{'t', 'e', 's', 't', 'q'}[:4], "test", false);
}