1#![no_std]
24#![allow(missing_docs)]
29
30extern crate alloc;
31
32use alloc::format;
33use alloc::string::{String, ToString};
34use alloc::vec::Vec;
35use wasm_bindgen::prelude::*;
36use zerodds_cdr::{BufferReader, BufferWriter, Endianness};
37
38#[wasm_bindgen(start)]
39pub fn init() {
40 #[cfg(feature = "console_error_panic_hook")]
41 console_error_panic_hook::set_once();
42}
43
44#[wasm_bindgen]
45pub fn version() -> String {
46 "zerodds-wasm 0.0.0".to_string()
47}
48
49#[wasm_bindgen(js_name = endiannessLittle)]
51pub fn endianness_little() -> u8 {
52 0
53}
54#[wasm_bindgen(js_name = endiannessBig)]
55pub fn endianness_big() -> u8 {
56 1
57}
58
59fn endianness_from_u8(value: u8) -> Result<Endianness, JsError> {
60 match value {
61 0 => Ok(Endianness::Little),
62 1 => Ok(Endianness::Big),
63 other => Err(JsError::new(&format!("invalid endianness {other}"))),
64 }
65}
66
67#[wasm_bindgen]
69pub struct CdrEncoder {
70 inner: BufferWriter,
71}
72
73#[wasm_bindgen]
74impl CdrEncoder {
75 #[wasm_bindgen(constructor)]
76 pub fn new(endianness: u8) -> Result<CdrEncoder, JsError> {
77 let endian = endianness_from_u8(endianness)?;
78 Ok(Self {
79 inner: BufferWriter::new(endian),
80 })
81 }
82
83 #[wasm_bindgen(js_name = writeU8)]
84 pub fn write_u8(&mut self, value: u8) -> Result<(), JsError> {
85 self.inner
86 .write_u8(value)
87 .map_err(|e| JsError::new(&format!("write_u8: {e:?}")))
88 }
89
90 #[wasm_bindgen(js_name = writeU16)]
91 pub fn write_u16(&mut self, value: u16) -> Result<(), JsError> {
92 self.inner
93 .write_u16(value)
94 .map_err(|e| JsError::new(&format!("write_u16: {e:?}")))
95 }
96
97 #[wasm_bindgen(js_name = writeU32)]
98 pub fn write_u32(&mut self, value: u32) -> Result<(), JsError> {
99 self.inner
100 .write_u32(value)
101 .map_err(|e| JsError::new(&format!("write_u32: {e:?}")))
102 }
103
104 #[wasm_bindgen(js_name = writeU64)]
105 pub fn write_u64(&mut self, value: u64) -> Result<(), JsError> {
106 self.inner
107 .write_u64(value)
108 .map_err(|e| JsError::new(&format!("write_u64: {e:?}")))
109 }
110
111 #[wasm_bindgen(js_name = writeString)]
112 pub fn write_string(&mut self, value: &str) -> Result<(), JsError> {
113 self.inner
114 .write_string(value)
115 .map_err(|e| JsError::new(&format!("write_string: {e:?}")))
116 }
117
118 #[wasm_bindgen(js_name = writeBytes)]
119 pub fn write_bytes(&mut self, data: &[u8]) -> Result<(), JsError> {
120 self.inner
121 .write_bytes(data)
122 .map_err(|e| JsError::new(&format!("write_bytes: {e:?}")))
123 }
124
125 pub fn align(&mut self, alignment: usize) {
126 self.inner.align(alignment);
127 }
128
129 pub fn position(&self) -> usize {
130 self.inner.position()
131 }
132
133 pub fn finish(self) -> Vec<u8> {
136 self.inner.into_bytes()
137 }
138}
139
140#[wasm_bindgen]
142pub struct CdrDecoder {
143 bytes: Vec<u8>,
144 endianness: Endianness,
145 position: usize,
146}
147
148#[wasm_bindgen]
149impl CdrDecoder {
150 #[wasm_bindgen(constructor)]
151 pub fn new(bytes: Vec<u8>, endianness: u8) -> Result<CdrDecoder, JsError> {
152 let endian = endianness_from_u8(endianness)?;
153 Ok(Self {
154 bytes,
155 endianness: endian,
156 position: 0,
157 })
158 }
159
160 fn reader(&self) -> BufferReader<'_> {
161 let mut r = BufferReader::new(&self.bytes, self.endianness);
162 let _ = r.read_bytes(self.position);
165 r
166 }
167
168 #[wasm_bindgen(js_name = readU8)]
169 pub fn read_u8(&mut self) -> Result<u8, JsError> {
170 let mut r = self.reader();
171 let v = r
172 .read_u8()
173 .map_err(|e| JsError::new(&format!("read_u8: {e:?}")))?;
174 self.position = r.position();
175 Ok(v)
176 }
177
178 #[wasm_bindgen(js_name = readU16)]
179 pub fn read_u16(&mut self) -> Result<u16, JsError> {
180 let mut r = self.reader();
181 let v = r
182 .read_u16()
183 .map_err(|e| JsError::new(&format!("read_u16: {e:?}")))?;
184 self.position = r.position();
185 Ok(v)
186 }
187
188 #[wasm_bindgen(js_name = readU32)]
189 pub fn read_u32(&mut self) -> Result<u32, JsError> {
190 let mut r = self.reader();
191 let v = r
192 .read_u32()
193 .map_err(|e| JsError::new(&format!("read_u32: {e:?}")))?;
194 self.position = r.position();
195 Ok(v)
196 }
197
198 #[wasm_bindgen(js_name = readU64)]
199 pub fn read_u64(&mut self) -> Result<u64, JsError> {
200 let mut r = self.reader();
201 let v = r
202 .read_u64()
203 .map_err(|e| JsError::new(&format!("read_u64: {e:?}")))?;
204 self.position = r.position();
205 Ok(v)
206 }
207
208 #[wasm_bindgen(js_name = readString)]
209 pub fn read_string(&mut self) -> Result<String, JsError> {
210 let mut r = self.reader();
211 let v = r
212 .read_string()
213 .map_err(|e| JsError::new(&format!("read_string: {e:?}")))?;
214 self.position = r.position();
215 Ok(v)
216 }
217
218 pub fn position(&self) -> usize {
219 self.position
220 }
221
222 pub fn remaining(&self) -> usize {
223 self.bytes.len().saturating_sub(self.position)
224 }
225}