~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/obj/Strbuf.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ---------------------------------------------------------------------------
2
 
// - Strbuf.cpp                                                              -
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.                  -
7
 
// -                                                                         -
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
 
// ---------------------------------------------------------------------------
16
 
 
17
 
#include "Ascii.hpp"
18
 
#include "Strbuf.hpp"
19
 
#include "Unicode.hpp"
20
 
 
21
 
namespace afnix {
22
 
 
23
 
  // -------------------------------------------------------------------------
24
 
  // - private section                                                       -
25
 
  // -------------------------------------------------------------------------
26
 
 
27
 
  // default buffer size
28
 
  const long BUFFER_SIZE = 1024;
29
 
 
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];
34
 
  }
35
 
 
36
 
  // -------------------------------------------------------------------------
37
 
  // - class section                                                         -
38
 
  // -------------------------------------------------------------------------
39
 
 
40
 
  // create a new buffer
41
 
 
42
 
  Strbuf::Strbuf (void) {
43
 
    d_size   = BUFFER_SIZE;
44
 
    p_buffer = new t_quad*[BUFFER_SIZE];
45
 
    d_length = 0;
46
 
  }
47
 
 
48
 
  // create a new buffer with a predefined size
49
 
 
50
 
  Strbuf::Strbuf (const long size) {
51
 
    d_size   = (size <= 0) ? BUFFER_SIZE : size;
52
 
    p_buffer = new t_quad*[d_size];
53
 
    d_length = 0;
54
 
  }
55
 
 
56
 
  // create a new buffer and initialize it with a c-string
57
 
 
58
 
  Strbuf::Strbuf (const char* value) {
59
 
    d_size   = BUFFER_SIZE;
60
 
    p_buffer = new t_quad*[BUFFER_SIZE];
61
 
    d_length = 0;
62
 
    add (value);
63
 
  }
64
 
 
65
 
  // create a new buffer and initialize it with a string
66
 
 
67
 
  Strbuf::Strbuf (const String& value) {
68
 
    d_size   = BUFFER_SIZE;
69
 
    p_buffer = new t_quad*[BUFFER_SIZE];
70
 
    d_length = 0;
71
 
    add (value);
72
 
  }
73
 
  
74
 
  // destroy this strbuf
75
 
  
76
 
  Strbuf::~Strbuf (void) {
77
 
    clrbuf (p_buffer, d_length);
78
 
    delete [] p_buffer;
79
 
  }
80
 
  
81
 
  // return the class name
82
 
 
83
 
  String Strbuf::repr (void) const {
84
 
    return "Strbuf";
85
 
  }
86
 
 
87
 
  // reset this buffer
88
 
  
89
 
  void Strbuf::reset (void) {
90
 
    wrlock ();
91
 
    clrbuf (p_buffer, d_length);
92
 
    d_length = 0;
93
 
    unlock ();
94
 
  }
95
 
 
96
 
  // return the length of this buffer
97
 
  
98
 
  long Strbuf::length (void) const {
99
 
    rdlock ();
100
 
    long result = 0;
101
 
    for (long i = 0; i < d_length; i++) {
102
 
      result += Unicode::strlen (p_buffer[i]);
103
 
    }
104
 
    unlock ();
105
 
    return result;
106
 
  }
107
 
 
108
 
  // return the non combining length of this buffer
109
 
 
110
 
  long Strbuf::ncclen (void) const {
111
 
    rdlock ();
112
 
    long result = d_length;
113
 
    unlock ();
114
 
    return result;
115
 
  }
116
 
 
117
 
  // resize this buffer
118
 
 
119
 
  void Strbuf::resize (const long size) {
120
 
    wrlock ();
121
 
    if ((size < 0) || (size < d_length)) {
122
 
      unlock ();
123
 
      return;
124
 
    }
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];
128
 
    delete [] p_buffer;
129
 
    // restore new buffer
130
 
    d_size   = size;
131
 
    p_buffer = buf;
132
 
    unlock ();
133
 
  }
134
 
 
135
 
  // add a character in this buffer
