From 692088fac1a880263491b105ceb4b242402a6d6b Mon Sep 17 00:00:00 2001 From: Fabian Freyer Date: Thu, 10 Feb 2022 23:09:38 +0100 Subject: rust: Add BinaryReader and BinaryWriter --- rust/src/binaryreader.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 rust/src/binaryreader.rs (limited to 'rust/src/binaryreader.rs') diff --git a/rust/src/binaryreader.rs b/rust/src/binaryreader.rs new file mode 100644 index 00000000..c92b9e50 --- /dev/null +++ b/rust/src/binaryreader.rs @@ -0,0 +1,85 @@ +use binaryninjacore_sys::*; + +use crate::binaryview::BinaryView; +use crate::Endianness; + +use std::io::{Read, Seek, SeekFrom}; + +pub struct BinaryReader { + handle: *mut BNBinaryReader, +} + +impl BinaryReader { + pub fn new(view: &BinaryView, endian: Endianness) -> Self { + let handle = unsafe { BNCreateBinaryReader(view.handle) }; + unsafe { + BNSetBinaryReaderEndianness(handle, endian); + } + Self { handle } + } + + pub fn endian(&self) -> Endianness { + unsafe { BNGetBinaryReaderEndianness(self.handle) } + } + + pub fn set_endian(&self, endian: Endianness) { + unsafe { BNSetBinaryReaderEndianness(self.handle, endian) } + } + + pub fn offset(&self) -> u64 { + unsafe { BNGetReaderPosition(self.handle) } + } + + pub fn eof(&self) -> bool { + unsafe { BNIsEndOfFile(self.handle) } + } +} + +impl Seek for BinaryReader { + /// Seek to the specified position. + /// + /// # Errors + /// Seeking relative to [SeekFrom::End] is unsupported and will return an error. + fn seek(&mut self, pos: SeekFrom) -> std::io::Result { + unsafe { + match pos { + SeekFrom::Current(offset) => BNSeekBinaryReaderRelative(self.handle, offset), + SeekFrom::Start(offset) => BNSeekBinaryReader(self.handle, offset), + _ => { + return Err(std::io::Error::new( + std::io::ErrorKind::Unsupported, + "Cannot seek end of BinaryReader", + )) + } + }; + } + + Ok(self.offset()) + } +} + +impl Read for BinaryReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let len = buf.len(); + + let result = unsafe { BNReadData(self.handle, buf.as_mut_ptr() as *mut _, len) }; + + if !result { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Read out of bounds", + )) + } else { + Ok(len) + } + } +} + +impl Drop for BinaryReader { + fn drop(&mut self) { + unsafe { BNFreeBinaryReader(self.handle) } + } +} + +unsafe impl Sync for BinaryReader {} +unsafe impl Send for BinaryReader {} -- cgit v1.3.1