aboutsummaryrefslogtreecommitdiff
path: root/src/unstable/textbuilder.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2019-11-11 05:01:29 -0800
committerMike Buland <eichlan@xagasoft.com>2019-11-11 05:01:29 -0800
commit96759377ae8a4394d325747f597fe5b60afabf6e (patch)
treedd2daea517d126edb782924cf6003b5ae24cbe50 /src/unstable/textbuilder.cpp
parentd5098782e5645d39b5e92f150e187e7194ef055a (diff)
downloadlibbu++-96759377ae8a4394d325747f597fe5b60afabf6e.tar.gz
libbu++-96759377ae8a4394d325747f597fe5b60afabf6e.tar.bz2
libbu++-96759377ae8a4394d325747f597fe5b60afabf6e.tar.xz
libbu++-96759377ae8a4394d325747f597fe5b60afabf6e.zip
Working on TextBuilder & Text.
Seriously thinking about changing Text to just use full codepoints. It would be much less work, more reliable and predictable, easier to use, but would use twice the memory.
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