aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/unstable/blobbuilder.cpp2
-rw-r--r--src/unstable/text.cpp56
-rw-r--r--src/unstable/text.h15
-rw-r--r--src/unstable/textbuilder.cpp306
-rw-r--r--src/unstable/textbuilder.h79
-rw-r--r--src/unstable/textcodec.cpp17
-rw-r--r--src/unstable/textcodec.h41
-rw-r--r--src/unstable/textcodecutf8.cpp25
-rw-r--r--src/unstable/textcodecutf8.h26
9 files changed, 552 insertions, 15 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
99Bu::BlobBuilderCore::~BlobBuilderCore() 99Bu::BlobBuilderCore::~BlobBuilderCore()
diff --git a/src/unstable/text.cpp b/src/unstable/text.cpp
index 9e5670d..be4c10f 100644
--- a/src/unstable/text.cpp
+++ b/src/unstable/text.cpp
@@ -6,22 +6,35 @@
6 */ 6 */
7 7
8#include "bu/text.h" 8#include "bu/text.h"
9#include "bu/textbuilder.h"
10
11#include "bu/exceptionbase.h"
12
9#include <string.h> 13#include <string.h>
10 14
11Bu::Text::Text() : 15Bu::Text::Text() :
12 pData( NULL ), 16 pData( NULL ),
13 iSize( 0 ), 17 bIsBmpOnly( true ),
14 iCodePoints( 0 ) 18 iSize( 0 )
15{ 19{
16} 20}
17 21
18Bu::Text::Text( const Text &rSrc ) : 22Bu::Text::Text( const Text &rSrc ) :
19 pData( NULL ), 23 pData( NULL ),
20 iSize( rSrc.iSize ), 24 bIsBmpOnly( rSrc.bIsBmpOnly ),
21 iCodePoints( rSrc.iCodePoints ) 25 iSize( rSrc.iSize )
26{
27 pData = new CodePoint[iSize];
28 memcpy( pData, rSrc.pData, sizeof(CodePoint)*iSize );
29}
30
31Bu::Text::Text( const TextBuilder &rSrc ) :
32 pData( NULL ),
33 bIsBmpOnly( true ),
34 iSize( rSrc.getSize() )
22{ 35{
23 pData = new uint16_t[iSize]; 36 pData = new CodePoint[iSize];
24 memcpy( pData, rSrc.pData, sizeof(uint16_t)*iSize ); 37
25} 38}
26 39
27Bu::Text::~Text() 40Bu::Text::~Text()
@@ -30,4 +43,35 @@ Bu::Text::~Text()
30 pData = NULL; 43 pData = NULL;
31} 44}
32 45
46bool Bu::Text::isEmpty() const
47{
48 return (iSize == 0);
49}
50
51bool Bu::Text::isBmpOnly() const
52{
53 return bIsBmpOnly;
54}
55
56int32_t Bu::Text::getSize() const
57{
58 return iSize;
59}
60
61int32_t Bu::Text::getSizeInBytes() const
62{
63 return iSize*sizeof(CodePoint);
64}
65
66Bu::CodePoint Bu::Text::operator[]( int32_t iIndex ) const
67{
68 if( iIndex < 0 || iIndex >= iSize )
69 throw Bu::ExceptionBase("Index out of range.");
70 return pData[iIndex];
71}
72
73Bu::CodePoint *Bu::Text::getData() const
74{
75 return pData;
76}
33 77
diff --git a/src/unstable/text.h b/src/unstable/text.h
index 1d623ff..c57dcfb 100644
--- a/src/unstable/text.h
+++ b/src/unstable/text.h
@@ -12,6 +12,8 @@
12 12
13namespace Bu 13namespace Bu
14{ 14{
15 class TextBuilder;
16
15 /** 17 /**
16 * Represents a string of text. Human readable language. This should be 18 * Represents a string of text. Human readable language. This should be
17 * used any time you're dealing with actual text and not just binary 19 * used any time you're dealing with actual text and not just binary
@@ -27,11 +29,6 @@ namespace Bu
27 * multilpe code points. In addition, a code point can also represent 29 * multilpe code points. In addition, a code point can also represent
28 * formatting or display inforamtion. 30 * formatting or display inforamtion.
29 * 31 *
30 * Internally all data is stored in UTF-16, which is a fair compromise for
31 * mose text. All characters from all modern natural languages fit within
32 * the Basic Multilingual Plane, which requires only a single 16 bit value
33 * to represent it. However, when iterating through or addressing data
34 * in the Text object all work is done on a code point basis.
35 */ 32 */
36 class Text 33 class Text
37 { 34 {
@@ -43,20 +40,22 @@ namespace Bu
43 public: 40 public:
44 Text(); 41 Text();
45 Text( const Text &rSrc ); 42 Text( const Text &rSrc );
43 Text( const TextBuilder &rSrc );
46 virtual ~Text(); 44 virtual ~Text();
47 45
48 bool isEmpty() const; 46 bool isEmpty() const;
49 bool isBmpOnly() const; 47 bool isBmpOnly() const;
50 int32_t getSize() const; 48 int32_t getSize() const;
51 int32_t getSizeInBytes() const; 49 int32_t getSizeInBytes() const;
50 CodePoint operator[]( int32_t iIndex ) const;
52 51
53 uint16_t *getRawData() const; 52 CodePoint *getData() const;
54// Text transform( (CodePoint *)(*pCallback)( CodePoint * ) ); 53// Text transform( (CodePoint *)(*pCallback)( CodePoint * ) );
55 54
56 private: 55 private:
57 uint16_t *pData; 56 CodePoint *pData;
57 bool bIsBmpOnly;
58 int32_t iSize; 58 int32_t iSize;
59 int32_t iCodePoints;
60 }; 59 };
61 typedef Text::CodePoint CodePoint; 60 typedef Text::CodePoint CodePoint;
62} 61}
diff --git a/src/unstable/textbuilder.cpp b/src/unstable/textbuilder.cpp
index 73271f8..acd3501 100644
--- a/src/unstable/textbuilder.cpp
+++ b/src/unstable/textbuilder.cpp
@@ -5,4 +5,310 @@
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 CodePoint *pDest = reinterpret_cast<CodePoint *>( pDestRaw );
195
196 Chunk *pCur = pFirst;
197 while( pCur && iLength )
198 {
199 int32_t iChunkLen = pCur->iLength;
200 if( iChunkLen > iLength )
201 iChunkLen = iLength;
202
203 memcpy( pDest, pCur->pData, iChunkLen*sizeof(CodePoint) );
204 pDest += iChunkLen;
205 iLength -= iChunkLen;
206
207 pCur = pCur->pNext;
208 }
209}
210
211Bu::CodePoint Bu::TextBuilderCore::getAt( int32_t iIndex ) const
212{
213 if( iIndex < 0 || iIndex >= iLength )
214 throw Bu::ExceptionBase("Requested index is out of range.");
215
216 Chunk *pCur = pFirst;
217 while( iIndex >= pCur->iLength )
218 {
219 iIndex -= pCur->iLength;
220 pCur = pCur->pNext;
221 }
222 return pCur->pData[iIndex];
223}
224
225/////
226// TextBuilder
227//
228
229Bu::TextBuilder::TextBuilder()
230{
231}
232
233Bu::TextBuilder::TextBuilder( const Text &rSrc )
234{
235 core->append( rSrc.getData(), rSrc.getSize() );
236}
237
238Bu::TextBuilder::TextBuilder( const TextBuilder &rSrc ) :
239 Bu::SharedCore<Bu::TextBuilder, Bu::TextBuilderCore>( rSrc )
240{
241}
242
243Bu::TextBuilder::~TextBuilder()
244{
245}
246
247void Bu::TextBuilder::set( const Text &rSrc )
248{
249 _hardCopy();
250 core->set( rSrc.getData(), rSrc.getSize() );
251}
252
253void Bu::TextBuilder::append( const Text &rSrc )
254{
255 _hardCopy();
256 core->append( rSrc.getData(), rSrc.getSize() );
257}
258
259void Bu::TextBuilder::append( const CodePoint *pSrc, int32_t iLength )
260{
261 _hardCopy();
262 core->append( pSrc, iLength );
263}
264
265void Bu::TextBuilder::prepend( const Text &rSrc )
266{
267 _hardCopy();
268 core->prepend( rSrc.getData(), rSrc.getSize() );
269}
270
271void Bu::TextBuilder::insert( int32_t iBefore, const Text &rSrc )
272{
273 _hardCopy();
274 core->insert( iBefore, rSrc.getData(), rSrc.getSize() );
275}
276
277void Bu::TextBuilder::clear()
278{
279 _hardCopy();
280 core->clear();
281}
282
283int32_t Bu::TextBuilder::getSize() const
284{
285 return core->iLength;
286}
287
288Bu::Text Bu::TextBuilder::getText() const
289{
290 return Text( *this );
291}
292
293void Bu::TextBuilder::copyTo( void *pDestRaw, int32_t iDestSize ) const
294{
295 core->copyTo( pDestRaw, iDestSize );
296}
297
298Bu::CodePoint Bu::TextBuilder::operator[]( int32_t iIndex ) const
299{
300 return core->getAt( iIndex );
301}
302
303Bu::TextBuilder &Bu::TextBuilder::operator=( const Text &rSrc )
304{
305 set( rSrc );
306 return *this;
307}
308
309Bu::TextBuilder &Bu::TextBuilder::operator==( const Text &rSrc )
310{
311
312 return *this;
313}
8 314
diff --git a/src/unstable/textbuilder.h b/src/unstable/textbuilder.h
index 73271f8..8c49f2a 100644
--- a/src/unstable/textbuilder.h
+++ b/src/unstable/textbuilder.h
@@ -5,4 +5,83 @@
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
15namespace 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( int32_t iBefore, const Text &rSrc );
74 void clear();
75
76 int32_t getSize() const;
77 Text getText() const;
78 void copyTo( void *pDestRaw, int32_t iDestSize ) const;
79 CodePoint operator[]( int32_t iIndex ) const;
80
81 TextBuilder &operator=( const Text &rSrc );
82 TextBuilder &operator==( const Text &rSrc );
83 };
84}
85
86#endif
8 87
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
10Bu::TextCodec::TextCodec()
11{
12}
13
14Bu::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
14namespace 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
10Bu::TextCodecUtf8::TextCodecUtf8()
11{
12}
13
14Bu::TextCodecUtf8::~TextCodecUtf8()
15{
16}
17
18void Bu::TextCodecUtf8::encode( BlobBuilder &rTarget, const Text &rSource )
19{
20}
21
22int32_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
13namespace 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