1use std::io::{self, Write};
4
5use chrono::{DateTime, Local};
6
7use crate::{common::{Dict, ObjRef, PdfString}, low, util::ByteCounter};
8
9#[must_use]
11pub struct PdfDict<'a, 'b> {
12 first: bool,
13 f: &'b mut Formatter<'a>,
14}
15
16impl<'a, 'b> PdfDict<'a, 'b> {
17 fn check_first(&mut self) -> io::Result<()> {
18 if self.first {
19 if self.f.indent > 0 {
20 writeln!(self.f.inner)?;
21 }
22 self.f.indent()?;
23 writeln!(self.f.inner, "<<")?;
24 self.first = false;
25 }
26 Ok(())
27 }
28
29 pub fn field(&mut self, name: &str, value: &dyn Serialize) -> io::Result<&mut Self> {
31 self.check_first()?;
32 self.f.indent += 2;
33 self.f.indent()?;
34 self.f.needs_space = write_name(name, &mut self.f.inner)?;
35 value.write(&mut self.f)?;
36 writeln!(self.f.inner)?;
37 self.f.indent -= 2;
38 Ok(self)
39 }
40
41 pub fn opt_field<X: Serialize>(
43 &mut self,
44 name: &str,
45 field: &Option<X>,
46 ) -> io::Result<&mut Self> {
47 if let Some(value) = field {
48 self.field(name, value)
49 } else {
50 Ok(self)
51 }
52 }
53
54 pub fn dict_field<X: Serialize>(
56 &mut self,
57 name: &str,
58 dict: &Dict<X>,
59 ) -> io::Result<&mut Self> {
60 if dict.is_empty() {
61 Ok(self)
62 } else {
63 self.field(name, dict)
64 }
65 }
66
67 pub fn dict_res_field<X: Serialize>(
69 &mut self,
70 name: &str,
71 res: &low::Resource<Dict<X>>,
72 ) -> io::Result<&mut Self> {
73 match res {
74 low::Resource::Ref(r) => self.field(name, r),
75 low::Resource::Immediate(dict) => self.dict_field(name, dict),
76 }
77 }
78
79 pub fn arr_field<X: Serialize>(&mut self, name: &str, array: &[X]) -> io::Result<&mut Self> {
81 self.check_first()?;
82 self.f.indent += 2;
83 self.f.indent()?;
84 write_name(name, &mut self.f.inner)?;
85
86 self.f.pdf_arr().entries(array)?.finish()?;
87
88 writeln!(self.f.inner)?;
89 self.f.indent -= 2;
90 Ok(self)
91 }
92
93 pub fn finish(&mut self) -> io::Result<()> {
95 if self.first {
96 write!(self.f.inner, "<< >>")?;
97 self.f.needs_space = false;
98 } else {
99 self.f.indent()?;
100 write!(self.f.inner, ">>")?;
101 if self.f.indent == 0 {
102 writeln!(self.f.inner)?;
103 }
104 }
105 Ok(())
106 }
107}
108
109#[must_use]
111pub struct PdfArr<'a, 'b> {
112 first: bool,
113 f: &'b mut Formatter<'a>,
114}
115
116impl<'a, 'b> PdfArr<'a, 'b> {
117 fn check_first(&mut self) -> io::Result<()> {
118 if self.first {
119 write!(self.f.inner, "[")?;
120 self.first = false;
121 self.f.needs_space = false;
122 }
123 Ok(())
124 }
125
126 pub fn entry(&mut self, value: &dyn Serialize) -> io::Result<&mut Self> {
128 self.check_first()?;
129 value.write(&mut self.f)?;
130 Ok(self)
131 }
132
133 pub fn entries<X: Serialize>(
135 &mut self,
136 i: impl IntoIterator<Item = X>,
137 ) -> io::Result<&mut Self> {
138 for entry in i.into_iter() {
139 self.entry(&entry)?;
140 }
141 Ok(self)
142 }
143
144 pub fn finish(&mut self) -> io::Result<()> {
146 if self.first {
147 write!(self.f.inner, "[]")?;
148 } else {
149 write!(self.f.inner, "]")?;
150 }
151 Ok(())
152 }
153}
154
155pub struct Formatter<'a> {
157 pub(super) inner: ByteCounter<&'a mut dyn Write>,
158 indent: usize,
159 needs_space: bool,
160 pub(super) xref: Vec<Option<(usize, u16, bool)>>,
161}
162
163impl<'a> Formatter<'a> {
164 pub fn new(w: &'a mut dyn Write) -> Self {
166 Self {
167 inner: ByteCounter::new(w),
168 indent: 0,
169 needs_space: false,
170 xref: vec![Some((0, 65535, true))],
171 }
172 }
173
174 pub fn pdf_dict(&mut self) -> PdfDict<'a, '_> {
176 PdfDict {
177 first: true,
178 f: self,
179 }
180 }
181
182 pub fn pdf_arr(&mut self) -> PdfArr<'a, '_> {
184 PdfArr {
185 first: true,
186 f: self,
187 }
188 }
189
190 pub fn pdf_stream(&mut self, data: &[u8]) -> io::Result<()> {
192 writeln!(self.inner, "stream")?;
193 self.inner.write_all(data)?;
194 writeln!(self.inner, "endstream")?;
195 Ok(())
196 }
197
198 pub fn obj(&mut self, r#ref: ObjRef, obj: &dyn Serialize) -> io::Result<()> {
200 let offset = self.inner.bytes_written();
201 writeln!(self.inner, "{} {} obj", r#ref.id, r#ref.gen)?;
202 obj.write(self)?;
203 writeln!(self.inner, "endobj")?;
204
205 while self.xref.len() <= (r#ref.id as usize) {
206 self.xref.push(None);
207 }
208 self.xref[r#ref.id as usize] = Some((offset, r#ref.gen, false));
209 Ok(())
210 }
211
212 pub fn xref(&mut self) -> io::Result<usize> {
214 let offset = self.inner.bytes_written();
215 writeln!(self.inner, "xref")?;
216
217 let mut rest = &self.xref[..];
218 let mut index = 0;
219 while let Some(pos) = rest.iter().position(Option::is_some) {
220 rest = &rest[pos..];
221 index += pos;
222 let mid = rest.iter().position(Option::is_none).unwrap_or(rest.len());
223 let (a, b) = rest.split_at(mid);
224
225 writeln!(self.inner, "{} {}", index, mid)?;
226 for elem in a {
227 let (offset, gen, free) = elem.unwrap();
228 let mark = if free { 'f' } else { 'n' };
229 writeln!(self.inner, "{:010} {:05} {} ", offset, gen, mark)?;
231 }
232
233 rest = b;
234 index += mid;
235 }
236
237 Ok(offset)
238 }
239
240 fn indent(&mut self) -> io::Result<()> {
241 write!(self.inner, "{:indent$}", "", indent = self.indent)?;
242 Ok(())
243 }
244}
245
246pub trait Serialize {
248 fn write(&self, f: &mut Formatter) -> io::Result<()>;
250}
251
252impl<X: Serialize> Serialize for &'_ X {
253 fn write(&self, f: &mut Formatter) -> io::Result<()> {
254 (*self).write(f)
255 }
256}
257
258impl Serialize for PdfString {
259 fn write(&self, f: &mut Formatter) -> io::Result<()> {
260 f.needs_space = write_string(self.as_bytes(), &mut f.inner)?;
261 Ok(())
262 }
263}
264
265macro_rules! serialize_display_impl {
266 ($ty:ty) => {
267 impl Serialize for $ty {
268 fn write(&self, f: &mut Formatter) -> io::Result<()> {
269 if f.needs_space {
270 write!(f.inner, " ")?;
271 }
272 write!(f.inner, "{}", self)?;
273 f.needs_space = true;
274 Ok(())
275 }
276 }
277 };
278}
279
280serialize_display_impl!(u8);
281serialize_display_impl!(usize);
282serialize_display_impl!(u32);
283serialize_display_impl!(i32);
284serialize_display_impl!(f32);
285
286impl<X: Serialize> Serialize for Vec<X> {
287 fn write(&self, f: &mut Formatter) -> io::Result<()> {
288 write!(f.inner, "[")?;
289 f.needs_space = false;
290 for elem in self {
291 elem.write(f)?;
292 }
293 write!(f.inner, "]")?;
294 Ok(())
295 }
296}
297
298impl<X: Serialize> Serialize for [X] {
299 fn write(&self, f: &mut Formatter) -> io::Result<()> {
300 write!(f.inner, "[")?;
301 f.needs_space = false;
302 for elem in self {
303 elem.write(f)?;
304 }
305 write!(f.inner, "]")?;
306 Ok(())
307 }
308}
309
310impl Serialize for ObjRef {
311 fn write(&self, f: &mut Formatter) -> io::Result<()> {
312 if f.needs_space {
313 write!(f.inner, " ")?;
314 }
315 f.needs_space = write_ref(*self, &mut f.inner)?;
316 Ok(())
317 }
318}
319
320#[derive(Debug, Copy, Clone)]
322pub struct PdfName<'a>(pub &'a str);
323
324impl Serialize for PdfName<'_> {
325 fn write(&self, f: &mut Formatter) -> io::Result<()> {
326 f.needs_space = write_name(&self.0, &mut f.inner)?;
327 Ok(())
328 }
329}
330
331impl Serialize for DateTime<Local> {
332 fn write(&self, f: &mut Formatter) -> io::Result<()> {
333 let off = self.offset();
334 let off_sec = off.local_minus_utc();
335 let (off_sec, mark) = if off_sec < 0 {
336 (-off_sec, '-')
337 } else {
338 (off_sec, '+')
339 };
340 let (_, off_min) = (off_sec % 60, off_sec / 60);
341 let (off_min, off_hor) = (off_min % 60, off_min / 60);
342 let date_time = format!(
343 "D:{}{}{:02}'{:02}",
344 self.format("%Y%m%d%H%M%S"),
345 mark,
346 off_hor,
347 off_min
348 );
349 let st = date_time.into_bytes();
350 f.needs_space = write_string(&st, &mut f.inner)?;
351 Ok(())
352 }
353}
354
355pub fn write_string<W: Write>(bytes: &[u8], w: &mut W) -> io::Result<bool> {
357 let mut cpc = bytes.iter().copied().filter(|c| *c == 41 ).count();
358 let mut opc = 0;
359 write!(w, "(")?;
360 for byte in bytes.iter().copied() {
361 match byte {
362 0..=31 | 127..=255 => write!(w, "\\{:03o}", byte)?,
363 92 => write!(w, "\\\\")?,
364 40 => {
365 if cpc == 0 {
366 write!(w, "\\(")?
367 } else {
368 write!(w, "(")?;
369 cpc -= 1;
370 opc += 1;
371 }
372 }
373 41 => {
374 if opc == 0 {
375 write!(w, "\\)")?
376 } else {
377 write!(w, ")")?;
378 opc -= 1;
379 }
380 }
381 _ => write!(w, "{}", byte as char)?,
382 }
383 }
384 write!(w, ")")?;
385 Ok(false)
386}
387
388pub fn write_name<W: Write>(name: &str, w: &mut W) -> io::Result<bool> {
392 write!(w, "/{}", name)?;
393 Ok(true)
394}
395
396pub fn write_ref<W: Write>(plain_ref: ObjRef, w: &mut W) -> io::Result<bool> {
398 write!(w, "{} {} R", plain_ref.id, plain_ref.gen)?;
399 Ok(true)
400}