extern crate alloc;
use super::IIterator;
use alloc::vec::Vec;
fn block<T: windows_core::RuntimeType>() -> usize {
(2048 / size_of::<T::Default>()).clamp(1, 128)
}
pub struct BufferedIterator<T: windows_core::RuntimeType + 'static> {
iterator: IIterator<T>,
buffer: Vec<T::Default>,
index: usize,
len: usize,
}
impl<T: windows_core::RuntimeType + 'static> BufferedIterator<T> {
pub fn new(iterator: IIterator<T>) -> Self {
let mut buffer = Vec::new();
buffer.resize_with(block::<T>(), || unsafe { core::mem::zeroed() });
Self {
iterator,
buffer,
index: 0,
len: 0,
}
}
}
impl<T: windows_core::RuntimeType + 'static> Iterator for BufferedIterator<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.len {
self.index = 0;
self.len = self.iterator.GetMany(&mut self.buffer).unwrap_or(0) as usize;
self.len = self.len.min(self.buffer.len());
if self.len == 0 {
return None;
}
}
let slot = core::mem::replace(&mut self.buffer[self.index], unsafe { core::mem::zeroed() });
self.index += 1;
T::from_default_owned(slot).ok()
}
}