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

moonbitlang / x / 301

10 Dec 2024 06:19AM UTC coverage: 85.204% (-2.6%) from 87.841%
301

Pull #78

github

web-flow
Merge b830031f4 into 91f0fdf48
Pull Request #78: feat: new package encoding

105 of 161 new or added lines in 3 files covered. (65.22%)

124 existing lines in 29 files now uncovered.

1169 of 1372 relevant lines covered (85.2%)

434.92 hits per line

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

85.19
/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
/// ```
33
pub fn encode(encoding : Encoding, src : String) -> Bytes {
34
  // NOTE: special case: MoonBit String are already valid UTF16(LE) bytes
35
  match encoding {
4✔
36
    UTF16 | UTF16LE => return src.to_bytes()
2✔
37
    _ => ()
2✔
38
  }
39
  let new_buf = @buffer.T::new(size_hint=src.length() * 4)
40
  let write = match encoding {
41
    UTF8 => write_utf8_char
1✔
42
    UTF16BE => write_utf16be_char
1✔
NEW
43
    _ => abort("unreachable")
×
44
  }
45
  for char in src {
46
    // SAFETY: Assume String are always valid UTF16LE
47
    write(new_buf, char)
48
  }
49
  new_buf.to_bytes()
50
}
51

52
///|
53
/// Converts a Char to UTF-8 bytes.
54
///
55
/// Note that this function incurs allocation overhead
56
/// due to the intermediate creation of new buffers.
57
pub fn to_utf8_bytes(value : Char) -> Bytes {
58
  let buf = @buffer.new(size_hint=4)
4✔
59
  write_utf8_char(buf, value)
60
  buf.to_bytes()
61
}
62

63
///|
64
/// Converts a Char to UTF-16LE bytes.
65
///
66
/// Alias for `to_utf16le_bytes`.
67
///
68
/// Note that this function incurs allocation overhead
69
/// due to the intermediate creation of new buffers.
70
pub fn to_utf16_bytes(value : Char) -> Bytes {
71
  to_utf16le_bytes(value)
4✔
72
}
73

74
///|
75
/// Converts a Char to UTF-16LE bytes.
76
///
77
/// Note that this function incurs allocation overhead
78
/// due to the intermediate creation of new buffers.
79
pub fn to_utf16le_bytes(value : Char) -> Bytes {
80
  let buf = @buffer.new(size_hint=4)
8✔
81
  write_utf16le_char(buf, value)
82
  buf.to_bytes()
83
}
84

85
///|
86
/// Converts a Char to UTF-16BE bytes.
87
///
88
/// Note that this function incurs allocation overhead
89
/// due to the intermediate creation of new buffers.
90
pub fn to_utf16be_bytes(value : Char) -> Bytes {
91
  let buf = @buffer.new(size_hint=4)
4✔
92
  write_utf16be_char(buf, value)
93
  buf.to_bytes()
94
}
95

96
///|
97
/// Write a char into buffer as UTF8.
98
pub fn write_utf8_char(buf : @buffer.T, value : Char) -> Unit {
99
  let code = value.to_uint()
41✔
100
  match code {
101
    _..<0x80 => {
2✔
102
      let b0 = ((code & 0x7F) | 0x00).to_byte()
103
      buf.write_byte(b0)
104
    }
105
    _..<0x0800 => {
2✔
106
      let b0 = (((code >> 6) & 0x1F) | 0xC0).to_byte()
107
      let b1 = ((code & 0x3F) | 0x80).to_byte()
108
      buf.write_byte(b0)
109
      buf.write_byte(b1)
110
    }
111
    _..<0x010000 => {
24✔
112
      let b0 = (((code >> 12) & 0x0F) | 0xE0).to_byte()
113
      let b1 = (((code >> 6) & 0x3F) | 0x80).to_byte()
114
      let b2 = ((code & 0x3F) | 0x80).to_byte()
115
      buf.write_byte(b0)
116
      buf.write_byte(b1)
117
      buf.write_byte(b2)
118
    }
119
    _..<0x110000 => {
13✔
120
      let b0 = (((code >> 18) & 0x07) | 0xF0).to_byte()
121
      let b1 = (((code >> 12) & 0x3F) | 0x80).to_byte()
122
      let b2 = (((code >> 6) & 0x3F) | 0x80).to_byte()
123
      let b3 = ((code & 0x3F) | 0x80).to_byte()
124
      buf.write_byte(b0)
125
      buf.write_byte(b1)
126
      buf.write_byte(b2)
127
      buf.write_byte(b3)
128
    }
NEW
129
    _ => abort("Char out of range")
×
130
  }
131
}
132

133
///|
134
/// Write a char into buffer as UTF16LE.
135
/// Alias for `write_utf16le_char`
136
pub fn write_utf16_char(buf : @buffer.T, value : Char) -> Unit {
137
  write_utf16le_char(buf, value)
4✔
138
}
139

140
///|
141
/// Write a char into buffer as UTF16LE.
142
pub fn write_utf16le_char(buf : @buffer.T, value : Char) -> Unit {
143
  let code = value.to_uint()
34✔
144
  if code < 0x10000 {
145
    let b0 = (code & 0xFF).to_byte()
24✔
146
    let b1 = (code >> 8).to_byte()
147
    buf.write_byte(b0)
148
    buf.write_byte(b1)
149
  } else if code < 0x110000 {
10✔
150
    let hi = code - 0x10000
10✔
151
    let lo = (hi >> 10) | 0xD800
152
    let hi = (hi & 0x3FF) | 0xDC00
153
    let b0 = (lo & 0xFF).to_byte()
154
    let b1 = (lo >> 8).to_byte()
155
    let b2 = (hi & 0xFF).to_byte()
156
    let b3 = (hi >> 8).to_byte()
157
    buf.write_byte(b0)
158
    buf.write_byte(b1)
159
    buf.write_byte(b2)
160
    buf.write_byte(b3)
161
  } else {
NEW
162
    abort("Char out of range")
×
163
  }
164
}
165

166
///|
167
/// Write a char into buffer as UTF16BE.
168
pub fn write_utf16be_char(buf : @buffer.T, value : Char) -> Unit {
169
  let code = value.to_uint()
51✔
170
  if code < 0x10000 {
171
    let b0 = (code >> 0xFF).to_byte()
43✔
172
    let b1 = (code & 0xFF).to_byte()
173
    buf.write_byte(b0)
174
    buf.write_byte(b1)
175
  } else if code < 0x110000 {
8✔
176
    let hi = code - 0x10000
8✔
177
    let lo = (hi >> 10) | 0xD800
178
    let hi = (hi & 0x3FF) | 0xDC00
179
    let b0 = (lo >> 8).to_byte()
180
    let b1 = (lo & 0xFF).to_byte()
181
    let b2 = (hi >> 8).to_byte()
182
    let b3 = (hi & 0xFF).to_byte()
183
    buf.write_byte(b0)
184
    buf.write_byte(b1)
185
    buf.write_byte(b2)
186
    buf.write_byte(b3)
187
  } else {
NEW
188
    abort("Char out of range")
×
189
  }
190
}
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