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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined Object_h
#define Object_h
#include "Utils.h"
#include <cmath>
#include <string>
#include <fstream>
#include <map>
#include <set>
#include <vector>
#include <utility>
namespace merge_lib
{
//This class represents pdf objects, and defines methods for performing
//all necessary operations on pdf objects
//Each object consists of two parts: content and object's number
//<object number> <number> obj
//<content>
//endobj
//Object can contain several links to other object. These objects has been named "children".
//Each reference (child object) should be kept with it position(s) in object's content.
//After each content modification, all references should be changed too.
//This convention lighten the recalculation object numbers work.
class Object
{
public:
friend class PageElementHandler;
typedef std::vector<unsigned int> ReferencePositionsInContent;
typedef std::pair<Object *, ReferencePositionsInContent > ChildAndItPositionInContent;
typedef std::map <unsigned int, ChildAndItPositionInContent> Children;
Object(unsigned int objectNumber, unsigned int generationNumber, const std::string & objectContent,
std::string fileName = "", std::pair<unsigned int, unsigned int> streamBounds = std::make_pair ((unsigned int)0,(unsigned int)0), bool hasStream = false
):
_number(objectNumber), _generationNumber(generationNumber), _oldNumber(objectNumber), _content(objectContent),_parents(),_children(),_isPassed(false),
_fileName(fileName), _streamBounds(streamBounds), _hasStream(hasStream), _hasStreamInContent(false)
{
}
virtual ~Object();
Object * getClone(std::vector<Object *> & clones);
void addChild(Object * child, const std::vector<unsigned int> childPositionsInContent);
void addChild(const Children & children);
ReferencePositionsInContent removeChild(Object * child);
void forgetAboutChildren(unsigned int leftBound, unsigned int rightBound);
Object * getChild(unsigned int objectNumber);
bool findObject(const std::string & token, Object* & foundObject, unsigned int & tokenPositionInContent);
std::vector<Object *> getChildrenByBounds(unsigned int leftBound, unsigned int rightBound);
std::vector<Object *> getSortedByPositionChildren(unsigned int leftBound, unsigned int rightBound);
void removeChildrenByBounds(unsigned int leftBound, unsigned int rightBound);
const Children & getChildren();
void removeHimself();
unsigned int getObjectNumber() const;
unsigned int getgenerationNumber() const;
std::string & getObjectContent();
void setObjectContent(const std::string & objectContent);
void appendContent(const std::string & addToContent);
void eraseContent(unsigned int from, unsigned int size);
void insertToContent(unsigned int position, const char * insertedStr, unsigned int length);
void insertToContent(unsigned int position, const std::string & insertedStr);
//vector <object number, its size>
void serialize(std::ofstream & out, std::map< unsigned int, std::pair<unsigned long long, unsigned int > > & sizesAndGenerationNumbers);
void recalculateObjectNumbers(unsigned int & newNumber);
bool isPassed()
{
return _isPassed;
}
void retrieveMaxObjectNumber(unsigned int & maxNumber);
void resetIsPassed()
{
if(_isPassed)
_isPassed = false;
Children::iterator it;
for ( it=_children.begin() ; it != _children.end(); it++ )
{
if((*it).second.first->isPassed())
(*it).second.first->resetIsPassed();
}
}
unsigned int getOldNumber()
{
return _oldNumber;
}
void setObjectNumber(unsigned int objNumber)
{
_number = objNumber;
_oldNumber = objNumber;
}
bool getStream(std::string &);
bool hasStream();
bool getHeader(std::string &content);
void forgetStreamInFile()
{
_hasStreamInContent = true;
_hasStream = true;
}
std::string getNameSimpleValue(const std::string &content, const std::string &patten, size_t pos = 0);
unsigned int getChildPosition(const Object * child); //throw (Exception)
const std::set<Object *> & getParents()
{
return _parents;
}
Object* findPatternInObjOrParents(const std::string &pattern);
private:
//methods
Object(const Object & copy);
Object * _getClone(std::map<unsigned int, Object *> & clones);
void _addChild(Object * child, const ReferencePositionsInContent & childPositionsInContent);
void _setObjectNumber(unsigned int objectNumber);
void _addParent(Object * child);
bool _findObject(const std::string & token, Object* & foundObject, unsigned int & tokenPositionInContent);
void _serialize(std::ofstream & out, const std::string & stream);
void _recalculateObjectNumbers(unsigned int & maxNumber);
void _recalculateReferencePositions(unsigned int changedReference, int displacement);
void _retrieveMaxObjectNumber(unsigned int & maxNumber);
void _serialize(std::ofstream & out, std::map<unsigned int, unsigned long long> & sizes);
bool _getStreamFromContent(std::string & stream);
//members
unsigned int _number;
unsigned int _generationNumber;
unsigned int _oldNumber;
std::string _content;
std::set <Object *> _parents;
Children _children;
bool _isPassed;
std::pair<unsigned int, unsigned int> _streamBounds;
std::string _fileName;
bool _hasStream;
bool _hasStreamInContent;
};
}
#endif