1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/// PDF content streams.
use std::fmt::{Display, Formatter};
use std::mem::replace;
use std::cmp::Ordering;
use std::io;
use itertools::Itertools;

use crate::error::*;
use crate::object::*;
use crate::parser::{Lexer, parse_with_lexer};
use crate::primitive::*;

/// Operation in a PDF content stream.
#[derive(Debug, Clone)]
pub struct Operation {
    pub operator: String,
    pub operands: Vec<Primitive>,
}

impl Operation {
    pub fn new(operator: String, operands: Vec<Primitive>) -> Operation {
        Operation{
            operator,
            operands,
        }
    }
}


/// Represents a PDF content stream - a `Vec` of `Operator`s
#[derive(Debug)]
pub struct Content {
    pub operations: Vec<Operation>,
}

impl Content {
    fn parse_from(data: &[u8], resolve: &impl Resolve) -> Result<Content> {
        let mut lexer = Lexer::new(data);

        let mut content = Content {operations: Vec::new()};
        let mut buffer = Vec::new();

        loop {
            let backup_pos = lexer.get_pos();
            let obj = parse_with_lexer(&mut lexer, resolve);
            match obj {
                Ok(obj) => {
                    // Operand
                    buffer.push(obj)
                }
                Err(e) => {
                    if e.is_eof() {
                        break;
                    }
                    // It's not an object/operand - treat it as an operator.
                    lexer.set_pos(backup_pos);
                    let operator = t!(lexer.next()).to_string();
                    let operation = Operation::new(operator, replace(&mut buffer, Vec::new()));
                    // Give operands to operation and empty buffer.
                    content.operations.push(operation.clone());
                }
            }
            match lexer.get_pos().cmp(&data.len()) {
                Ordering::Greater => err!(PdfError::ContentReadPastBoundary),
                Ordering::Less => (),
                Ordering::Equal => break
            }
        }
        Ok(content)
    }
}

impl Object for Content {
    /// Write object as a byte stream
    fn serialize<W: io::Write>(&self, _out: &mut W) -> Result<()> {unimplemented!()}
    /// Convert primitive to Self
    fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
        type ContentStream = Stream<()>;
        
        match p {
            Primitive::Array(parts) => {
                let mut content_data = Vec::new();
                for p in parts {
                    let part = t!(ContentStream::from_primitive(p, resolve));
                    let data = t!(part.data());
                    content_data.extend(data);
                }
                Content::parse_from(&content_data, resolve)
            }
            p => {
                Content::parse_from(
                    t!(t!(ContentStream::from_primitive(p, resolve)).data()),
                    resolve
                )
            }
        }
    }
}


impl Display for Content {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        write!(f, "Content: ")?;
        for operation in &self.operations {
            write!(f, "{}", operation)?;
        }
        Ok(())
    }
}

impl Display for Operation {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        write!(f, "{} : {}", self.operator, self.operands.iter().format(", "))
    }
}