136
 
 
137
 
  void Strbuf::add (const char value) {
138
 
    wrlock ();
139
 
    try {
140
 
      add (Unicode::toquad (value));
141
 
      unlock ();
142
 
    } catch (...) {
143
 
      unlock ();
144
 
      throw;
145
 
    }
146
 
  }
147
 
 
148
 
  // add a unicode character in this buffer
149
 
  
150
 
  void Strbuf::add (const t_quad value) {
151
 
    wrlock ();
152
 
    try {
153
 
      // check for combining class
154
 
      if (Unicode::isncc (value) == true) {
155
 
        // normalize the charcater
156
 
        t_quad* buf = Unicode::strmak (value);
157
 
        if (buf == nilp) {
158
 
          unlock ();
159
 
          return;
160
 
        }
161
 
        // check for resize
162
 
        if (d_length == d_size) resize (d_size * 2);
163
 
        // add the charcater buffer
164
 
        p_buffer[d_length++] = buf;
165
 
      } else {
166
 
        // check if we have a non combining character
167
 
        // we do not add floating combining characters
168
 
        if (d_length > 0) {
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;
173
 
        }
174
 
      }
175
 
      unlock ();
176
 
    } catch (...) {
177
 
      unlock ();
178
 
      throw;
179
 
    }
180
 
  }
181
 
 
182
 
  // add a unicode character at a certain position
183
 
 
184
 
  void Strbuf::add (const t_quad value, const long pos) {
185
 
    // check for position
186
 
    if (pos < 0) return;
187
 
    wrlock ();
188
 
    try {
189
 
      // check for add at end
190
 
      if (pos >= d_length) {
191
 
        add (value);
192
 
        unlock ();
193
 
        return;
194
 
      }
195
 
      if (Unicode::isncc (value) == true) {
196
 
        t_quad* buf = Unicode::strmak (value);
197
 
        if (buf == nilp) {
198
 
          unlock ();
199
 
          return;
200
 
        }
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
206
 
        p_buffer[pos] = buf;
207
 
      } else {
208
 
        t_quad* buf = Unicode::strmak (p_buffer[pos], value);
209
 
        delete [] p_buffer[pos];
210
 
        p_buffer[pos] = buf;
211
 
      }
212
 
      unlock ();
213
 
    } catch (...) {
214
 
      unlock ();
215
 
      throw;
216
 
    }
217
 
  }
218
 
 
219
 
  // put a unicode character at a certain position
220
 
 
221
 
  void Strbuf::put (const t_quad value, const long pos) {
222
 
    // check for position
223
 
    if (pos < 0) return;
224
 
    wrlock ();
225
 
    try {
226
 
      // check for add at end
227
 
      if (pos >= d_length) {
228
 
        add (value);
229
 
        unlock ();
230
 
        return;
231
 
      }
232
 
      if (Unicode::isncc (value) == true) {
233
 
        t_quad* buf = Unicode::strmak (value);
234
 
        if (buf == nilp) {
235
 
          unlock ();
236
 
          return;
237
 
        }
238
 
        // here we are in the middle - so we replace in position
239
 
        delete [] p_buffer[pos];
240
 
        p_buffer[pos] = buf;
241
 
      } else {
242
 
        t_quad* buf = Unicode::strmak (p_buffer[pos], value);
243
 
        delete [] p_buffer[pos];
244
 
        p_buffer[pos] = buf;
245
 
      }
246
 
      unlock ();
247
 
    } catch (...) {
248
 
      unlock ();
249
 
      throw;
250
 
    }
251
 
  }
252
 
 
253
 
  // add a character buffer in this buffer
254
 
 
255
 
  void Strbuf::add (const char* s) {
256
 
    wrlock ();
257
 
    try {
258
 
      long size = Ascii::strlen (s);
259
 
      add (s, size);
260
 
      unlock ();
261
 
    } catch (...) {
262
 
      unlock ();
263
 
      throw;
264
 
    }
265
 
  }
266
 
 
267
 
  // add a character buffer in this buffer by size
