• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moonbitlang / x / 534

21 Jul 2025 07:25AM UTC coverage: 89.676% (-0.2%) from 89.897%
534

push

github

peter-jerry-ye
ci: it's 2025 now

1911 of 2131 relevant lines covered (89.68%)

383.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.35
/encoding/encoding.mbt
1
// Copyright 2024 International Digital Economy Academy
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
///|
16
/// Encode a given string to the specified character encoding and returns the resulting bytes.
17
///
18
/// # Parameters
19
///
20
/// - `encoding` : The target encoding format.
21
/// - `src`: The input string to be encoded.
22
///
23
/// # Returns
24
///
25
/// A `bytes` representing the encoded string in the selected format.
26
///
27
/// # Examples
28
///
29
/// ```moonbit
30
///   let src = "Hello, World!"
31
///   let encoded_bytes = encode(UTF8, src)
32
///   assert_eq(encoded_bytes, @bytes.of([72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]))
33
/// ```
34
pub fn encode(encoding : Encoding, src : String) -> Bytes {
35
  // NOTE: special case: MoonBit String are already valid UTF16(LE) bytes
36
  match encoding {
7✔
37
    UTF16 | UTF16LE => return src.to_bytes()
2✔
38
    _ => ()
5✔
39
  }
40
  let new_buf = @buffer.new(size_hint=src.length() * 4)
5✔
41
  let write = match encoding {
5✔
42
    UTF8 => write_utf8_char
3✔
43
    UTF16BE => write_utf16be_char
2✔
44
    _ => abort("unreachable")
×
45
  }
46
  for char in src {
47
    // SAFETY: Assume String are always valid UTF16LE
48
    write(new_buf, char)
101✔
49
  }
50
  new_buf.to_bytes()
5✔
51
}
52

53
///|
54
/// Encodes a string into the specified character encoding and writes the result
55
/// directly into a buffer.
56
///
57
/// Parameters:
58
///
59
/// * `string` : The input string to be encoded.
60
/// * `buffer` : The buffer where the encoded bytes will be written to.
61
/// * `encoding` : The target encoding format. Defaults to UTF8 if not specified.
62
///
63
/// Example:
64
///
65
/// ```moonbit
66
///   let buf = @buffer.new()
67
///   let text = "Hello, world"
68
///   @encoding.encode_to(text, buf, encoding=UTF16)
69
///   inspect(buf.to_string(), content="Hello, world")
70
/// ```
71
pub fn encode_to(
72
  src : String,
73
  buffer : @buffer.T,
74
  encoding~ : Encoding
75
) -> Unit {
76
  match encoding {
5✔
77
    UTF8 =>
78
      for char in src {
1✔
79
        write_utf8_char(buffer, char)
3✔
80
      }
81
    UTF16BE =>
82
      for char in src {
1✔
83
        write_utf16be_char(buffer, char)
25✔
84
      }
85
    UTF16 | UTF16LE => buffer.write_string(src)
3✔
86
  }
87
}
88

89
///|
90
/// Converts a Char to UTF-8 bytes.
91
///
92
/// Note that this function incurs allocation overhead
93
/// due to the intermediate creation of new buffers.
94
pub fn to_utf8_bytes(value : Char) -> Bytes {
95
  let buf = @buffer.new(size_hint=4)
4✔
96
  write_utf8_char(buf, value)
4✔
97
  buf.to_bytes()
4✔
98
}
99

100
///|
101
/// Converts a Char to UTF-16LE bytes.
102
///
103
/// Alias for `to_utf16le_bytes`.
104
///
105
/// Note that this function incurs allocation overhead
106
/// due to the intermediate creation of new buffers.
107
pub fn to_utf16_bytes(value : Char) -> Bytes {
108
  to_utf16le_bytes(value)
4✔
109
}
110

111
///|
112
/// Converts a Char to UTF-16LE bytes.
113
///
114
/// Note that this function incurs allocation overhead
115
/// due to the intermediate creation of new buffers.
116
pub fn to_utf16le_bytes(value : Char) -> Bytes {
117
  let buf = @buffer.new(size_hint=4)
8✔
118
  write_utf16le_char(buf, value)
8✔
119
  buf.to_bytes()
8✔
120
}
121

122
///|
123
/// Converts a Char to UTF-16BE bytes.
124
///
125
/// Note that this function incurs allocation overhead
126
/// due to the intermediate creation of new buffers.
127
pub fn to_utf16be_bytes(value : Char) -> Bytes {
128
  let buf = @buffer.new(size_hint=4)
4✔
129
  write_utf16be_char(buf, value)
4✔
130
  buf.to_bytes()
4✔
131
}
132

