diff options
author | Mike Buland <eichlan@xagasoft.com> | 2019-11-11 05:01:29 -0800 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2019-11-11 05:01:29 -0800 |
commit | 96759377ae8a4394d325747f597fe5b60afabf6e (patch) | |
tree | dd2daea517d126edb782924cf6003b5ae24cbe50 /src | |
parent | d5098782e5645d39b5e92f150e187e7194ef055a (diff) | |
download | libbu++-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')
-rw-r--r-- | src/unstable/blobbuilder.cpp | 2 | ||||
-rw-r--r-- | src/unstable/textbuilder.cpp | 281 | ||||
-rw-r--r-- | src/unstable/textbuilder.h | 78 | ||||
-rw-r--r-- | src/unstable/textcodec.cpp | 17 | ||||
-rw-r--r-- | src/unstable/textcodec.h | 41 | ||||
-rw-r--r-- | src/unstable/textcodecutf8.cpp | 25 | ||||
-rw-r--r-- | src/unstable/textcodecutf8.h | 26 |
7 files changed, 469 insertions, 1 deletions
diff --git a/src/unstable/blobbuilder.cpp b/src/unstable/blobbuilder.cpp index 43c0779..fd62cb0 100644 --- a/src/unstable/blobbuilder.cpp +++ b/src/unstable/blobbuilder.cpp | |||
@@ -93,7 +93,7 @@ Bu::BlobBuilderCore::BlobBuilderCore( const Bu::BlobBuilderCore &rSrc ) : | |||
93 | pLast( 0 ), | 93 | pLast( 0 ), |
94 | iLength( rSrc.iLength ) | 94 | iLength( rSrc.iLength ) |
95 | { | 95 | { |
96 | 96 | throw Bu::ExceptionBase("Not yet implemented."); | |
97 | } | 97 | } |
98 | 98 | ||
99 | Bu::BlobBuilderCore::~BlobBuilderCore() | 99 | Bu::BlobBuilderCore::~BlobBuilderCore() |
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 | |||
15 | Bu::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 | |||
31 | Bu::TextBuilderCore::Chunk::~Chunk() | ||
32 | { | ||
33 | delete[] pData; | ||
34 | pData = 0; | ||
35 | pNext = 0; | ||
36 | } | ||
37 | |||
38 | void 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 | |||
57 | Bu::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 | // | ||
77 | Bu::TextBuilderCore::TextBuilderCore() : | ||
78 | pFirst( 0 ), | ||
79 | pLast( 0 ), | ||
80 | iLength( 0 ) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | Bu::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 | |||
92 | Bu::TextBuilderCore::~TextBuilderCore() | ||
93 | { | ||
94 | clear(); | ||
95 | } | ||
96 | |||
97 | void 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 | |||
110 | void 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 | |||
133 | void 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 | |||
148 | void 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 | |||
186 | void Bu::TextBuilderCore::set( const CodePoint *pSrc, int32_t iLength ) | ||
187 | { | ||
188 | clear(); | ||
189 | append( pSrc, iLength ); | ||
190 | } | ||
191 | |||
192 | void Bu::TextBuilderCore::copyTo( void *pDestRaw, int32_t iLength ) | ||
193 | { | ||
194 | |||
195 | } | ||
196 | |||
197 | Bu::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 | |||
215 | Bu::TextBuilder::TextBuilder() | ||
216 | { | ||
217 | } | ||
218 | |||
219 | Bu::TextBuilder::TextBuilder( const Text &rSrc ) | ||
220 | { | ||
221 | } | ||
222 | |||
223 | Bu::TextBuilder::TextBuilder( const TextBuilder &rSrc ) : | ||
224 | Bu::SharedCore<Bu::TextBuilder, Bu::TextBuilderCore>( rSrc ) | ||
225 | { | ||
226 | } | ||
227 | |||
228 | Bu::TextBuilder::~TextBuilder() | ||
229 | { | ||
230 | } | ||
231 | |||
232 | void Bu::TextBuilder::set( const Text &rSrc ) | ||
233 | { | ||
234 | _hardCopy(); | ||
235 | core->set( rSrc.getData(), rSrc.getSize() ); | ||
236 | } | ||
237 | |||
238 | void Bu::TextBuilder::append( const Text &rSrc ) | ||
239 | { | ||
240 | _hardCopy(); | ||
241 | } | ||
242 | |||
243 | void Bu::TextBuilder::append( const CodePoint *pSrc, int32_t iLength ) | ||
244 | { | ||
245 | _hardCopy(); | ||
246 | } | ||
247 | |||
248 | void Bu::TextBuilder::prepend( const Text &rSrc ) | ||
249 | { | ||
250 | _hardCopy(); | ||
251 | } | ||
252 | |||
253 | void Bu::TextBuilder::insert( const Text &rSrc ) | ||
254 | { | ||
255 | _hardCopy(); | ||
256 | } | ||
257 | |||
258 | void Bu::TextBuilder::clear() | ||
259 | { | ||
260 | _hardCopy(); | ||
261 | } | ||
262 | |||
263 | int32_t Bu::TextBuilder::getSize() const | ||
264 | { | ||
265 | return core->iLength; | ||
266 | } | ||
267 | |||
268 | Bu::Text Bu::TextBuilder::getText() const | ||
269 | { | ||
270 | return Text( *this ); | ||
271 | } | ||
272 | |||
273 | Bu::CodePoint Bu::TextBuilder::operator[]( int32_t iIndex ) const | ||
274 | { | ||
275 | return core->getAt( iIndex ); | ||
276 | } | ||
277 | |||
278 | Bu::TextBuilder &Bu::TextBuilder::operator=( const Text &rSrc ) | ||
279 | { | ||
280 | set( rSrc ); | ||
281 | return *this; | ||
282 | } | ||
283 | |||
284 | Bu::TextBuilder &Bu::TextBuilder::operator==( const Text &rSrc ) | ||
285 | { | ||
286 | set( pSrc ); | ||
287 | return *this; | ||
288 | } | ||
8 | 289 | ||
diff --git a/src/unstable/textbuilder.h b/src/unstable/textbuilder.h index 73271f8..22fa653 100644 --- a/src/unstable/textbuilder.h +++ b/src/unstable/textbuilder.h | |||
@@ -5,4 +5,82 @@ | |||
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 | #ifndef BU_TEXT_BUILDER_H | ||
9 | #define BU_TEXT_BUILDER_H | ||
10 | |||
11 | #include <stdint.h> | ||
12 | #include "bu/sharedcore.h" | ||
13 | #include "bu/text.h" | ||
14 | |||
15 | namespace Bu | ||
16 | { | ||
17 | class TextBuilder; | ||
18 | |||
19 | /** @cond DEVEL */ | ||
20 | class TextBuilderCore | ||
21 | { | ||
22 | friend class TextBuilder; | ||
23 | friend class SharedCore<TextBuilder, TextBuilderCore>; | ||
24 | private: | ||
25 | class Chunk | ||
26 | { | ||
27 | public: | ||
28 | Chunk( const CodePoint *pSrc, int32_t iLength ); | ||
29 | ~Chunk(); | ||
30 | |||
31 | void append( const CodePoint *&pSrc, int32_t &iLength ); | ||
32 | |||
33 | Chunk *split( int32_t iIndex ); | ||
34 | |||
35 | int32_t iLength; | ||
36 | CodePoint *pData; | ||
37 | Chunk *pNext; | ||
38 | }; | ||
39 | |||
40 | TextBuilderCore(); | ||
41 | TextBuilderCore( const TextBuilderCore &rSrc ); | ||
42 | virtual ~TextBuilderCore(); | ||
43 | |||
44 | void clear(); | ||
45 | void append( const CodePoint *pSrc, int32_t iLength ); | ||
46 | void prepend( const CodePoint *pSrc, int32_t iLength ); | ||
47 | void insert( int32_t iBefore, const CodePoint *pSrc, int32_t iLength ); | ||
48 | void set( const CodePoint *pSrc, int32_t iLength ); | ||
49 | void copyTo( void *pDestRaw, int32_t iLength ); | ||
50 | CodePoint getAt( int32_t iIndex ) const; | ||
51 | |||
52 | Chunk *pFirst; | ||
53 | Chunk *pLast; | ||
54 | int32_t iLength; | ||
55 | }; | ||
56 | |||
57 | class TextBuilder : public Bu::SharedCore<TextBuilder, TextBuilderCore> | ||
58 | { | ||
59 | protected: | ||
60 | using SharedCore<TextBuilder, TextBuilderCore>::core; | ||
61 | using SharedCore<TextBuilder, TextBuilderCore>::_hardCopy; | ||
62 | |||
63 | public: | ||
64 | TextBuilder(); | ||
65 | TextBuilder( const Text &rSrc ); | ||
66 | TextBuilder( const TextBuilder &rSrc ); | ||
67 | virtual ~TextBuilder(); | ||
68 | |||
69 | void set( const Text &rSrc ); | ||
70 | void append( const Text &rSrc ); | ||
71 | void append( const CodePoint *pSrc, int32_t iLength ); | ||
72 | void prepend( const Text &rSrc ); | ||
73 | void insert( const Text &rSrc ); | ||
74 | void clear(); | ||
75 | |||
76 | int32_t getSize() const; | ||
77 | Text getText() const; | ||
78 | CodePoint operator[]( int32_t iIndex ) const; | ||
79 | |||
80 | TextBuilder &operator=( const Text &rSrc ); | ||
81 | TextBuilder &operator==( const Text &rSrc ); | ||
82 | }; | ||
83 | } | ||
84 | |||
85 | #endif | ||
8 | 86 | ||
diff --git a/src/unstable/textcodec.cpp b/src/unstable/textcodec.cpp index e69de29..0ac791e 100644 --- a/src/unstable/textcodec.cpp +++ b/src/unstable/textcodec.cpp | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2019 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #include "bu/textcodec.h" | ||
9 | |||
10 | Bu::TextCodec::TextCodec() | ||
11 | { | ||
12 | } | ||
13 | |||
14 | Bu::TextCodec::~TextCodec() | ||
15 | { | ||
16 | } | ||
17 | |||
diff --git a/src/unstable/textcodec.h b/src/unstable/textcodec.h index e69de29..6ae392e 100644 --- a/src/unstable/textcodec.h +++ b/src/unstable/textcodec.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2019 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #ifndef TEXT_CODEC_H | ||
9 | #define TEXT_CODEC_H | ||
10 | |||
11 | #include "bu/text.h" | ||
12 | #include "bu/blob.h" | ||
13 | |||
14 | namespace Bu | ||
15 | { | ||
16 | class Text; | ||
17 | class Blob; | ||
18 | class TextBuilder; | ||
19 | class BlobBuilder; | ||
20 | |||
21 | /** | ||
22 | * Represents a textual format and the routines to convert from that | ||
23 | * format to unicode code points and vica versa. | ||
24 | */ | ||
25 | class TextCodec | ||
26 | { | ||
27 | public: | ||
28 | TextCodec(); | ||
29 | virtual ~TextCodec(); | ||
30 | |||
31 | // virtual Blob encode( const Text &rSource ); | ||
32 | // virtual Text decode( const Blob &rSource, int32_t &rBytesUsed ); | ||
33 | |||
34 | virtual void encode( BlobBuilder &rTarget, const Text &rSource )=0; | ||
35 | virtual int32_t decode( TextBuilder &rTarget, const Blob &rSource )=0; | ||
36 | |||
37 | private: | ||
38 | }; | ||
39 | }; | ||
40 | |||
41 | #endif | ||
diff --git a/src/unstable/textcodecutf8.cpp b/src/unstable/textcodecutf8.cpp index e69de29..ce4e0a2 100644 --- a/src/unstable/textcodecutf8.cpp +++ b/src/unstable/textcodecutf8.cpp | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2019 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #include "bu/textcodecutf8.h" | ||
9 | |||
10 | Bu::TextCodecUtf8::TextCodecUtf8() | ||
11 | { | ||
12 | } | ||
13 | |||
14 | Bu::TextCodecUtf8::~TextCodecUtf8() | ||
15 | { | ||
16 | } | ||
17 | |||
18 | void Bu::TextCodecUtf8::encode( BlobBuilder &rTarget, const Text &rSource ) | ||
19 | { | ||
20 | } | ||
21 | |||
22 | int32_t Bu::TextCodecUtf8::decode( TextBuilder &rTarget, const Blob &rSource ) | ||
23 | { | ||
24 | } | ||
25 | |||
diff --git a/src/unstable/textcodecutf8.h b/src/unstable/textcodecutf8.h index e69de29..f565f57 100644 --- a/src/unstable/textcodecutf8.h +++ b/src/unstable/textcodecutf8.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2019 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #ifndef TEXT_CODEC_UTF8_H | ||
9 | #define TEXT_CODEC_UTF8_H | ||
10 | |||
11 | #include "bu/textcodec.h" | ||
12 | |||
13 | namespace Bu | ||
14 | { | ||
15 | class TextCodecUtf8 : public TextCodec | ||
16 | { | ||
17 | public: | ||
18 | TextCodecUtf8(); | ||
19 | virtual ~TextCodecUtf8(); | ||
20 | |||
21 | virtual void encode( BlobBuilder &rTarget, const Text &rSource ); | ||
22 | virtual int32_t decode( TextBuilder &rTarget, const Blob &rSource ); | ||
23 | }; | ||
24 | } | ||
25 | |||
26 | #endif | ||