Przeglądaj źródła

os2 internals -> (c)string16

gingerBill 2 miesięcy temu
rodzic
commit
c631a8eff5

+ 3 - 11
core/os/os2/dir_windows.odin

@@ -16,7 +16,7 @@ find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW, al
 	}
 
 	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
-	path := concatenate({base_path, `\`, win32_wstring_to_utf8(raw_data(d.cFileName[:]), temp_allocator) or_else ""}, allocator) or_return
+	path := concatenate({base_path, `\`, win32_wstring_to_utf8(cstring16(raw_data(d.cFileName[:])), temp_allocator) or_else ""}, allocator) or_return
 
 	handle := win32.HANDLE(_open_internal(path, {.Read}, 0o666) or_else 0)
 	defer win32.CloseHandle(handle)
@@ -107,15 +107,7 @@ _read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File) {
 		return
 	}
 
-	wpath: []u16
-	{
-		i := 0
-		for impl.wname[i] != 0 {
-			i += 1
-		}
-		wpath = impl.wname[:i]
-	}
-
+	wpath := string16(impl.wname)
 	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 	wpath_search := make([]u16, len(wpath)+3, temp_allocator)
@@ -124,7 +116,7 @@ _read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File) {
 	wpath_search[len(wpath)+1] = '*'
 	wpath_search[len(wpath)+2] = 0
 
-	it.impl.find_handle = win32.FindFirstFileW(raw_data(wpath_search), &it.impl.find_data)
+	it.impl.find_handle = win32.FindFirstFileW(cstring16(raw_data(wpath_search)), &it.impl.find_data)
 	if it.impl.find_handle == win32.INVALID_HANDLE_VALUE {
 		read_directory_iterator_set_error(it, impl.name, _get_platform_error())
 		return

+ 1 - 1
core/os/os2/env_windows.odin

@@ -31,7 +31,7 @@ _lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value:
 		return "", false
 	}
 
-	value = win32_utf16_to_utf8(b[:n], allocator) or_else ""
+	value = win32_utf16_to_utf8(string16(b[:n]), allocator) or_else ""
 	found = true
 	return
 }

+ 52 - 16
core/os/os2/file_windows.odin

@@ -247,7 +247,7 @@ _destroy :: proc(f: ^File_Impl) -> Error {
 	}
 
 	a := f.allocator
-	err0 := free(f.wname, a)
+	err0 := free(rawptr(f.wname), a)
 	err1 := delete(f.name, a)
 	err2 := free(f, a)
 	err3 := delete(f.r_buf, a)
@@ -661,7 +661,7 @@ _normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: st
 	}
 
 
-	handle := _open_sym_link(raw_data(p)) or_return
+	handle := _open_sym_link(cstring16(raw_data(p))) or_return
 	defer win32.CloseHandle(handle)
 
 	n := win32.GetFinalPathNameByHandleW(handle, nil, 0, win32.VOLUME_NAME_DOS)
@@ -672,7 +672,7 @@ _normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: st
 	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 	buf := make([]u16, n+1, temp_allocator)
-	n = win32.GetFinalPathNameByHandleW(handle, raw_data(buf), u32(len(buf)), win32.VOLUME_NAME_DOS)
+	n = win32.GetFinalPathNameByHandleW(handle, cstring16(raw_data(buf)), u32(len(buf)), win32.VOLUME_NAME_DOS)
 	if n == 0 {
 		return "", _get_platform_error()
 	}
@@ -713,7 +713,7 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er
 	switch rdb.ReparseTag {
 	case win32.IO_REPARSE_TAG_SYMLINK:
 		rb := (^win32.SYMBOLIC_LINK_REPARSE_BUFFER)(&rdb.rest)
-		pb := win32.wstring(&rb.PathBuffer)
+		pb := ([^]u16)(&rb.PathBuffer)
 		pb[rb.SubstituteNameOffset+rb.SubstituteNameLength] = 0
 		p := pb[rb.SubstituteNameOffset:][:rb.SubstituteNameLength]
 		if rb.Flags & win32.SYMLINK_FLAG_RELATIVE != 0 {
@@ -723,7 +723,7 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er
 
 	case win32.IO_REPARSE_TAG_MOUNT_POINT:
 		rb := (^win32.MOUNT_POINT_REPARSE_BUFFER)(&rdb.rest)
-		pb := win32.wstring(&rb.PathBuffer)
+		pb := ([^]u16)(&rb.PathBuffer)
 		pb[rb.SubstituteNameOffset+rb.SubstituteNameLength] = 0
 		p := pb[rb.SubstituteNameOffset:][:rb.SubstituteNameLength]
 		return _normalize_link_path(p, allocator)
@@ -874,8 +874,8 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte,
 
 
 @(private="package", require_results)
-win32_utf8_to_wstring :: proc(s: string, allocator: runtime.Allocator) -> (ws: [^]u16, err: runtime.Allocator_Error) {
-	ws = raw_data(win32_utf8_to_utf16(s, allocator) or_return)
+win32_utf8_to_wstring :: proc(s: string, allocator: runtime.Allocator) -> (ws: cstring16, err: runtime.Allocator_Error) {
+	ws = cstring16(raw_data(win32_utf8_to_utf16(s, allocator) or_return))
 	return
 }
 
@@ -909,24 +909,60 @@ win32_utf8_to_utf16 :: proc(s: string, allocator: runtime.Allocator) -> (ws: []u
 }
 
 @(private="package", require_results)
-win32_wstring_to_utf8 :: proc(s: [^]u16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
-	if s == nil || s[0] == 0 {
+win32_wstring_to_utf8 :: proc(s: cstring16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
+	if s == nil || s == "" {
 		return "", nil
 	}
-	n := 0
-	for s[n] != 0 {
-		n += 1
+	return win32_utf16_to_utf8(string16(s), allocator)
+}
+
+@(private="package")
+win32_utf16_to_utf8 :: proc{
+	win32_utf16_string16_to_utf8,
+	win32_utf16_u16_to_utf8
+}
+
+@(private="package", require_results)
+win32_utf16_string16_to_utf8 :: proc(s: string16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
+	if len(s) == 0 {
+		return
 	}
-	return win32_utf16_to_utf8(s[:n], allocator)
+
+	n := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, cstring16(raw_data(s)), i32(len(s)), nil, 0, nil, nil)
+	if n == 0 {
+		return
+	}
+
+	// If N < 0 the call to WideCharToMultiByte assume the wide string is null terminated
+	// and will scan it to find the first null terminated character. The resulting string will
+	// also be null terminated.
+	// If N > 0 it assumes the wide string is not null terminated and the resulting string
+	// will not be null terminated.
+	text := make([]byte, n, allocator) or_return
+
+	n1 := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, cstring16(raw_data(s)), i32(len(s)), raw_data(text), n, nil, nil)
+	if n1 == 0 {
+		delete(text, allocator)
+		return
+	}
+
+	for i in 0..<n {
+		if text[i] == 0 {
+			n = i
+			break
+		}
+	}
+	res = string(text[:n])
+	return
 }
 
 @(private="package", require_results)
-win32_utf16_to_utf8 :: proc(s: []u16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
+win32_utf16_u16_to_utf8 :: proc(s: []u16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
 	if len(s) == 0 {
 		return
 	}
 
-	n := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, raw_data(s), i32(len(s)), nil, 0, nil, nil)
+	n := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, cstring16(raw_data(s)), i32(len(s)), nil, 0, nil, nil)
 	if n == 0 {
 		return
 	}
@@ -938,7 +974,7 @@ win32_utf16_to_utf8 :: proc(s: []u16, allocator: runtime.Allocator) -> (res: str
 	// will not be null terminated.
 	text := make([]byte, n, allocator) or_return
 
-	n1 := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, raw_data(s), i32(len(s)), raw_data(text), n, nil, nil)
+	n1 := win32.WideCharToMultiByte(win32.CP_UTF8, win32.WC_ERR_INVALID_CHARS, cstring16(raw_data(s)), i32(len(s)), raw_data(text), n, nil, nil)
 	if n1 == 0 {
 		delete(text, allocator)
 		return

+ 4 - 4
core/os/os2/path_windows.odin

@@ -91,11 +91,11 @@ _remove_all :: proc(path: string) -> Error {
 		nil,
 		win32.FO_DELETE,
 		dir,
-		&empty[0],
+		cstring16(&empty[0]),
 		win32.FOF_NOCONFIRMATION | win32.FOF_NOERRORUI | win32.FOF_SILENT,
 		false,
 		nil,
-		&empty[0],
+		cstring16(&empty[0]),
 	}
 	res := win32.SHFileOperationW(&file_op)
 	if res != 0 {
@@ -303,13 +303,13 @@ _get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absol
 	}
 	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 	rel_utf16 := win32.utf8_to_utf16(rel, temp_allocator)
-	n := win32.GetFullPathNameW(raw_data(rel_utf16), 0, nil, nil)
+	n := win32.GetFullPathNameW(cstring16(raw_data(rel_utf16)), 0, nil, nil)
 	if n == 0 {
 		return "", Platform_Error(win32.GetLastError())
 	}
 
 	buf := make([]u16, n, temp_allocator) or_return
-	n = win32.GetFullPathNameW(raw_data(rel_utf16), u32(n), raw_data(buf), nil)
+	n = win32.GetFullPathNameW(cstring16(raw_data(rel_utf16)), u32(n), cstring16(raw_data(buf)), nil)
 	if n == 0 {
 		return "", Platform_Error(win32.GetLastError())
 	}

+ 4 - 4
core/os/os2/process_windows.odin

@@ -175,7 +175,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
 				info.fields += {.Command_Line}
 			}
 			if .Command_Args in selection {
-				info.command_args = _parse_command_line(raw_data(cmdline_w), allocator) or_return
+				info.command_args = _parse_command_line(cstring16(raw_data(cmdline_w)), allocator) or_return
 				info.fields += {.Command_Args}
 			}
 		}
@@ -286,7 +286,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
 				info.fields += {.Command_Line}
 			}
 			if .Command_Args in selection {
-				info.command_args = _parse_command_line(raw_data(cmdline_w), allocator) or_return
+				info.command_args = _parse_command_line(cstring16(raw_data(cmdline_w)), allocator) or_return
 				info.fields += {.Command_Args}
 			}
 		}
@@ -610,7 +610,7 @@ _process_exe_by_pid :: proc(pid: int, allocator: runtime.Allocator) -> (exe_path
 		err =_get_platform_error()
 		return
 	}
-	return win32_wstring_to_utf8(raw_data(entry.szExePath[:]), allocator)
+	return win32_wstring_to_utf8(cstring16(raw_data(entry.szExePath[:])), allocator)
 }
 
 _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Allocator) -> (full_username: string, err: Error) {
@@ -650,7 +650,7 @@ _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Alloc
 	return strings.concatenate({domain, "\\", username}, allocator)
 }
 
-_parse_command_line :: proc(cmd_line_w: [^]u16, allocator: runtime.Allocator) -> (argv: []string, err: Error) {
+_parse_command_line :: proc(cmd_line_w: cstring16, allocator: runtime.Allocator) -> (argv: []string, err: Error) {
 	argc: i32
 	argv_w := win32.CommandLineToArgvW(cmd_line_w, &argc)
 	if argv_w == nil {

+ 7 - 7
core/os/os2/stat_windows.odin

@@ -49,12 +49,12 @@ full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path
 
 	p := win32_utf8_to_utf16(name, temp_allocator) or_return
 
-	n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil)
+	n := win32.GetFullPathNameW(cstring16(raw_data(p)), 0, nil, nil)
 	if n == 0 {
 		return "", _get_platform_error()
 	}
 	buf := make([]u16, n+1, temp_allocator)
-	n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
+	n = win32.GetFullPathNameW(cstring16(raw_data(p)), u32(len(buf)), cstring16(raw_data(buf)), nil)
 	if n == 0 {
 		return "", _get_platform_error()
 	}
@@ -140,8 +140,8 @@ _cleanpath_from_handle :: proc(f: ^File, allocator: runtime.Allocator) -> (strin
 	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 	buf := make([]u16, max(n, 260)+1, temp_allocator)
-	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
-	return _cleanpath_from_buf(buf[:n], allocator)
+	n = win32.GetFinalPathNameByHandleW(h, cstring16(raw_data(buf)), u32(len(buf)), 0)
+	return _cleanpath_from_buf(string16(buf[:n]), allocator)
 }
 
 _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) {
@@ -158,12 +158,12 @@ _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) {
 	temp_allocator := TEMP_ALLOCATOR_GUARD({})
 
 	buf := make([]u16, max(n, 260)+1, temp_allocator)
-	n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0)
+	n = win32.GetFinalPathNameByHandleW(h, cstring16(raw_data(buf)), u32(len(buf)), 0)
 	return _cleanpath_strip_prefix(buf[:n]), nil
 }
 
-_cleanpath_from_buf :: proc(buf: []u16, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
-	buf := buf
+_cleanpath_from_buf :: proc(buf: string16, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
+	buf := transmute([]u16)buf
 	buf = _cleanpath_strip_prefix(buf)
 	return win32_utf16_to_utf8(buf, allocator)
 }

+ 2 - 2
core/os/os2/temp_file_windows.odin

@@ -12,12 +12,12 @@ _temp_dir :: proc(allocator: runtime.Allocator) -> (string, runtime.Allocator_Er
 	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
 
 	b := make([]u16, max(win32.MAX_PATH, n), temp_allocator)
-	n = win32.GetTempPathW(u32(len(b)), raw_data(b))
+	n = win32.GetTempPathW(u32(len(b)), cstring16(raw_data(b)))
 
 	if n == 3 && b[1] == ':' && b[2] == '\\' {
 
 	} else if n > 0 && b[n-1] == '\\' {
 		n -= 1
 	}
-	return win32_utf16_to_utf8(b[:n], allocator)
+	return win32_utf16_to_utf8(string16(b[:n]), allocator)
 }

+ 1 - 2
core/os/os2/user_windows.odin

@@ -74,6 +74,5 @@ _get_known_folder_path :: proc(rfid: win32.REFKNOWNFOLDERID, allocator: runtime.
 		return "", .Invalid_Path
 	}
 
-	dir, _ = win32.wstring_to_utf8(path_w, -1, allocator)
-	return
+	return win32_wstring_to_utf8(cstring16(path_w), allocator)
 }

+ 1 - 1
core/sys/windows/kernel32.odin

@@ -258,7 +258,7 @@ foreign kernel32 {
 	) -> BOOL ---
 	CreateProcessW :: proc(
 		lpApplicationName: LPCWSTR,
-		lpCommandLine: LPWSTR,
+		lpCommandLine: LPCWSTR,
 		lpProcessAttributes: LPSECURITY_ATTRIBUTES,
 		lpThreadAttributes: LPSECURITY_ATTRIBUTES,
 		bInheritHandles: BOOL,

+ 1 - 1
core/sys/windows/types.odin

@@ -1698,7 +1698,7 @@ NM_FONTCHANGED          :: NM_OUTOFMEMORY-22
 NM_CUSTOMTEXT           :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
 NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM
 
-PCZZWSTR :: ^WCHAR
+PCZZWSTR :: cstring16
 
 SHFILEOPSTRUCTW :: struct {
 	hwnd: HWND,