133
///|
134
/// Write a char into buffer as UTF8.
135
pub fn write_utf8_char(buf : @buffer.T, value : Char) -> Unit {
136
  let code = value.to_uint()
83✔
137
  match code {
83✔
138
    _..<0x80 => {
32✔
139
      let b0 = ((code & 0x7F) | 0x00).to_byte()
32✔
140
      buf.write_byte(b0)
32✔
141
    }
142
    _..<0x0800 => {
2✔
143
      let b0 = (((code >> 6) & 0x1F) | 0xC0).to_byte()
2✔
144
      let b1 = ((code & 0x3F) | 0x80).to_byte()
2✔
145
      buf.write_byte(b0)
2✔
146
      buf.write_byte(b1)
2✔
147
    }
148
    _..<0x010000 => {
29✔
149
      let b0 = (((code >> 12) & 0x0F) | 0xE0).to_byte()
29✔
150
      let b1 = (((code >> 6) & 0x3F) | 0x80).to_byte()
29✔
151
      let b2 = ((code & 0x3F) | 0x80).to_byte()
29✔
152
      buf.write_byte(b0)
29✔
153
      buf.write_byte(b1)
29✔
154
      buf.write_byte(b2)
29✔
155
    }
156
    _..<0x110000 => {
20✔
157
      let b0 = (((code >> 18) & 0x07) | 0xF0).to_byte()
20✔
158
      let b1 = (((code >> 12) & 0x3F) | 0x80).to_byte()
20✔
159
      let b2 = (((code >> 6) & 0x3F) | 0x80).to_byte()
20✔
160
      let b3 = ((code & 0x3F) | 0x80).to_byte()
20✔
161
      buf.write_byte(b0)
20✔
162
      buf.write_byte(b1)
20✔
163
      buf.write_byte(b2)
20✔
164
      buf.write_byte(b3)
20✔
165
    }
166
    _ => abort("Char out of range")
×
167
  }
168
}
169

170
///|
171
/// Write a char into buffer as UTF16LE.
172
/// Alias for `write_utf16le_char`
173
pub fn write_utf16_char(buf : @buffer.T, value : Char) -> Unit {
174
  write_utf16le_char(buf, value)
4✔
175
}
176

177
///|
178
/// Write a char into buffer as UTF16LE.
179
pub fn write_utf16le_char(buf : @buffer.T, value : Char) -> Unit {
180
  let code = value.to_uint()
64✔
181
  if code < 0x10000 {
182
    let b0 = (code & 0xFF).to_byte()
44✔
183
    let b1 = (code >> 8).to_byte()
44✔
184
    buf.write_byte(b0)
44✔
185
    buf.write_byte(b1)
44✔
186
  } else if code < 0x110000 {
20✔
187
    let hi = code - 0x10000
20✔
188
    let lo = (hi >> 10) | 0xD800
189
    let hi = (hi & 0x3FF) | 0xDC00
190
    let b0 = (lo & 0xFF).to_byte()
20✔
191
    let b1 = (lo >> 8).to_byte()
20✔
192
    let b2 = (hi & 0xFF).to_byte()
20✔
193
    let b3 = (hi >> 8).to_byte()
20✔
194
    buf.write_byte(b0)
20✔
195
    buf.write_byte(b1)
20✔
196
    buf.write_byte(b2)
20✔
197
    buf.write_byte(b3)
20✔
198
  } else {
199
    abort("Char out of range")
×
200
  }
201
}
202

203
///|
204
/// Write a char into buffer as UTF16BE.
205
pub fn write_utf16be_char(buf : @buffer.T, value : Char) -> Unit {
206
  let code = value.to_uint()
116✔
207
  if code < 0x10000 {
208
    let b0 = (code >> 8).to_byte()
106✔
209
    let b1 = (code & 0xFF).to_byte()
106✔
210
    buf.write_byte(b0)
106✔
211
    buf.write_byte(b1)
106✔
212
  } else if code < 0x110000 {
10✔
213
    let hi = code - 0x10000
10✔
214
    let lo = (hi >> 10) | 0xD800
215
    let hi = (hi & 0x3FF) | 0xDC00
216
    let b0 = (lo >> 8).to_byte()
10✔
217
    let b1 = (lo & 0xFF).to_byte()
10✔
218
    let b2 = (hi >> 8).to_byte()
10✔
219
    let b3 = (hi & 0xFF).to_byte()
10✔
220
    buf.write_byte(b0)
10✔
221
    buf.write_byte(b1)
10✔
222
    buf.write_byte(b2)
10✔
223
    buf.write_byte(b3)
10✔
224
  } else {
225
    abort("Char out of range")
×
226
  }
227
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc