builtin: reduce allocations in `rune.bytes()`

pull/13136/head
Delyan Angelov 2022-01-11 14:41:01 +02:00
parent cb684b5c64
commit 8acd84d04a
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 21 additions and 10 deletions

View File

@ -54,8 +54,11 @@ pub fn (c rune) repeat(count int) string {
return res.repeat(count) return res.repeat(count)
} }
[manualfree]
pub fn (c rune) bytes() []byte { pub fn (c rune) bytes() []byte {
return c.str().bytes() mut res := []byte{cap: 5}
res.len = unsafe { utf32_decode_to_buffer(u32(c), &byte(res.data)) }
return res
} }
pub fn (c rune) length_in_bytes() int { pub fn (c rune) length_in_bytes() int {

View File

@ -23,27 +23,36 @@ pub fn utf32_to_str(code u32) string {
[manualfree; unsafe] [manualfree; unsafe]
pub fn utf32_to_str_no_malloc(code u32, buf &byte) string { pub fn utf32_to_str_no_malloc(code u32, buf &byte) string {
unsafe {
len := utf32_decode_to_buffer(code, buf)
if len == 0 {
return ''
}
buf[len] = 0
return tos(buf, len)
}
}
[manualfree; unsafe]
pub fn utf32_decode_to_buffer(code u32, buf &byte) int {
unsafe { unsafe {
icode := int(code) // Prevents doing casts everywhere icode := int(code) // Prevents doing casts everywhere
mut buffer := &byte(buf) mut buffer := &byte(buf)
if icode <= 127 { if icode <= 127 {
// 0x7F // 0x7F
buffer[0] = byte(icode) buffer[0] = byte(icode)
buffer[1] = 0 return 1
return tos(buffer, 1)
} else if icode <= 2047 { } else if icode <= 2047 {
// 0x7FF // 0x7FF
buffer[0] = 192 | byte(icode >> 6) // 0xC0 - 110xxxxx buffer[0] = 192 | byte(icode >> 6) // 0xC0 - 110xxxxx
buffer[1] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx buffer[1] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[2] = 0 return 2
return tos(buffer, 2)
} else if icode <= 65535 { } else if icode <= 65535 {
// 0xFFFF // 0xFFFF
buffer[0] = 224 | byte(icode >> 12) // 0xE0 - 1110xxxx buffer[0] = 224 | byte(icode >> 12) // 0xE0 - 1110xxxx
buffer[1] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx buffer[1] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[2] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx buffer[2] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[3] = 0 return 3
return tos(buffer, 3)
} }
// 0x10FFFF // 0x10FFFF
else if icode <= 1114111 { else if icode <= 1114111 {
@ -51,11 +60,10 @@ pub fn utf32_to_str_no_malloc(code u32, buf &byte) string {
buffer[1] = 128 | (byte(icode >> 12) & 63) // 0x80 - 0x3F - 10xxxxxx buffer[1] = 128 | (byte(icode >> 12) & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[2] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx buffer[2] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[3] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx buffer[3] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx
buffer[4] = 0 return 4
return tos(buffer, 4)
} }
} }
return '' return 0
} }
// Convert utf8 to utf32 // Convert utf8 to utf32