1use std::{
2 cell::RefCell,
3 io::Result,
4 pin::Pin,
5 rc::Rc,
6 task::{Context, Poll},
7};
8
9use futures_lite::AsyncWrite;
10use js_sys::{Object, Uint8Array};
11use wasm_bindgen::JsValue;
12
13use crate::{
14 set_value, File, Fs, Task, BUF, CLOSE, CURSOR, FD, FLUSH, FS, INDEX, POST_ERROR, WRITE,
15};
16
17impl Fs {
18 fn write(&self, fd: usize, buf: &[u8], cursor: u64, task: Rc<RefCell<Task<Result<usize>>>>) {
19 let write_obj = Object::new();
20 let index = self.inner.borrow_mut().writing_tasks.insert(task);
21 let typed_array = Uint8Array::new_with_length(buf.len() as u32);
22 typed_array.copy_from(buf);
23
24 set_value(&write_obj, &INDEX, &JsValue::from(index));
25 set_value(&write_obj, &FD, &JsValue::from(fd));
26 set_value(&write_obj, &BUF, &typed_array.buffer());
27 set_value(&write_obj, &CURSOR, &JsValue::from_f64(cursor as f64));
28 let msg = Object::new();
29 set_value(&msg, &WRITE, &write_obj);
30
31 self.worker.post_message(&msg).expect(POST_ERROR);
32 }
33 fn flush(&self, fd: usize, task: Rc<RefCell<Task<Result<()>>>>) {
34 let index = self.inner.borrow_mut().flushing_tasks.insert(task);
35
36 let msg = Object::new();
37 let flust = Object::new();
38 set_value(&flust, &FD, &JsValue::from(fd));
39 set_value(&flust, &INDEX, &JsValue::from(index));
40 set_value(&msg, &FLUSH, &flust);
41
42 self.worker.post_message(&msg).expect(POST_ERROR);
43 }
44 fn close(&self, fd: usize, task: Rc<RefCell<Task<Result<()>>>>) {
45 let index = self.inner.borrow_mut().closing_tasks.insert(task);
46
47 let msg = Object::new();
48 let close = Object::new();
49 set_value(&close, &FD, &JsValue::from(fd));
50 set_value(&close, &INDEX, &JsValue::from(index));
51 set_value(&msg, &CLOSE, &close);
52
53 self.worker.post_message(&msg).expect(POST_ERROR);
54 }
55}
56
57impl AsyncWrite for File {
58 fn poll_write(
59 mut self: Pin<&mut Self>,
60 cx: &mut Context<'_>,
61 buf: &[u8],
62 ) -> Poll<Result<usize>> {
63 let task = if let Some(task) = self.write_task.clone() {
64 task
65 } else {
66 let task = Rc::new(RefCell::new(Task {
67 waker: Some(cx.waker().clone()),
68 result: None,
69 }));
70 let task_clone = task.clone();
71 FS.with_borrow(|fs| fs.write(self.fd, buf, self.cursor, task_clone));
72
73 self.write_task = Some(task.clone());
74 task
75 };
76 let mut inner = task.borrow_mut();
77 if let Some(result) = inner.result.take() {
78 self.write_task = None;
79 if let Ok(size) = result {
80 self.size += size as u64;
81 }
82 Poll::Ready(result)
83 } else {
84 Poll::Pending
85 }
86 }
87 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
88 let task = if let Some(task) = self.flush_task.clone() {
89 task
90 } else {
91 let task = Rc::new(RefCell::new(Task {
92 waker: Some(cx.waker().clone()),
93 result: None,
94 }));
95 let task_clone = task.clone();
96 FS.with_borrow(|fs| fs.flush(self.fd, task_clone));
97
98 self.flush_task = Some(task.clone());
99 task
100 };
101 let mut inner = task.borrow_mut();
102 if let Some(result) = inner.result.take() {
103 self.flush_task = None;
104 Poll::Ready(result)
105 } else {
106 Poll::Pending
107 }
108 }
109 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
110 let task = if let Some(task) = self.close_task.clone() {
111 task
112 } else {
113 let task = Rc::new(RefCell::new(Task {
114 waker: Some(cx.waker().clone()),
115 result: None,
116 }));
117 let task_clone = task.clone();
118 FS.with_borrow(|fs| fs.close(self.fd, task_clone));
119
120 self.close_task = Some(task.clone());
121 task
122 };
123 let mut inner = task.borrow_mut();
124 if let Some(result) = inner.result.take() {
125 self.close_task = None;
126 Poll::Ready(result)
127 } else {
128 Poll::Pending
129 }
130 }
131}