106 lines
2.5 KiB
Rust
106 lines
2.5 KiB
Rust
use libc::{c_void, c_int};
|
|
use std::old_io::{EndOfFile, IoResult, IoError, OtherIoError};
|
|
use std::old_io::{Reader, Writer};
|
|
use std::ptr;
|
|
|
|
use ffi;
|
|
use ssl::error::{SslError};
|
|
|
|
pub struct MemBio {
|
|
bio: *mut ffi::BIO,
|
|
owned: bool
|
|
}
|
|
|
|
impl Drop for MemBio {
|
|
fn drop(&mut self) {
|
|
if self.owned {
|
|
unsafe {
|
|
ffi::BIO_free_all(self.bio);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl MemBio {
|
|
/// Creates a new owned memory based BIO
|
|
pub fn new() -> Result<MemBio, SslError> {
|
|
ffi::init();
|
|
|
|
let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) };
|
|
try_ssl_null!(bio);
|
|
|
|
Ok(MemBio {
|
|
bio: bio,
|
|
owned: true
|
|
})
|
|
}
|
|
|
|
/// Returns a "borrow", i.e. it has no ownership
|
|
pub fn borrowed(bio: *mut ffi::BIO) -> MemBio {
|
|
MemBio {
|
|
bio: bio,
|
|
owned: false
|
|
}
|
|
}
|
|
|
|
/// Consumes current bio and returns wrapped value
|
|
/// Note that data ownership is lost and
|
|
/// should be managed manually
|
|
pub unsafe fn unwrap(mut self) -> *mut ffi::BIO {
|
|
self.owned = false;
|
|
self.bio
|
|
}
|
|
|
|
/// Temporarily gets wrapped value
|
|
pub unsafe fn get_handle(&self) -> *mut ffi::BIO {
|
|
self.bio
|
|
}
|
|
}
|
|
|
|
impl Reader for MemBio {
|
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
|
let ret = unsafe {
|
|
ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void,
|
|
buf.len() as c_int)
|
|
};
|
|
|
|
if ret <= 0 {
|
|
let is_eof = unsafe { ffi::BIO_eof(self.bio) };
|
|
let err = if is_eof {
|
|
IoError {
|
|
kind: EndOfFile,
|
|
desc: "MemBio EOF",
|
|
detail: None
|
|
}
|
|
} else {
|
|
IoError {
|
|
kind: OtherIoError,
|
|
desc: "MemBio read error",
|
|
detail: Some(format!("{:?}", SslError::get()))
|
|
}
|
|
};
|
|
Err(err)
|
|
} else {
|
|
Ok(ret as usize)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Writer for MemBio {
|
|
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
|
let ret = unsafe {
|
|
ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void,
|
|
buf.len() as c_int)
|
|
};
|
|
if buf.len() != ret as usize {
|
|
Err(IoError {
|
|
kind: OtherIoError,
|
|
desc: "MemBio write error",
|
|
detail: Some(format!("{:?}", SslError::get()))
|
|
})
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|