Milán Major

netscape-revival

1 branch
Code

lib/mac/TX/ObjectsRanges.h

// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
//	
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ

#pragma once


#include "TextensionCommon.h"
#include "Array.h"
#include "AttrObject.h"


//***************************************************************************************************


struct TSectRanges {
	long leadIndex; //range index
	long leadCount; //count of range elements in the first range that are not inside
	long leadSectCount; //count of range elements in the first range that are inside
	
	long insideIndex; //range index
	long insideCount; //ranges count
	
	long trailIndex; //range index
	long trailCount; //count of range elements in the last range that are not inside
	long trailSectCount; //count of range elements in the last range that are inside
};
//***************************************************************************************************


class CRanges : public CLongTagArray
{
	public:
//------
	CRanges();
	
	inline void IRanges(short elementSize, short moreElements = 1)
		{this->IArray(elementSize, moreElements);}
	
	virtual void FreeData(Boolean compact = true);

	long GetRangeEnd(long rangeIndex) const;
	long GetRangeStart(long rangeIndex) const;
	long GetRangeLen(long rangeIndex) const;
	
	void SetRangeEnd(long rangeIndex, long newEnd);
	
	void GetRangeBounds(long rangeIndex, TOffsetPair* bounds) const;
	
	inline Boolean IsRangeEmpty(long rangeIndex) const {return this->GetRangeLen(rangeIndex) == 0;}
	
	Boolean IsRangeStart(long offset, long rangeIndex = -1) const;

	long GetLastRangeEnd() const;
	
	long OffsetToRangeIndex(TOffset rangeOffset) const;
	
	void OffsetRanges(long valToAdd, long firstIndex, long count = -1);
	//count < 0 ==> offset up to last range
	
	long SectRanges(long offset, long count, TSectRanges* sectInfo) const;
	
	
	#ifdef txtnDebug
	virtual void CheckCoherence(long count);
	#endif
	
};


class CObjectsRanges : public CRanges
{
	public:
								CObjectsRanges();
		void 					IObjectsRanges(CAttrObject* continuousObj, short moreElements = 1);
		
		//¥override
		virtual void 			Free();
		virtual void 			FreeData(Boolean compact = true);
	
		virtual long 			RemoveElements(long removeIndex, long countToRemove);

		//returns the new elements count
		
		//¥own
		virtual CAttrObject* OffsetToObject(TOffset offset);
	
		CAttrObject* RangeIndexToObject(short rangeIndex) const;
	
		short GetNextObjectRange(long offset, CAttrObject** theObj, long* rangeLen) const;
		// returns the range index, -1 if no next
		
		OSErr ReplaceRange(long offset, long oldLen, long newLen
											, CAttrObject* theObject = nil, Boolean takeObjectCopy =true);
		/*
			-if oldLen == 0 ==> acts as Insert
			-if newLen == 0 ==> acts a delete, in this case "theObject" is not used
			-if theObject is nil the object at "offset" is used
		*/
		
		OSErr ReplaceRange(long offset, long oldLen, CObjectsRanges* newRanges, Boolean plug = false);
	
		OSErr InsertObjectRange(short insertIndex, long rangeEnd, CAttrObject* rangeObj, Boolean reference);
		
		virtual long UpdateRangeObjects(long startOffset, long len, const AttrObjModifier& modifier);
	
		virtual CAttrObject* GetContinuousObj(long startOffset, long len);
	
		inline short CountRanges() const {return this->CountElements();}
		
		inline void SetFreeObjects(char free) {fFreeObjects = free;}
		
		#ifdef txtnDebug
		short CountUniqueObjects();
		virtual void CheckCoherence(long count);
		#endif
		
		
	protected :
	//---------
	CAttrObject*		fContinuousObj;
	
	private:
	//------
	long fLastContStart; //-1 ==> GetContinuousObj will recalc fContinuousObj
	long fLastContLen;
	
	CAttrObject* fLastSearchedObj;
	char fFreeObjects;
	
		CAttrObject* MapObject(CAttrObject* newObj, Boolean takeObjectCopy, Boolean* reference);
		CAttrObject* SearchObject(const CAttrObject* objToCheck);
		
		void SetObjectRange(short rangeIndex, long newRangeEnd, CAttrObject* newObj, Boolean reference);
		
		void ReplaceRangeObj(long offset, long len, CAttrObject* newObj, Boolean reference);
				
		Boolean UpdateRangesBounds(long startOffset, long endOffset, CAttrObject* newObj
																, short* firstRange, short* lastRange);	
		
		
		void ClearRange(long offset, long len);
		
		void FreeObjects(short firstIndex = 0, short lastIndex = -1);
		//frees the objects in the range firstIndex..lastIndex inclusive
		//no params ==> free all objects
};