aboutsummaryrefslogtreecommitdiff
path: root/src/unstable/textbuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/unstable/textbuilder.cpp')
-rw-r--r--src/unstable/textbuilder.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/unstable/textbuilder.cpp b/src/unstable/textbuilder.cpp
index 73271f8..af4dbac 100644
--- a/src/unstable/textbuilder.cpp
+++ b/src/unstable/textbuilder.cpp
@@ -5,4 +5,285 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#include "bu/textbuilder.h"
9
10#include "bu/exceptionbase.h"
11#include "bu/text.h"
12
13#define PAGE_SIZE 16
14
15Bu::TextBuilderCore::Chunk::Chunk( const CodePoint *pSrc, int32_t iLength ) :
16 iLength( iLength ),
17 pData( 0 ),
18 pNext( 0 )
19{
20 if( iLength < PAGE_SIZE )
21 {
22 pData = new CodePoint[PAGE_SIZE];
23 }
24 else
25 {
26 pData = new CodePoint[iLength];
27 }
28 memcpy( pData, pSrc, iLength*sizeof(CodePoint) );
29}
30
31Bu::TextBuilderCore::Chunk::~Chunk()
32{
33 delete[] pData;
34 pData = 0;
35 pNext = 0;
36}
37
38void Bu::TextBuilderCore::Chunk::append( const Bu::CodePoint *&pSrc,
39 int32_t &iLength )
40{
41 if( this->iLength >= PAGE_SIZE )
42 {
43 // This chink is full, just return.
44 return;
45 }
46 int32_t iCopy = PAGE_SIZE-this->iLength;
47 if( iCopy > iLength )
48 {
49 iCopy = iLength;
50 }
51 memcpy( pData+this->iLength, pSrc, iCopy*sizeof(Bu::CodePoint) );
52 this->iLength += iCopy;
53 pSrc += iCopy;
54 iLength -= iCopy;
55}
56
57Bu::TextBuilderCore::Chunk *Bu::TextBuilderCore::Chunk::split( int32_t iIndex )
58{
59 if( iIndex == 0 )
60 return NULL;
61
62 if( iIndex >= iLength )
63 return NULL;
64
65 Chunk *pNew = new Chunk( pData+iIndex, iLength-iIndex );
66 iLength -= iIndex;
67 pNew->pNext = pNext;
68 pNext = pNew;
69
70 return pNew;
71}
72
73
74//////
75// TextBuilderCore
76//
77Bu::TextBuilderCore::TextBuilderCore() :
78 pFirst( 0 ),
79 pLast( 0 ),
80 iLength( 0 )
81{
82}
83
84Bu::TextBuilderCore::TextBuilderCore( const TextBuilderCore &rSrc ) :
85 pFirst( 0 ),
86 pLast( 0 ),
87 iLength( rSrc.iLength )
88{
89 throw Bu::ExceptionBase("Not yet implemented.");
90}
91
92Bu::TextBuilderCore::~TextBuilderCore()
93{
94 clear();
95}
96
97void Bu::TextBuilderCore::clear()
98{
99 Chunk *pCur = pFirst;
100 while( pCur )
101 {
102 Chunk *pNext = pCur->pNext;
103 delete pCur;
104 pCur = pNext;
105 }
106 pFirst = pLast = 0;
107 iLength = 0;
108}
109
110void Bu::TextBuilderCore::append( const CodePoint *pSrc, int32_t iLength )
111{
112 this->iLength += iLength;
113 if( pFirst == 0 )
114 {
115 // Nothing in the list, just add a chunk.
116 pFirst = pLast = new Chunk( pSrc, iLength );
117 return;
118 }
119 else if( pLast->iLength < PAGE_SIZE )
120 {
121 // Append to the last chunk first, this will modify pSrc & iLength.
122 pLast->append( pSrc, iLength );
123 }
124
125 // If there's unused data at the end, append it now.
126 if( iLength > 0 )
127 {
128 pLast->pNext = new Chunk( pSrc, iLength );
129 pLast = pLast->pNext;
130 }
131}
132
133void Bu::TextBuilderCore::prepend( const CodePoint *pSrc, int32_t iLength )
134{
135 if( pFirst == 0 )
136 {
137 pFirst = pLast = new Chunk( pSrc, iLength );
138 }
139 else
140 {
141 Chunk *pNew = new Chunk( pSrc, iLength );
142 pNew->pNext = pFirst;
143 pFirst = pNew;
144 }
145 this->iLength += iLength;
146}
147
148void Bu::TextBuilderCore::insert( int32_t iBefore, const CodePoint *pSrc, int32_t iLength )
149{
150 if( iBefore <= 0 )
151 {
152 prepend( pSrc, iLength );
153 return;
154 }
155 if( iBefore >= this->iLength )
156 {
157 append( pSrc, iLength );
158 return;
159 }
160
161 Chunk *pCur = pFirst;
162 while( pCur )
163 {
164 if( iBefore == 0 )
165 {
166 // Insert between chunks, no splitting required.
167 Chunk *pNew = new Chunk( pSrc, iLength );
168 pNew->pNext = pCur->pNext;
169 pCur->pNext = pNew;
170 if( pLast == pCur )
171 pLast = pNew;
172 }
173 if( iBefore < pCur->iLength )
174 {
175 // This is the chunk we need to split.
176 Chunk *pNew = pCur->split( iBefore );
177 if( pLast == pCur )
178 pLast = pNew;
179 continue;
180 }
181 pCur = pCur->pNext;
182 }
183 this->iLength = iLength;
184}
185
186void Bu::TextBuilderCore::set( const CodePoint *pSrc, int32_t iLength )
187{
188 clear();
189 append( pSrc, iLength );
190}
191
192void Bu::TextBuilderCore::copyTo( void *pDestRaw, int32_t iLength )
193{
194
195}
196
197Bu::CodePoint Bu::TextBuilderCore::getAt( int32_t iIndex ) const
198{
199 if( iIndex < 0 || iIndex >= iLength )
200 throw Bu::ExceptionBase("Requested index is out of range.");
201
202 Chunk *pCur = pFirst;
203 while( iIndex >= pCur->iLength )
204 {
205 iIndex -= pCur->iLength;
206 pCur = pCur->pNext;
207 }
208 return pCur->pData[iIndex];
209}
210
211/////
212// TextBuilder
213//
214
215Bu::TextBuilder::TextBuilder()
216{
217}
218
219Bu::TextBuilder::TextBuilder( const Text &rSrc )
220{
221}
222
223Bu::TextBuilder::TextBuilder( const TextBuilder &rSrc ) :
224 Bu::SharedCore<Bu::TextBuilder, Bu::TextBuilderCore>( rSrc )
225{
226}
227
228Bu::TextBuilder::~TextBuilder()
229{
230}
231
232void Bu::TextBuilder::set( const Text &rSrc )
233{
234 _hardCopy();
235 core->set( rSrc.getData(), rSrc.getSize() );
236}
237
238void Bu::TextBuilder::append( const Text &rSrc )
239{
240 _hardCopy();
241}
242
243void Bu::TextBuilder::append( const CodePoint *pSrc, int32_t iLength )
244{
245 _hardCopy();
246}
247
248void Bu::TextBuilder::prepend( const Text &rSrc )
249{
250 _hardCopy();
251}
252
253void Bu::TextBuilder::insert( const Text &rSrc )
254{
255 _hardCopy();
256}
257
258void Bu::TextBuilder::clear()
259{
260 _hardCopy();
261}
262
263int32_t Bu::TextBuilder::getSize() const
264{
265 return core->iLength;
266}
267
268Bu::Text Bu::TextBuilder::getText() const
269{
270 return Text( *this );
271}
272
273Bu::CodePoint Bu::TextBuilder::operator[]( int32_t iIndex ) const
274{
275 return core->getAt( iIndex );
276}
277
278Bu::TextBuilder &Bu::TextBuilder::operator=( const Text &rSrc )
279{
280 set( rSrc );
281 return *this;
282}
283
284Bu::TextBuilder &Bu::TextBuilder::operator==( const Text &rSrc )
285{
286 set( pSrc );
287 return *this;
288}
8 289