1 /****************************************************************************
2 **
3 ** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
4 **
5 ** This file is part of the Edyuk project <http://edyuk.org>
6 **
7 ** This file may be used under the terms of the GNU General Public License
8 ** version 3 as published by the Free Software Foundation and appearing in the
9 ** file GPL.txt included in the packaging of this file.
10 **
11 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 **
14 ****************************************************************************/
15 
16 #ifndef _QDOCUMENT_BUFFER_H_
17 #define _QDOCUMENT_BUFFER_H_
18 
19 #include "qce-config.h"
20 
21 #include <QVector>
22 
23 #include "qdocumentline_p.h"
24 
25 class QDocumentLineHandle;
26 
27 class QCE_EXPORT QDocumentBuffer
28 {
29 	friend class QDocumentLineHandle;
30 
31 	public:
32 		class iterator
33 		{
34 			public:
35 				iterator(const iterator& i);
36 
37 				bool atEnd() const;
38 
39 				int lineNumber() const;
40 				QDocumentLineHandle* lineHandle() const;
41 
42 				void move(int numLines);
43 
44 			protected:
45 				iterator(QDocumentBuffer *buffer, int block, int line);
46 
47 			private:
48 				int m_block;
49 				int m_line;
50 				QDocumentBuffer *m_buffer;
51 		};
52 
53 		QDocumentBuffer();
54 		~QDocumentBuffer();
55 
56 		QDocumentLineHandle* at(int index) const;
57 
58 		void appendLine(QDocumentLineHandle *l);
59 
60 		void insertLine(int index, QDocumentLineHandle *l);
61 		void removeLine(int index);
62 
63 		void insertLines(int after, const QVector<QDocumentLineHandle*>& l);
64 		void removeLines(int after, int n);
65 
66 	private:
cleanHelper(QVector<QDocumentLineHandle * > & l)67 		static void cleanHelper(QVector<QDocumentLineHandle*>& l)
68 		{
69 			foreach ( QDocumentLineHandle *h, l )
70 				h->deref();
71 		}
72 
73 		struct Block
74 		{
BlockBlock75 			inline Block() : start(-1), end(-1) {}
BlockBlock76 			inline Block(int line) : start(line), end(line) {}
~BlockBlock77 			~Block() { cleanHelper(lines); }
78 
moveBlock79 			inline void move(int numLines) { start += numLines; end += numLines; }
80 
sizeBlock81 			inline int size() const { return lines.count(); }
atBlock82 			inline QDocumentLineHandle* at(int index) const { return lines.at(index - start); }
83 
appendBlock84 			inline void append(QDocumentLineHandle *h) { lines.append(h); }
prependBlock85 			inline void prepend(QDocumentLineHandle *h) { lines.prepend(h); }
insertBlock86 			inline void insert(int index, QDocumentLineHandle *h) { lines.insert(index - start, h); }
insertBlock87 			inline void insert(int index, const QDocumentLineHandle* const* l, int n)
88 			{
89 				QDocumentLineHandle **d = const_cast<QDocumentLineHandle**>(l);
90 
91 				int i = index - start;
92 				lines.insert(i, n, 0);
93 
94 				while ( n )
95 				{
96 					lines[i++] = *d;
97 					++d;
98 					--n;
99 				}
100 			}
101 
appendBlock102 			inline void append(const QDocumentLineHandle* const* l, int n)
103 			{
104 				QDocumentLineHandle **d = const_cast<QDocumentLineHandle**>(l);
105 
106 				int i = lines.count();
107 				lines.insert(i, n, 0);
108 
109 				while ( n )
110 				{
111 					lines[i++] = *d;
112 					++d;
113 					--n;
114 				}
115 			}
116 
prependBlock117 			inline void prepend(const QDocumentLineHandle* const* l, int n)
118 			{
119 				QDocumentLineHandle **d = const_cast<QDocumentLineHandle**>(l);
120 
121 				int i = 0;
122 				lines.insert(i, n, 0);
123 
124 				while ( n )
125 				{
126 					lines[i++] = *d;
127 					++d;
128 					--n;
129 				}
130 			}
131 
removeBlock132 			inline void remove(int index) { lines.remove(index - start); }
removeBlock133 			inline void remove(int index, int count) { lines.remove(index - start, qMin(count, end - index)); }
134 
135 			int start, end;
136 			QVector<QDocumentLineHandle*> lines;
137 		};
138 
139 		int blockForLine(int index) const;
140 
141 		int m_safetyRoom;
142 		int m_optimalSize;
143 		int m_forkThresold;
144 		int m_mergeThresold;
145 
146 		QVector<Block*> m_blocks;
147 };
148 
149 #endif // !_QDOCUMENT_BUFFER_H_
150