util.odin 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package sys_windows
  2. utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 {
  3. if len(s) < 1 {
  4. return nil;
  5. }
  6. b := transmute([]byte)s;
  7. cstr := &b[0];
  8. n := MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), nil, 0);
  9. if n == 0 {
  10. return nil;
  11. }
  12. text := make([]u16, n+1, allocator);
  13. n1 := MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), wstring(&text[0]), i32(n));
  14. if n1 == 0 {
  15. delete(text, allocator);
  16. return nil;
  17. }
  18. text[n] = 0;
  19. for n >= 1 && text[n-1] == 0 {
  20. n -= 1;
  21. }
  22. return text[:n];
  23. }
  24. utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstring {
  25. if res := utf8_to_utf16(s, allocator); res != nil {
  26. return wstring(&res[0]);
  27. }
  28. return nil;
  29. }
  30. wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> string {
  31. if N == 0 {
  32. return "";
  33. }
  34. n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil);
  35. if n == 0 {
  36. return "";
  37. }
  38. // If N == -1 the call to WideCharToMultiByte assume the wide string is null terminated
  39. // and will scan it to find the first null terminated character. The resulting string will
  40. // also null terminated.
  41. // If N != -1 it assumes the wide string is not null terminated and the resulting string
  42. // will not be null terminated, we therefore have to force it to be null terminated manually.
  43. text := make([]byte, n+1 if N != -1 else n, allocator);
  44. if n1 := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), &text[0], n, nil, nil); n1 == 0 {
  45. delete(text, allocator);
  46. return "";
  47. }
  48. for i in 0..<n {
  49. if text[i] == 0 {
  50. n = i;
  51. break;
  52. }
  53. }
  54. return string(text[:n]);
  55. }
  56. utf16_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> string {
  57. if len(s) == 0 do return "";
  58. return wstring_to_utf8(cast(wstring)&s[0], len(s), allocator);
  59. }