1
// ---------------------------------------------------------------------------
3
// - standard object library - string vector 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
// ---------------------------------------------------------------------------
21
#include "Unicode.hpp"
22
#include "Integer.hpp"
23
#include "Exception.hpp"
27
// -------------------------------------------------------------------------
28
// - private section -
29
// -------------------------------------------------------------------------
31
// check that a character is in the c-string.
32
static bool match_break_sequence (const t_quad c, const t_quad* str) {
33
long size = Unicode::strlen (str);
35
for (long i = 0; i < size; i++)
36
if (c == str[i]) return true;
40
// -------------------------------------------------------------------------
42
// -------------------------------------------------------------------------
44
// split this string with a sequence of characters
46
Strvec Strvec::split (const String& name, const String& sbrk) {
50
// first thing first - do we have a nil string
51
if (name.length () == 0) return result;
53
// get a unicode string representation
54
t_quad* data = name.toquad ();
56
// fix the break sequence in case it is nil
57
const t_quad* cbrk = (sbrk.length () == 0) ? Unicode::strdup (" \t\n") :
59
// loop and accumulate - if a character match the break sequence
60
// the buffer is inserted into the vector
63
while ((c = *data++) != nilp) {
64
if (match_break_sequence (c, cbrk) == true) {
65
result.add (buffer.tostring());
71
// check if the buffer is not empty
72
if (buffer.length () != 0) result.add (buffer.tostring());
73
// clean the break sequence and return
79
// split this string with a default break sequence
81
Strvec Strvec::split (const String& name) {
82
return Strvec::split (name, "");
85
// -------------------------------------------------------------------------
87
// -------------------------------------------------------------------------
89
// create an empty string vector
91
Strvec::Strvec (void) {
97
// create a string vector with an original size
99
Strvec::Strvec (const long size) {
100
if (size < 0) throw Exception ("size-error","negative strvec size");
103
p_vector = new String[d_size];
106
// copy constructor for this string vector
108
Strvec::Strvec (const Strvec& that) {
111
d_size = that.d_length;
112
d_length = that.d_length;
114
// create a new vector of strings and copy them
115
if ((d_length > 0) && (that.p_vector != nilp)) {
116
p_vector = new String[d_length];
117
for (long i = 0; i < d_length; i++) p_vector[i] = that.p_vector[i];
122
// destroy this string vector
124
Strvec::~Strvec (void) {
128
// return the class name
130
String Strvec::repr (void) const {
134
// return the string vector serial code
136
t_byte Strvec::serialid (void) const {
137
return SERIAL_STRV_ID;
140
// serialize this string vector
142
void Strvec::wrstream (Output& os) const {
145
// write the vector length
146
Integer vlen (d_length);
149
for (long i = 0; i < d_length; i++) {
150
p_vector[i].wrstream (os);
159
// deserialize this string vector
161
void Strvec::rdstream (Input& is) {
164
// reset the string vector
166
// get the vector length
169
long len = vlen.tointeger ();
170
// read in each object
171
for (long i = 0; i < len; i++) {
184
// assign a string vector to this one
186
Strvec& Strvec::operator = (const Strvec& that) {
187
// check againt equal equal
188
if (this == &that) return *this;
195
d_size = that.d_length;
196
d_length = that.d_length;
198
// create a new string vector of strings and copy them
199
if ((d_length > 0) && (that.p_vector != nilp)) {
200
p_vector = new String[d_size];
201
for (long i = 0; i < d_length; i++) p_vector[i] = that.p_vector[i];
210
void Strvec::reset (void) {
219
// return true if the vector is empty
221
bool Strvec::empty (void) const {
223
bool result = (d_length == 0);
228
// check that a string exists in this vector
230
bool Strvec::exists (const String& name) const {
237
for (long i = 0; i < d_length; i++) {
238
if (p_vector[i] == name) {
251
// get the number of element in this string vector
253
long Strvec::length (void) const {
255
long result = d_length;
260
// add a new element in this string vector
262
void Strvec::add (const String& str) {
265
// check if we have to resize the Strvec
266
if (d_length + 1 >= d_size) {
267
long size = (d_size <= 0) ? 1 : d_size * 2;
268
String* vector = new String[size];
269
for (long i = 0; i < d_length; i++) vector[i] = p_vector[i];
274
// set the string in this Strvec
275
p_vector[d_length++] = str;
283
// set an string at a certain position in this vector
284
// the old string is destroyed
286
void Strvec::set (const long index, const String& str) {
289
// check that we are bounded
290
if (index >= d_length)
291
throw Exception ("index-error","in string vector set");
292
p_vector[index] = str;
300
// pop the first string from this vector
302
String Strvec::pop (void) {
305
// check that the vector is not empty
307
throw Exception ("pop-error", "pop request with empty vector");
310
String result = p_vector[0];
311
// compress the vector
312
for (long i = 1; i < d_length; i++) {
313
p_vector[i-1] = p_vector[i];
315
// clear last element
316
p_vector[--d_length] = "";
326
// pop the last string from this vector
328
String Strvec::rml (void) {
331
// check that the vector is not empty
333
throw Exception ("rml-error", "rml request with empty vector");
336
String result = p_vector[d_length-1];
337
// clear last element
338
p_vector[--d_length] = "";
348
// get an string at a certain position
350
String Strvec::get (const long index) const {
353
// check that we are bounded
354
if (index >= d_length)
355
throw Exception ("index-error","in string vector set");
356
const String& result = p_vector[index];
365
// return the first string in this vector
367
String Strvec::first (void) const {
370
String result = get (0);
379
// return the last string in this vector
381
String Strvec::last (void) const {
384
String result = get (d_length-1);
393
// return the index of a key or -1
395
long Strvec::find (const String& key) const {
398
for (long i = 0; i < d_length; i++) {
399
if (p_vector[i] == key) {
412
// return the index of a key in this string vector
414
long Strvec::lookup (const String& key) const {
417
for (long i = 0; i < d_length; i++) {
418
if (p_vector[i] == key) {
423
throw Exception ("key-error", "key not found", key);
430
// remove an entry by index and repack the vector
432
void Strvec::remove (const long index) {
435
if ((index < 0) || (index >= d_length)) {
436
throw Exception ("index-error","index is out of range");
439
long mark = d_length - 1;
440
for (long i = index; i < mark; i++) {
441
p_vector[i] = p_vector[i+1];
452
// remove an entry by value if it exists
454
void Strvec::remove (const String& key) {
458
long index = find (key);
460
if (index != -1) remove (index);
467
// return the maximum string length in this vector
469
long Strvec::maxlen (void) const {
473
for (long i = 0; i < d_length; i++) {
474
long len = p_vector[i].length ();
475
if (len > result) result = len;
485
// return the minimum string length in this vector
487
long Strvec::minlen (void) const {
491
for (long i = 0; i < d_length; i++) {
492
long len = p_vector[i].length ();
493
if (len < result) result = len;
503
// return an array of quarks for this vector
505
long* Strvec::toquarks (void) const {
512
long* result = new long[d_length];
513
for (long i = 0; i < d_length; i++) result[i] = p_vector[i].toquark ();
522
// retrun a vector of strings
524
Vector* Strvec::tovector (void) const {
526
Vector* result = new Vector;
532
for (long i = 0; i < d_length; i++) {
533
result->append (new String (p_vector[i]));