/*
* 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 2 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 ) ,
_streamBounds ( streamBounds ) , _fileName ( fileName ) , _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