1 | // Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved. |
2 | // Use of this source code is governed by an MIT license that can be found in the LICENSE file. |
3 | module builtin |
4 | |
5 | import strings |
6 | |
7 | // This was never working correctly, the issue is now |
8 | // fixed however the type checks in checker need to be |
9 | // updated. if you uncomment it you will see the issue |
10 | // type rune = int |
11 | |
12 | pub fn (c rune) str() string { |
13 | return utf32_to_str(u32(c)) |
14 | /* |
15 | unsafe { |
16 | fst_byte := int(c)>>8 * 3 & 0xff |
17 | len := utf8_char_len(u8(fst_byte)) |
18 | println('len=$len') |
19 | mut str := string{ |
20 | len: len |
21 | str: malloc_noscan(len + 1) |
22 | } |
23 | for i in 0..len { |
24 | str.str[i] = u8(int(c)>>8 * (3 - i) & 0xff) |
25 | } |
26 | str.str[len] = `\0` |
27 | println(str) |
28 | return str |
29 | } |
30 | */ |
31 | } |
32 | |
33 | // string converts a rune array to a string |
34 | [manualfree] |
35 | pub fn (ra []rune) string() string { |
36 | mut sb := strings.new_builder(ra.len) |
37 | sb.write_runes(ra) |
38 | res := sb.str() |
39 | unsafe { sb.free() } |
40 | return res |
41 | } |
42 | |
43 | // repeat returns a new string with `count` number of copies of the rune it was called on. |
44 | pub fn (c rune) repeat(count int) string { |
45 | if count < 0 { |
46 | panic('rune.repeat: count is negative: ${count}') |
47 | } else if count == 0 { |
48 | return '' |
49 | } else if count == 1 { |
50 | return c.str() |
51 | } |
52 | mut buffer := [5]u8{} |
53 | res := unsafe { utf32_to_str_no_malloc(u32(c), &buffer[0]) } |
54 | return res.repeat(count) |
55 | } |
56 | |
57 | [manualfree] |
58 | pub fn (c rune) bytes() []u8 { |
59 | mut res := []u8{cap: 5} |
60 | res.len = unsafe { utf32_decode_to_buffer(u32(c), &u8(res.data)) } |
61 | return res |
62 | } |
63 | |
64 | // length_in_bytes returns the number of bytes needed to store the code point. |
65 | // Returns -1 if the data is not a valid code point. |
66 | pub fn (c rune) length_in_bytes() int { |
67 | code := u32(c) |
68 | if code <= 0x7F { |
69 | return 1 |
70 | } else if code <= 0x7FF { |
71 | return 2 |
72 | } else if 0xD800 <= code && code <= 0xDFFF { |
73 | // between min and max for surrogates |
74 | return -1 |
75 | } else if code <= 0xFFFF { |
76 | return 3 |
77 | } else if code <= 0x10FFFF { |
78 | // 0x10FFFF is the maximum valid unicode code point |
79 | return 4 |
80 | } |
81 | return -1 |
82 | } |