#![no_std]
#![allow(missing_docs)]
extern crate alloc;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use wasm_bindgen::prelude::*;
use zerodds_cdr::{BufferReader, BufferWriter, Endianness};
#[wasm_bindgen(start)]
pub fn init() {
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
pub fn version() -> String {
"zerodds-wasm 0.0.0".to_string()
}
#[wasm_bindgen(js_name = endiannessLittle)]
pub fn endianness_little() -> u8 {
0
}
#[wasm_bindgen(js_name = endiannessBig)]
pub fn endianness_big() -> u8 {
1
}
fn endianness_from_u8(value: u8) -> Result<Endianness, JsError> {
match value {
0 => Ok(Endianness::Little),
1 => Ok(Endianness::Big),
other => Err(JsError::new(&format!("invalid endianness {other}"))),
}
}
#[wasm_bindgen]
pub struct CdrEncoder {
inner: BufferWriter,
}
#[wasm_bindgen]
impl CdrEncoder {
#[wasm_bindgen(constructor)]
pub fn new(endianness: u8) -> Result<CdrEncoder, JsError> {
let endian = endianness_from_u8(endianness)?;
Ok(Self {
inner: BufferWriter::new(endian),
})
}
#[wasm_bindgen(js_name = writeU8)]
pub fn write_u8(&mut self, value: u8) -> Result<(), JsError> {
self.inner
.write_u8(value)
.map_err(|e| JsError::new(&format!("write_u8: {e:?}")))
}
#[wasm_bindgen(js_name = writeU16)]
pub fn write_u16(&mut self, value: u16) -> Result<(), JsError> {
self.inner
.write_u16(value)
.map_err(|e| JsError::new(&format!("write_u16: {e:?}")))
}
#[wasm_bindgen(js_name = writeU32)]
pub fn write_u32(&mut self, value: u32) -> Result<(), JsError> {
self.inner
.write_u32(value)
.map_err(|e| JsError::new(&format!("write_u32: {e:?}")))
}
#[wasm_bindgen(js_name = writeU64)]
pub fn write_u64(&mut self, value: u64) -> Result<(), JsError> {
self.inner
.write_u64(value)
.map_err(|e| JsError::new(&format!("write_u64: {e:?}")))
}
#[wasm_bindgen(js_name = writeString)]
pub fn write_string(&mut self, value: &str) -> Result<(), JsError> {
self.inner
.write_string(value)
.map_err(|e| JsError::new(&format!("write_string: {e:?}")))
}
#[wasm_bindgen(js_name = writeBytes)]
pub fn write_bytes(&mut self, data: &[u8]) -> Result<(), JsError> {
self.inner
.write_bytes(data)
.map_err(|e| JsError::new(&format!("write_bytes: {e:?}")))
}
pub fn align(&mut self, alignment: usize) {
self.inner.align(alignment);
}
pub fn position(&self) -> usize {
self.inner.position()
}
pub fn finish(self) -> Vec<u8> {
self.inner.into_bytes()
}
}
#[wasm_bindgen]
pub struct CdrDecoder {
bytes: Vec<u8>,
endianness: Endianness,
position: usize,
}
#[wasm_bindgen]
impl CdrDecoder {
#[wasm_bindgen(constructor)]
pub fn new(bytes: Vec<u8>, endianness: u8) -> Result<CdrDecoder, JsError> {
let endian = endianness_from_u8(endianness)?;
Ok(Self {
bytes,
endianness: endian,
position: 0,
})
}
fn reader(&self) -> BufferReader<'_> {
let mut r = BufferReader::new(&self.bytes, self.endianness);
let _ = r.read_bytes(self.position);
r
}
#[wasm_bindgen(js_name = readU8)]
pub fn read_u8(&mut self) -> Result<u8, JsError> {
let mut r = self.reader();
let v = r
.read_u8()
.map_err(|e| JsError::new(&format!("read_u8: {e:?}")))?;
self.position = r.position();
Ok(v)
}
#[wasm_bindgen(js_name = readU16)]
pub fn read_u16(&mut self) -> Result<u16, JsError> {
let mut r = self.reader();
let v = r
.read_u16()
.map_err(|e| JsError::new(&format!("read_u16: {e:?}")))?;
self.position = r.position();
Ok(v)
}
#[wasm_bindgen(js_name = readU32)]
pub fn read_u32(&mut self) -> Result<u32, JsError> {
let mut r = self.reader();
let v = r
.read_u32()
.map_err(|e| JsError::new(&format!("read_u32: {e:?}")))?;
self.position = r.position();
Ok(v)
}
#[wasm_bindgen(js_name = readU64)]
pub fn read_u64(&mut self) -> Result<u64, JsError> {
let mut r = self.reader();
let v = r
.read_u64()
.map_err(|e| JsError::new(&format!("read_u64: {e:?}")))?;
self.position = r.position();
Ok(v)
}
#[wasm_bindgen(js_name = readString)]
pub fn read_string(&mut self) -> Result<String, JsError> {
let mut r = self.reader();
let v = r
.read_string()
.map_err(|e| JsError::new(&format!("read_string: {e:?}")))?;
self.position = r.position();
Ok(v)
}
pub fn position(&self) -> usize {
self.position
}
pub fn remaining(&self) -> usize {
self.bytes.len().saturating_sub(self.position)
}
}