1
// ---------------------------------------------------------------------------
3
// - standard object library - string buffer class implementation -
4
// ---------------------------------------------------------------------------
5
// - This program is free software; you can redistribute it and/or modify -
6
// - it provided that this copyright notice is kept intact. -
8
// - This program is distributed in the hope that it will be useful, but -
9
// - without any warranty; without even the implied warranty of -
10
// - merchantability or fitness for a particular purpose. In no event shall -
11
// - the copyright holder be liable for any direct, indirect, incidental or -
12
// - special damages arising in any way out of the use of this software. -
13
// ---------------------------------------------------------------------------
14
// - copyright (c) 1999-2007 amaury darsch -
15
// ---------------------------------------------------------------------------
19
#include "Unicode.hpp"
23
// -------------------------------------------------------------------------
24
// - private section -
25
// -------------------------------------------------------------------------
27
// default buffer size
28
const long BUFFER_SIZE = 1024;
30
// this procedure clean a string buffer by length
31
static void clrbuf (t_quad** buf, const long len) {
32
if ((buf == nilp) || (len <= 0)) return;
33
for (long i = 0; i < len; i++) delete [] buf[i];
36
// -------------------------------------------------------------------------
38
// -------------------------------------------------------------------------
40
// create a new buffer
42
Strbuf::Strbuf (void) {
44
p_buffer = new t_quad*[BUFFER_SIZE];
48
// create a new buffer with a predefined size
50
Strbuf::Strbuf (const long size) {
51
d_size = (size <= 0) ? BUFFER_SIZE : size;
52
p_buffer = new t_quad*[d_size];
56
// create a new buffer and initialize it with a c-string
58
Strbuf::Strbuf (const char* value) {
60
p_buffer = new t_quad*[BUFFER_SIZE];
65
// create a new buffer and initialize it with a string
67
Strbuf::Strbuf (const String& value) {
69
p_buffer = new t_quad*[BUFFER_SIZE];
74
// destroy this strbuf
76
Strbuf::~Strbuf (void) {
77
clrbuf (p_buffer, d_length);
81
// return the class name
83
String Strbuf::repr (void) const {
89
void Strbuf::reset (void) {
91
clrbuf (p_buffer, d_length);
96
// return the length of this buffer
98
long Strbuf::length (void) const {
101
for (long i = 0; i < d_length; i++) {
102
result += Unicode::strlen (p_buffer[i]);
108
// return the non combining length of this buffer
110
long Strbuf::ncclen (void) const {
112
long result = d_length;
117
// resize this buffer
119
void Strbuf::resize (const long size) {
121
if ((size < 0) || (size < d_length)) {
125
// allocate and copy the new buffer
126
t_quad** buf = new t_quad*[size];
127
for (long i = 0; i < d_length; i++) buf[i] = p_buffer[i];
129
// restore new buffer
135
// add a character in this buffer
137
void Strbuf::add (const char value) {
140
add (Unicode::toquad (value));
148
// add a unicode character in this buffer
150
void Strbuf::add (const t_quad value) {
153
// check for combining class
154
if (Unicode::isncc (value) == true) {
155
// normalize the charcater
156
t_quad* buf = Unicode::strmak (value);
162
if (d_length == d_size) resize (d_size * 2);
163
// add the charcater buffer
164
p_buffer[d_length++] = buf;
166
// check if we have a non combining character
167
// we do not add floating combining characters
169
long index = d_length - 1;
170
t_quad* buf = Unicode::strmak (p_buffer[index], value);
171
delete [] p_buffer[index];
172
p_buffer[index] = buf;
182
// add a unicode character at a certain position
184
void Strbuf::add (const t_quad value, const long pos) {
185
// check for position
189
// check for add at end
190
if (pos >= d_length) {
195
if (Unicode::isncc (value) == true) {
196
t_quad* buf = Unicode::strmak (value);
201
// here we are in the middle - so we need to shift first
202
// and the add in position - but first we check for resize
203
if (d_length == d_size) resize (d_size * 2);
204
for (long i = d_length; i > pos; i--) p_buffer[i] = p_buffer[i-1];
205
// the insert slot is free so we can add in position
208
t_quad* buf = Unicode::strmak (p_buffer[pos], value);
209
delete [] p_buffer[pos];
219
// put a unicode character at a certain position
221
void Strbuf::put (const t_quad value, const long pos) {
222
// check for position
226
// check for add at end
227
if (pos >= d_length) {
232
if (Unicode::isncc (value) == true) {
233
t_quad* buf = Unicode::strmak (value);
238
// here we are in the middle - so we replace in position
239
delete [] p_buffer[pos];
242
t_quad* buf = Unicode::strmak (p_buffer[pos], value);
243
delete [] p_buffer[pos];
253
// add a character buffer in this buffer
255
void Strbuf::add (const char* s) {
258
long size = Ascii::strlen (s);
267
// add a character buffer in this buffer by size
269
void Strbuf::add (const char* s, const long size) {
270
if ((s == nilp) || (size == 0)) return;
273
for (long i = 0; i < size; i++) add (s[i]);
281
// add a unicode buffer in this buffer
283
void Strbuf::add (const t_quad* s) {
286
long size = Unicode::strlen (s);
295
// add a unicode buffer in this buffer by size
297
void Strbuf::add (const t_quad* s, const long size) {
298
if ((s == nilp) || (size == 0)) return;
301
for (long i = 0; i < size; i++) add (s[i]);
309
// add a string in this buffer
311
void Strbuf::add (const String& s) {
314
// get the quad representation
315
t_quad* buf = s.toquad ();
316
// add the buffer and clean
326
// remove a character at a certain position
328
void Strbuf::chdel (const long pos) {
329
// check for position
333
// check if we have something to delete
338
// try to delete at the end
339
if (pos >= d_length) {
340
delete [] p_buffer[--d_length];
344
// delete in place and shift
345
delete [] p_buffer[pos];
346
for (long i = pos; i < d_length; i++) p_buffer[i] = p_buffer[i+1];
356
// return the corresponding string accumulated in this buffer
358
String Strbuf::tostring (void) const {
360
// create a temporary buffer to hold the characters
361
long len = length ();
362
t_quad* buf = new t_quad[len+1];
363
// build the result string
366
for (long i = 0; i < d_length; i++) {
367
t_quad* s = p_buffer[i];
368
while (*s != nilq) buf[idx++] = *s++;
382
// return a substring from a position to the end
384
String Strbuf::substr (const long pos) const {
386
// check for good position
387
if (d_length - pos <= 0) {
392
// allocate a buffer to store the result
393
long len = length ();
394
t_quad* buf = new t_quad[len+1];
395
// copy the characters in the buffer
398
for (long i = pos; i < d_length; i++) {
399
t_quad* s = p_buffer[i];
400
while (*s != nilq) buf[idx++] = *s++;