uPDFParser/include/uPDFTypes.h
2021-08-21 18:22:58 +02:00

254 lines
5.6 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef _UPDFTYPES_HPP_
#define _UPDFTYPES_HPP_
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
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<DataType*>::iterator it;
for(it=_value.begin(); it!=_value.end(); it++)
res->addData((*it)->clone());
return res;
}
std::vector<DataType*>& value() {return _value;}
virtual std::string str();
private:
std::vector<DataType*> _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<std::string, DataType*>::iterator it;
for(it=_value.begin(); it!=_value.end(); it++)
{
res->addData(it->first, it->second->clone());
}
return res;
}
std::map<std::string, DataType*>& value() {return _value;}
virtual std::string str();
private:
std::map<std::string, DataType*> _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