268
 
  
269
 
  void Strbuf::add (const char* s, const long size) {
270
 
    if ((s == nilp) || (size == 0)) return;
271
 
    wrlock ();
272
 
    try {
273
 
      for (long i = 0; i < size; i++) add (s[i]);
274
 
      unlock ();
275
 
    } catch (...) {
276
 
      unlock ();
277
 
      throw;
278
 
    }
279
 
  }
280
 
 
281
 
  // add a unicode buffer in this buffer
282
 
 
283
 
  void Strbuf::add (const t_quad* s) {
284
 
    wrlock ();
285
 
    try {
286
 
      long size = Unicode::strlen (s);
287
 
      add (s, size);
288
 
      unlock ();
289
 
    } catch (...) {
290
 
      unlock ();
291
 
      throw;
292
 
    }
293
 
  }
294
 
 
295
 
  // add a unicode buffer in this buffer by size
296
 
  
297
 
  void Strbuf::add (const t_quad* s, const long size) {
298
 
    if ((s == nilp) || (size == 0)) return;
299
 
    wrlock ();
300
 
    try {
301
 
      for (long i = 0; i < size; i++) add (s[i]);
302
 
      unlock ();
303
 
    } catch (...) {
304
 
      unlock ();
305
 
      throw;
306
 
    }
307
 
  }
308
 
 
309
 
  // add a string in this buffer
310
 
  
311
 
  void Strbuf::add (const String& s) {
312
 
    wrlock ();
313
 
    try {
314
 
      // get the quad representation
315
 
      t_quad* buf = s.toquad ();
316
 
      // add the buffer and clean
317
 
      add (buf);
318
 
      delete [] buf;
319
 
    } catch (...) {
320
 
      unlock ();
321
 
      throw;
322
 
    }
323
 
    unlock ();
324
 
  }
325
 
   
326
 
  // remove a character at a certain position
327
 
 
328
 
  void Strbuf::chdel (const long pos) {
329
 
    // check for position
330
 
    if (pos < 0) return;
331
 
    wrlock ();
332
 
    try {
333
 
      // check if we have something to delete
334
 
      if (d_length == 0) {
335
 
        unlock ();
336
 
        return;
337
 
      }
338
 
      // try to delete at the end
339
 
      if (pos >= d_length) {
340
 
        delete [] p_buffer[--d_length];
341
 
        unlock ();
342
 
        return;
343
 
      }
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];
347
 
      d_length--;
348
 
      // done
349
 
      unlock ();
350
 
    } catch (...) {
351
 
      unlock ();
352
 
      throw;
353
 
    }
354
 
  }
355
 
 
356
 
  // return the corresponding string accumulated in this buffer
357
 
  
358
 
  String Strbuf::tostring (void) const {
359
 
    rdlock ();
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
364
 
    try {
365
 
      long idx = 0;
366
 
      for (long i = 0; i < d_length; i++) {
367
 
        t_quad* s = p_buffer[i];
368
 
        while (*s != nilq) buf[idx++] = *s++;   
369
 
      }
370
 
      buf[idx] = nilq;
371
 
      String result = buf;
372
 
      delete [] buf;
373
 
      unlock ();
374
 
      return result;
375
 
    } catch (...) {
376
 
      delete [] buf;
377
 
      unlock ();
378
 
      throw;
379
 
    }
380
 
  }
381
 
 
382
 
  // return a substring from a position to the end
383
 
 
384
 
  String Strbuf::substr (const long pos) const {
385
 
    rdlock ();
386
 
    // check for good position
387
 
    if (d_length - pos <= 0) {
388
 
      String result;
389
 
      unlock ();
390
 
      return result;
391
 
    }
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
396
 
    try {
397
 
      long idx = 0;
398
 
      for (long i = pos; i < d_length; i++) {
399
 
        t_quad* s = p_buffer[i];
400
 
        while (*s != nilq) buf[idx++] = *s++;   
401
 
      }
402
 
      buf[idx] = nilq;
403
 
      String result = buf;
404
 
      delete [] buf;
405
 
      unlock ();
406
 
      return result;
407
 
    } catch (...) {
408
 
      delete [] buf;
409
 
      unlock ();
410
 
      throw;
411
 
    }
412
 
  }
413
 
}