use crate::PdfData;
use crate::object::ObjectIdentifier;
use crate::object::Stream;
use crate::reader::ReaderContext;
use crate::util::SegmentList;
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};
use std::sync::Mutex;
pub(crate) struct Data {
data: PdfData,
decoded: SegmentList<Option<Vec<u8>>, 32>,
map: Mutex<HashMap<ObjectIdentifier, usize>>,
}
impl Debug for Data {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Data {{ ... }}")
}
}
impl Data {
pub fn new(data: PdfData) -> Self {
Self {
data,
decoded: SegmentList::new(),
map: Mutex::new(HashMap::new()),
}
}
pub(crate) fn get(&self) -> &[u8] {
self.data.as_ref().as_ref()
}
pub(crate) fn get_with(&self, id: ObjectIdentifier, ctx: &ReaderContext) -> Option<&[u8]> {
if let Some(&idx) = self.map.lock().unwrap().get(&id) {
self.decoded.get(idx)?.as_deref()
} else {
let idx = {
let mut locked = self.map.lock().unwrap();
let idx = locked.len();
locked.insert(id, idx);
idx
};
self.decoded
.get_or_init(idx, || {
let stream = ctx.xref.get_with::<Stream>(id, ctx)?;
stream.decoded().ok()
})
.as_deref()
}
}
}