Created
November 11, 2018 00:16
-
-
Save Connicpu/7d423cac145f98cb354b8278efd2a1df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use com_impl::{Refcount, VTable}; | |
use winapi::ctypes::c_void; | |
use winapi::shared::winerror::{ERROR_INVALID_INDEX, HRESULT, HRESULT_FROM_WIN32, S_OK}; | |
use winapi::um::dwrite::{IDWriteFontFileStream, IDWriteFontFileStreamVtbl}; | |
use wio::com::ComPtr; | |
#[repr(C)] | |
#[derive(ComImpl)] | |
pub struct FileStream { | |
vtbl: VTable<IDWriteFontFileStreamVtbl>, | |
refcount: Refcount, | |
write_time: u64, | |
file_data: Vec<u8>, | |
} | |
impl FileStream { | |
// Todo: Use a wrapper type for the ComPtr | |
pub fn new(write_time: u64, data: Vec<u8>) -> ComPtr<IDWriteFontFileStream> { | |
let ptr = FileStream::create_raw(write_time, data); | |
let ptr = ptr as *mut IDWriteFontFileStream; | |
unsafe { ComPtr::from_raw(ptr) } | |
} | |
} | |
#[com_impl] | |
unsafe impl IDWriteFontFileStream for FileStream { | |
unsafe fn get_file_size(&self, size: *mut u64) -> HRESULT { | |
*size = self.file_data.len() as u64; | |
S_OK | |
} | |
unsafe fn get_last_write_time(&self, write_time: *mut u64) -> HRESULT { | |
*write_time = self.write_time; | |
S_OK | |
} | |
unsafe fn read_file_fragment( | |
&self, | |
start: *mut *const c_void, | |
offset: u64, | |
size: u64, | |
ctx: *mut *mut c_void, | |
) -> HRESULT { | |
if offset > std::isize::MAX as u64 || size > std::isize::MAX as u64 { | |
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); | |
} | |
let offset = offset as usize; | |
let size = size as usize; | |
if offset + size > self.file_data.len() { | |
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); | |
} | |
*start = self.file_data.as_ptr().offset(offset as isize) as *const c_void; | |
*ctx = std::ptr::null_mut(); | |
S_OK | |
} | |
unsafe fn release_file_fragment(&self, _ctx: *mut c_void) { | |
// Nothing to do | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub mod file_stream { | |
use com_impl::{Refcount, VTable}; | |
use winapi::ctypes::c_void; | |
use winapi::shared::winerror::{ERROR_INVALID_INDEX, HRESULT, HRESULT_FROM_WIN32, S_OK}; | |
use winapi::um::dwrite::{IDWriteFontFileStream, IDWriteFontFileStreamVtbl}; | |
use wio::com::ComPtr; | |
#[repr(C)] | |
pub struct FileStream { | |
vtbl: VTable<IDWriteFontFileStreamVtbl>, | |
refcount: Refcount, | |
write_time: u64, | |
file_data: Vec<u8>, | |
} | |
impl FileStream { | |
fn create_raw(write_time: u64, file_data: Vec<u8>) -> *mut Self { | |
Box::into_raw(Box::new(FileStream { | |
vtbl: <Self as com_impl::BuildVTable<_>>::static_vtable(), | |
refcount: Default::default(), | |
write_time: write_time, | |
file_data: file_data, | |
})) | |
} | |
} | |
unsafe impl com_impl::BuildVTable<winapi::um::unknwnbase::IUnknownVtbl> for FileStream { | |
const VTBL: winapi::um::unknwnbase::IUnknownVtbl = winapi::um::unknwnbase::IUnknownVtbl { | |
AddRef: Self::__com_impl__IUnknown__AddRef, | |
Release: Self::__com_impl__IUnknown__Release, | |
QueryInterface: Self::__com_impl__IUnknown__QueryInterface, | |
}; | |
fn static_vtable() -> com_impl::VTable<winapi::um::unknwnbase::IUnknownVtbl> { | |
com_impl::VTable::new(&Self::VTBL) | |
} | |
} | |
#[allow(non_snake_case)] | |
impl FileStream { | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl__IUnknown__AddRef( | |
this: *mut winapi::um::unknwnbase::IUnknown, | |
) -> u32 { | |
let this = &*(this as *const Self); | |
this.refcount.add_ref() | |
} | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl__IUnknown__Release( | |
this: *mut winapi::um::unknwnbase::IUnknown, | |
) -> u32 { | |
let ptr = this as *mut Self; | |
let count = (*ptr).refcount.release(); | |
if count == 0 { | |
Box::from_raw(ptr); | |
} | |
count | |
} | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl__IUnknown__QueryInterface( | |
this: *mut winapi::um::unknwnbase::IUnknown, | |
riid: *const winapi::shared::guiddef::IID, | |
ppv: *mut *mut winapi::ctypes::c_void, | |
) -> winapi::shared::winerror::HRESULT { | |
if ppv.is_null() { | |
return winapi::shared::winerror::E_POINTER; | |
} | |
if winapi::shared::guiddef::IsEqualIID( | |
&*riid, | |
&<winapi::um::unknwnbase::IUnknown as winapi::Interface>::uuidof(), | |
) || winapi::shared::guiddef::IsEqualIID( | |
&*riid, | |
&<IDWriteFontFileStream as winapi::Interface>::uuidof(), | |
) { | |
*ppv = this as *mut winapi::ctypes::c_void; | |
winapi::shared::winerror::S_OK | |
} else { | |
*ppv = std::ptr::null_mut(); | |
winapi::shared::winerror::E_NOINTERFACE | |
} | |
} | |
} | |
impl FileStream { | |
pub fn new(write_time: u64, data: Vec<u8>) -> ComPtr<IDWriteFontFileStream> { | |
let ptr = FileStream::create_raw(write_time, data); | |
let ptr = ptr as *mut IDWriteFontFileStream; | |
unsafe { ComPtr::from_raw(ptr) } | |
} | |
} | |
unsafe impl com_impl::BuildVTable<IDWriteFontFileStreamVtbl> for FileStream { | |
const VTBL: IDWriteFontFileStreamVtbl = IDWriteFontFileStreamVtbl { | |
parent: <Self as com_impl::BuildVTable<_>>::VTBL, | |
GetFileSize: Self::__com_impl_stub__IDWriteFontFileStream__GetFileSize, | |
GetLastWriteTime: Self::__com_impl_stub__IDWriteFontFileStream__GetLastWriteTime, | |
ReadFileFragment: Self::__com_impl_stub__IDWriteFontFileStream__ReadFileFragment, | |
ReleaseFileFragment: Self::__com_impl_stub__IDWriteFontFileStream__ReleaseFileFragment, | |
}; | |
fn static_vtable() -> com_impl::VTable<IDWriteFontFileStreamVtbl> { | |
com_impl::VTable::new(&Self::VTBL) | |
} | |
} | |
#[allow(non_snake_case)] | |
impl FileStream { | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl_stub__IDWriteFontFileStream__GetFileSize( | |
this: *mut IDWriteFontFileStream, | |
__com_arg_0: *mut u64, | |
) -> HRESULT { | |
let this = &*(this as *const Self); | |
Self::__com_impl_body__IDWriteFontFileStream__GetFileSize(this, __com_arg_0) | |
} | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl_stub__IDWriteFontFileStream__GetLastWriteTime( | |
this: *mut IDWriteFontFileStream, | |
__com_arg_0: *mut u64, | |
) -> HRESULT { | |
let this = &*(this as *const Self); | |
Self::__com_impl_body__IDWriteFontFileStream__GetLastWriteTime(this, __com_arg_0) | |
} | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl_stub__IDWriteFontFileStream__ReadFileFragment( | |
this: *mut IDWriteFontFileStream, | |
__com_arg_0: *mut *const c_void, | |
__com_arg_1: u64, | |
__com_arg_2: u64, | |
__com_arg_3: *mut *mut c_void, | |
) -> HRESULT { | |
let this = &*(this as *const Self); | |
Self::__com_impl_body__IDWriteFontFileStream__ReadFileFragment( | |
this, | |
__com_arg_0, | |
__com_arg_1, | |
__com_arg_2, | |
__com_arg_3, | |
) | |
} | |
#[inline(never)] | |
unsafe extern "system" fn __com_impl_stub__IDWriteFontFileStream__ReleaseFileFragment( | |
this: *mut IDWriteFontFileStream, | |
__com_arg_0: *mut c_void, | |
) { | |
let this = &*(this as *const Self); | |
Self::__com_impl_body__IDWriteFontFileStream__ReleaseFileFragment(this, __com_arg_0) | |
} | |
#[inline(always)] | |
unsafe extern "system" fn __com_impl_body__IDWriteFontFileStream__GetFileSize( | |
&self, | |
size: *mut u64, | |
) -> HRESULT { | |
*size = self.file_data.len() as u64; | |
S_OK | |
} | |
#[inline(always)] | |
unsafe extern "system" fn __com_impl_body__IDWriteFontFileStream__GetLastWriteTime( | |
&self, | |
write_time: *mut u64, | |
) -> HRESULT { | |
*write_time = self.write_time; | |
S_OK | |
} | |
#[inline(always)] | |
unsafe extern "system" fn __com_impl_body__IDWriteFontFileStream__ReadFileFragment( | |
&self, | |
start: *mut *const c_void, | |
offset: u64, | |
size: u64, | |
ctx: *mut *mut c_void, | |
) -> HRESULT { | |
if offset > std::isize::MAX as u64 || size > std::isize::MAX as u64 { | |
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); | |
} | |
let offset = offset as usize; | |
let size = size as usize; | |
if offset + size > self.file_data.len() { | |
return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX); | |
} | |
*start = self.file_data.as_ptr().offset(offset as isize) as *const c_void; | |
*ctx = std::ptr::null_mut(); | |
S_OK | |
} | |
#[inline(always)] | |
unsafe extern "system" fn __com_impl_body__IDWriteFontFileStream__ReleaseFileFragment( | |
&self, | |
_ctx: *mut c_void, | |
) { | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment