Object.h 6.68 KB
Newer Older
Claudio Valerio's avatar
Claudio Valerio committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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/>.
 */
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
#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),
51
           _streamBounds(streamBounds), _fileName(fileName), _hasStream(hasStream), _hasStreamInContent(false)
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
	   {
	   }
	   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