Skip to content

Commit 6a8a49a

Browse files
committed
internal(fs): add wasm & wasm-gc support
1 parent 7668101 commit 6a8a49a

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

fs_sync/fs_sync_wasm.mbt

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright 2025 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+
fn get_error_message_ffi() -> XExternString = "__moonbit_fs_unstable" "get_error_message"
16+
17+
fn get_error_message() -> String {
18+
string_from_extern(get_error_message_ffi())
19+
}
20+
21+
fn get_file_content_ffi() -> XExternByteArray = "__moonbit_fs_unstable" "get_file_content"
22+
23+
fn read_file_to_bytes_ffi(path : XExternString) -> Int = "__moonbit_fs_unstable" "read_file_to_bytes_new"
24+
25+
fn write_bytes_to_file_ffi(path : XExternString, content : XExternByteArray) -> Int = "__moonbit_fs_unstable" "write_bytes_to_file_new"
26+
27+
fn read_file_to_bytes_internal(path : String) -> Bytes! {
28+
let res = read_file_to_bytes_ffi(string_to_extern(path))
29+
guard res != -1 else { raise IOError(get_error_message()) }
30+
byte_array_from_extern(get_file_content_ffi())
31+
}
32+
33+
fn read_file_to_string_internal(path : String, encoding~ : String = "utf8") -> String! {
34+
guard encoding == "utf8" else { raise IOError("Unsupported encoding: \{encoding}, only utf8 is supported for now") }
35+
utf8_bytes_to_mbt_string(read_file_to_bytes_internal!(path))
36+
}
37+
38+
fn write_bytes_to_file_internal(path : String, content : Bytes) -> Unit! {
39+
let res = write_bytes_to_file_ffi(string_to_extern(path), byte_array_to_extern(content))
40+
guard res != -1 else { raise IOError(get_error_message()) }
41+
}
42+
43+
fn write_string_to_file_internal(path : String, content : String, encoding~ : String = "utf8") -> Unit! {
44+
guard encoding == "utf8" else { raise IOError("Unsupported encoding: \{encoding}, only utf8 is supported for now") }
45+
write_bytes_to_file_internal!(path, mbt_string_to_utf8_bytes(content, false))
46+
}
47+
48+
49+
///|
50+
priv type XStringCreateHandle
51+
52+
///|
53+
priv type XExternString
54+
55+
///|
56+
priv type XExternByteArray
57+
58+
///|
59+
priv type XByteArrayCreateHandle
60+
61+
///|
62+
priv type XByteArrayReadHandle
63+
64+
///|
65+
fn begin_create_string() -> XStringCreateHandle = "__moonbit_fs_unstable" "begin_create_string"
66+
67+
///|
68+
fn string_append_char(handle : XStringCreateHandle, ch : Char) = "__moonbit_fs_unstable" "string_append_char"
69+
70+
///|
71+
fn finish_create_string(handle : XStringCreateHandle) -> XExternString = "__moonbit_fs_unstable" "finish_create_string"
72+
73+
///|
74+
fn string_to_extern(s : String) -> XExternString {
75+
let handle = begin_create_string()
76+
for i = 0; i < s.length(); i = i + 1 {
77+
string_append_char(handle, s[i])
78+
}
79+
finish_create_string(handle)
80+
}
81+
82+
///|
83+
fn begin_read_byte_array(s : XExternByteArray) -> XByteArrayReadHandle = "__moonbit_fs_unstable" "begin_read_byte_array"
84+
85+
///|
86+
fn byte_array_read_byte(handle : XByteArrayReadHandle) -> Int = "__moonbit_fs_unstable" "byte_array_read_byte"
87+
88+
///|
89+
fn finish_read_byte_array(handle : XByteArrayReadHandle) = "__moonbit_fs_unstable" "finish_read_byte_array"
90+
91+
///|
92+
fn begin_create_byte_array() -> XByteArrayCreateHandle = "__moonbit_fs_unstable" "begin_create_byte_array"
93+
94+
///|
95+
fn byte_array_append_byte(handle : XByteArrayCreateHandle, ch : Int) = "__moonbit_fs_unstable" "byte_array_append_byte"
96+
97+
///|
98+
fn finish_create_byte_array(
99+
handle : XByteArrayCreateHandle
100+
) -> XExternByteArray = "__moonbit_fs_unstable" "finish_create_byte_array"
101+
102+
///|
103+
fn byte_array_to_extern(s : Bytes) -> XExternByteArray {
104+
let handle = begin_create_byte_array()
105+
for i = 0; i < s.length(); i = i + 1 {
106+
byte_array_append_byte(handle, s[i].to_int())
107+
}
108+
finish_create_byte_array(handle)
109+
}
110+
111+
///|
112+
fn byte_array_from_extern(e : XExternByteArray) -> Bytes {
113+
let buf = Array::new()
114+
let handle = begin_read_byte_array(e)
115+
while true {
116+
let ch = byte_array_read_byte(handle)
117+
if ch == -1 {
118+
break
119+
} else {
120+
buf.push(ch.to_byte())
121+
}
122+
}
123+
finish_read_byte_array(handle)
124+
Bytes::from_array(buf)
125+
}
126+
127+
priv type XStringReadHandle
128+
///|
129+
fn begin_read_string(s : XExternString) -> XStringReadHandle = "__moonbit_fs_unstable" "begin_read_string"
130+
131+
///| Read one char from the string, returns -1 if the end of the string is reached.
132+
/// The number returned is the unicode codepoint of the character.
133+
fn string_read_char(handle : XStringReadHandle) -> Int = "__moonbit_fs_unstable" "string_read_char"
134+
135+
///|
136+
fn finish_read_string(handle : XStringReadHandle) = "__moonbit_fs_unstable" "finish_read_string"
137+
138+
fn string_from_extern(e : XExternString) -> String {
139+
let buf = StringBuilder::new()
140+
let handle = begin_read_string(e)
141+
while true {
142+
let ch = string_read_char(handle)
143+
if ch == -1 {
144+
break
145+
} else {
146+
buf.write_char(Char::from_int(ch))
147+
}
148+
}
149+
finish_read_string(handle)
150+
buf.to_string()
151+
}

0 commit comments

Comments
 (0)