use super::*;
use intercom::raw::BSTR;
use std::os::raw;
#[crate::com_class(IAllocator)]
#[derive(Default)]
pub struct Allocator;
#[crate::com_interface(
com_iid = "18EE22B3-B0C6-44A5-A94A-7A417676FB66",
raw_iid = "7A6F6564-04B5-4455-A223-EA0512B8CC63"
)]
pub trait IAllocator: crate::IUnknown
{
unsafe fn alloc_bstr(&self, text: *const u16, len: u32) -> BSTR;
unsafe fn free_bstr(&self, bstr: BSTR);
unsafe fn alloc(&self, len: usize) -> *mut raw::c_void;
unsafe fn free(&self, ptr: *mut raw::c_void);
}
impl IAllocator for Allocator
{
unsafe fn alloc_bstr(&self, text: *const u16, len: u32) -> BSTR
{
BSTR(os::alloc_bstr(text, len))
}
unsafe fn free_bstr(&self, bstr: BSTR)
{
os::free_bstr(bstr.0)
}
unsafe fn alloc(&self, len: usize) -> *mut raw::c_void
{
os::alloc(len)
}
unsafe fn free(&self, ptr: *mut raw::c_void)
{
os::free(ptr)
}
}
pub unsafe fn allocate(len: usize) -> *mut raw::c_void
{
os::alloc(len)
}
pub unsafe fn free(ptr: *mut raw::c_void)
{
os::free(ptr)
}
#[cfg(windows)]
mod os
{
use std::os::raw;
pub unsafe fn alloc_bstr(psz: *const u16, len: u32) -> *mut u16
{
SysAllocStringLen(psz, len)
}
pub unsafe fn free_bstr(bstr: *mut u16)
{
SysFreeString(bstr)
}
pub unsafe fn alloc(len: usize) -> *mut raw::c_void
{
CoTaskMemAlloc(len)
}
pub unsafe fn free(ptr: *mut raw::c_void)
{
CoTaskMemFree(ptr)
}
#[link(name = "oleaut32")]
extern "system" {
pub fn SysAllocStringLen(psz: *const u16, len: u32) -> *mut u16;
pub fn SysFreeString(bstr: *mut u16);
}
#[link(name = "ole32")]
extern "system" {
pub fn CoTaskMemAlloc(len: usize) -> *mut raw::c_void;
pub fn CoTaskMemFree(ptr: *mut raw::c_void);
}
}
#[cfg(not(windows))]
mod os
{
use std::os::raw;
pub unsafe fn alloc_bstr(psz: *const u16, len: u32) -> *mut u16
{
let text_size: usize = (len * 2) as usize;
let ptr = libc::malloc(text_size + 6);
let text_data = (ptr as usize + 4) as *mut u16;
*(ptr as *mut u32) = text_size as u32;
libc::memcpy(text_data as *mut _, psz as *mut _, text_size);
*((text_data as usize + text_size) as *mut _) = 0u16;
text_data
}
pub unsafe fn free_bstr(bstr: *mut u16)
{
if bstr.is_null() {
return;
}
let ptr = (bstr as usize - 4) as *mut _;
libc::free(ptr)
}
pub unsafe fn alloc(len: usize) -> *mut raw::c_void
{
libc::malloc(len) as *mut _
}
pub unsafe fn free(ptr: *mut raw::c_void)
{
libc::free(ptr as *mut _)
}
}