1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

builtin: implement string_from_wide/1 and string_from_wide2/2 on *nix too (#18776)

This commit is contained in:
Delyan Angelov 2023-07-04 15:49:15 +03:00 committed by GitHub
parent 5d269ba703
commit 884fbb0a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 4 deletions

View File

@ -1,5 +1,7 @@
module builtin
import strings
const cp_utf8 = 65001
// to_wide returns a pointer to an UTF-16 version of the string receiver.
@ -34,7 +36,7 @@ pub fn (_str string) to_wide() &u16 {
// string_from_wide creates a V string, encoded in UTF-8, given a windows
// style string encoded in UTF-16.
[unsafe]
[manualfree; unsafe]
pub fn string_from_wide(_wstr &u16) string {
$if windows {
unsafe {
@ -42,7 +44,11 @@ pub fn string_from_wide(_wstr &u16) string {
return string_from_wide2(_wstr, wstr_len)
}
} $else {
return ''
mut i := 0
for unsafe { _wstr[i] } != 0 {
i++
}
return unsafe { string_from_wide2(_wstr, i) }
}
}
@ -50,7 +56,7 @@ pub fn string_from_wide(_wstr &u16) string {
// style string, encoded in UTF-16. It is more efficient, compared to
// string_from_wide, but it requires you to know the input string length,
// and to pass it as the second argument.
[unsafe]
[manualfree; unsafe]
pub fn string_from_wide2(_wstr &u16, len int) string {
$if windows {
unsafe {
@ -64,6 +70,15 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
return tos2(str_to)
}
} $else {
return ''
mut sb := strings.new_builder(len)
defer {
unsafe { sb.free() }
}
for i := 0; i < len; i++ {
u := unsafe { rune(_wstr[i]) }
sb.write_rune(u)
}
res := sb.str()
return res
}
}

View File

@ -54,3 +54,24 @@ fn test_to_wide_cyrillic() {
assert w[5] == 0
}
}
const wide_serial_number = [u8(67), 0, 76, 0, 52, 0, 54, 0, 73, 0, 49, 0, 65, 0, 48, 0, 48, 0,
54, 0, 52, 0, 57, 0, 0, 0, 0]
const swide_serial_number = 'CL46I1A00649'
fn test_string_from_wide() {
z := unsafe { string_from_wide(wide_serial_number.data) }
assert z == swide_serial_number
}
fn test_string_from_wide2() {
z := unsafe { string_from_wide2(wide_serial_number.data, 12) }
assert z == swide_serial_number
}
fn test_reverse_cyrillic_with_string_from_wide() {
s := 'Проба'
z := unsafe { string_from_wide(s.to_wide()) }
assert z == s
}