diff --git a/vlib/builtin/rune.v b/vlib/builtin/rune.v index 2386231a4b..c0b5891c64 100644 --- a/vlib/builtin/rune.v +++ b/vlib/builtin/rune.v @@ -54,8 +54,11 @@ pub fn (c rune) repeat(count int) string { return res.repeat(count) } +[manualfree] 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 { diff --git a/vlib/builtin/utf8.v b/vlib/builtin/utf8.v index 83c1fb8ca9..1ca083989a 100644 --- a/vlib/builtin/utf8.v +++ b/vlib/builtin/utf8.v @@ -23,27 +23,36 @@ pub fn utf32_to_str(code u32) string { [manualfree; unsafe] 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 { icode := int(code) // Prevents doing casts everywhere mut buffer := &byte(buf) if icode <= 127 { // 0x7F buffer[0] = byte(icode) - buffer[1] = 0 - return tos(buffer, 1) + return 1 } else if icode <= 2047 { // 0x7FF buffer[0] = 192 | byte(icode >> 6) // 0xC0 - 110xxxxx buffer[1] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx - buffer[2] = 0 - return tos(buffer, 2) + return 2 } else if icode <= 65535 { // 0xFFFF buffer[0] = 224 | byte(icode >> 12) // 0xE0 - 1110xxxx buffer[1] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx buffer[2] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx - buffer[3] = 0 - return tos(buffer, 3) + return 3 } // 0x10FFFF 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[2] = 128 | (byte(icode >> 6) & 63) // 0x80 - 0x3F - 10xxxxxx buffer[3] = 128 | byte(icode & 63) // 0x80 - 0x3F - 10xxxxxx - buffer[4] = 0 - return tos(buffer, 4) + return 4 } } - return '' + return 0 } // Convert utf8 to utf32