/* Copyright 2021 Grégory Soutadé This file is part of uPDFParser. uPDFParser is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. uPDFParser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with uPDFParser. If not, see . */ #ifndef _UPDFTYPES_HPP_ #define _UPDFTYPES_HPP_ #include #include #include #include #include namespace uPDFParser { /** * @brief Base class for PDF object type * From https://resources.infosecinstitute.com/topic/pdf-file-format-basic-structure/ */ class DataType { public: enum TYPE {BOOLEAN, INTEGER, REAL, NAME, STRING, HEXASTRING, REFERENCE, ARRAY, DICTIONARY, STREAM}; DataType(TYPE _type): _type(_type) {} virtual ~DataType() {} /** * @brief Get current data type */ TYPE type() { return _type; } /** * @brief String representation for serialization */ virtual std::string str() = 0; /** * @brief Clone current object */ virtual DataType* clone() = 0; protected: TYPE _type; }; class Boolean : public DataType { public: Boolean(bool value): DataType(DataType::TYPE::BOOLEAN), _value(value) {} virtual DataType* clone() {return new Boolean(_value);} bool value() {return _value;} virtual std::string str() { return (_value)?" true":" false";} private: bool _value; }; class Integer : public DataType { public: Integer(int value, bool _signed=false): DataType(DataType::TYPE::INTEGER), _value(value), _signed(_signed) {} virtual DataType* clone() {return new Integer(_value, _signed);} int value() {return _value;} virtual std::string str(); private: int _value; bool _signed; }; class Real : public DataType { public: Real(float value, bool _signed=false): DataType(DataType::TYPE::REAL), _value(value), _signed(_signed) {} virtual DataType* clone() {return new Real(_value, _signed);} float value() {return _value;} virtual std::string str(); private: float _value; bool _signed; }; class Name : public DataType { public: Name(const std::string&); virtual DataType* clone() {return new Name(_value);} std::string value() { const char* name = _value.c_str(); return std::string(&name[1]); } virtual std::string str() { return _value;} private: std::string _value; }; class String : public DataType { public: String(const std::string&); virtual DataType* clone() {return new String(_value);} std::string value() {return _value;} // Escape '(' and ')' characters virtual std::string str() { char prev = '\0'; std::string res("("); for(unsigned int i=0; i<_value.size(); i++) { if ((_value[i] == '(' || _value[i] == ')') && prev != '\\') res += '\\'; res += _value[i]; prev = _value[i]; } res += ")"; return res; } private: std::string _value; }; class HexaString : public DataType { public: HexaString(const std::string&); virtual DataType* clone() {return new HexaString(_value);} std::string value() {return _value;} virtual std::string str() { return std::string("<") + _value + std::string(">");} private: std::string _value; }; class Reference : public DataType { public: Reference(int objectId, int generationNumber): DataType(DataType::TYPE::REFERENCE), objectId(objectId), generationNumber(generationNumber) {} virtual DataType* clone() {return new Reference(objectId, generationNumber);} int value() {return objectId;} virtual std::string str() { std::stringstream res; res << " " << objectId << " " << generationNumber << " R"; return res.str(); } private: int objectId, generationNumber; }; class Array : public DataType { public: Array(): DataType(DataType::TYPE::ARRAY) {} void addData(DataType* data) {_value.push_back(data);} virtual DataType* clone() { Array* res = new Array(); std::vector::iterator it; for(it=_value.begin(); it!=_value.end(); it++) res->addData((*it)->clone()); return res; } std::vector& value() {return _value;} virtual std::string str(); private: std::vector _value; }; class Dictionary : public DataType { public: Dictionary(): DataType(DataType::TYPE::DICTIONARY) {} void addData(const std::string&, DataType*); virtual DataType* clone() { Dictionary* res = new Dictionary(); std::map::iterator it; for(it=_value.begin(); it!=_value.end(); it++) { res->addData(it->first, it->second->clone()); } return res; } std::map& value() {return _value;} virtual std::string str(); private: std::map _value; }; class Stream : public DataType { public: Stream(int startOffset, int endOffset): DataType(DataType::TYPE::STREAM), startOffset(startOffset), endOffset(endOffset) {} virtual DataType* clone() {return new Stream(startOffset, endOffset);} virtual std::string str() { return "stream\nendstream\n";} private: int startOffset, endOffset; }; } #endif