use napi_derive::napi;
use napi::bindgen_prelude::*;
use napi::{ Result, Status::GenericFailure };
#[napi]
#[derive(Clone)]
pub struct BinaryStream {
pub binary: Vec<u8>,
pub offset: u32,
}
#[napi]
impl BinaryStream {
#[napi(constructor)]
pub fn new(buffer: Option<Buffer>, offset: Option<u32>) -> Self {
let bin = match buffer {
Some(buffer) => buffer,
None => Buffer::from(vec![]),
};
let offset = match offset {
Some(offset) => offset,
None => 0,
};
BinaryStream {
binary: bin.to_vec(),
offset,
}
}
#[napi(factory)]
pub fn from(binary: Vec<u8>, offset: Option<u32>) -> Self {
let offset = match offset {
Some(offset) => offset,
None => 0,
};
BinaryStream {
binary,
offset,
}
}
#[napi(factory)]
pub fn from_buffer(buffer: Buffer, offset: Option<u32>) -> Self {
let offset = match offset {
Some(offset) => offset,
None => 0,
};
BinaryStream {
binary: buffer.to_vec(),
offset,
}
}
#[napi]
pub fn read(&mut self, length: u32) -> Result<Vec<u8>> {
if length > self.binary.len() as u32 {
return Err(
Error::new(
GenericFailure,
"Length is greater than the remaining bytes.".to_string()
)
)
}
if self.offset + length > self.binary.len() as u32 {
return Err(
Error::new(
GenericFailure,
"Offset is out of bounds.".to_string()
)
)
}
let start = self.offset as usize;
let end = (self.offset + length) as usize;
self.offset += length;
Ok(self.binary[start..end].to_vec())
}
#[napi]
pub fn read_buffer(&mut self, length: u32) -> Result<Buffer> {
let bytes = match self.read(length) {
Ok(bytes) => bytes,
Err(err) => return Err(err)
};
Ok(Buffer::from(bytes))
}
#[napi]
pub fn write(&mut self, data: Vec<u8>) {
self.binary.extend(data);
}
#[napi]
pub fn write_buffer(&mut self, data: Buffer) {
self.binary.extend(data.to_vec());
}
#[napi]
pub fn read_remaining(&mut self) -> Vec<u8> {
let start = self.offset as usize;
let end = self.binary.len();
self.offset = end as u32;
self.binary[start..end].to_vec()
}
#[napi]
pub fn read_remaining_buffer(&mut self) -> Buffer {
let bytes = self.read_remaining();
Buffer::from(bytes)
}
#[napi]
pub fn skip(&mut self, length: u32) {
self.offset += length;
}
#[napi]
pub fn cursor_at_end(&self) -> bool {
self.offset == self.binary.len() as u32
}
#[napi]
pub fn cursor_at_start(&self) -> bool {
self.offset == 0
}
#[napi]
pub fn get_buffer(&self) -> Buffer {
Buffer::from(self.binary.clone())
}
}
impl FromNapiValue for BinaryStream {
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
let offset = 0;
let buffer = Buffer::from_napi_value(env, napi_val)?;
let binary = buffer.to_vec();
Ok(BinaryStream {
binary,
offset,
})
}
}