833 lines
14 KiB
C++
833 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include <simstr.hxx>
|
|
|
|
#include <string.h> // strlen(), memcpy(), memset()
|
|
#include <ctype.h> // tolower()
|
|
#include <limits.h> // INT_MAX
|
|
|
|
const char NULCH = '\0';
|
|
const int NO_POS = -1;
|
|
|
|
|
|
Simstr::Simstr(const char * s_)
|
|
{
|
|
if (s_ == 0)
|
|
{
|
|
len = 0;
|
|
sz = new char[1];
|
|
*sz = 0;
|
|
}
|
|
else
|
|
{
|
|
len = (int)strlen(s_);
|
|
sz = new char[len+1];
|
|
memcpy(sz,s_,len+1);
|
|
}
|
|
}
|
|
|
|
Simstr::Simstr(const char * anybytes, int nrOfBytes)
|
|
{
|
|
if (anybytes == 0)
|
|
{
|
|
len = 0;
|
|
sz = new char[1];
|
|
*sz = 0;
|
|
return;
|
|
}
|
|
|
|
int slen = static_cast<int>( strlen(anybytes) );
|
|
|
|
len = slen < nrOfBytes
|
|
? slen
|
|
: nrOfBytes;
|
|
sz = new char[len+1];
|
|
memcpy( sz, anybytes, len );
|
|
*( sz + len ) = 0;
|
|
}
|
|
|
|
Simstr::Simstr(char c, int anzahl)
|
|
{
|
|
if (anzahl < 1)
|
|
{
|
|
len = 0;
|
|
sz = new char[1];
|
|
*sz = 0;
|
|
}
|
|
else
|
|
{
|
|
len = anzahl;
|
|
sz = new char[len+1];
|
|
memset(sz,c,anzahl);
|
|
sz[len] = 0;
|
|
}
|
|
}
|
|
|
|
Simstr::Simstr( const char * anybytes,
|
|
int firstBytesPos,
|
|
int nrOfBytes)
|
|
{
|
|
unsigned slen = (unsigned)strlen(anybytes);
|
|
if (anybytes == 0 || slen <= unsigned(firstBytesPos))
|
|
{
|
|
len = 0;
|
|
sz = new char[1];
|
|
*sz = 0;
|
|
}
|
|
else
|
|
{
|
|
int maxLen = slen - unsigned(firstBytesPos);
|
|
len = maxLen < nrOfBytes
|
|
? maxLen
|
|
: nrOfBytes;
|
|
sz = new char[len+1];
|
|
memcpy(sz,anybytes+firstBytesPos,len);
|
|
*(sz+len) = 0;
|
|
}
|
|
}
|
|
|
|
|
|
Simstr::Simstr(const Simstr & S)
|
|
{
|
|
len = S.len;
|
|
sz = new char[len+1];
|
|
memcpy(sz,S.sz,len+1);
|
|
}
|
|
|
|
Simstr & Simstr::operator=(const Simstr & S)
|
|
{
|
|
if (sz == S.sz)
|
|
return *this;
|
|
|
|
delete [] sz;
|
|
|
|
len = S.len;
|
|
sz = new char[len+1];
|
|
memcpy(sz,S.sz,len+1);
|
|
|
|
return *this;
|
|
}
|
|
|
|
Simstr::~Simstr()
|
|
{
|
|
delete [] sz;
|
|
}
|
|
|
|
char &
|
|
Simstr::ch(int n)
|
|
{
|
|
static char nullCh = NULCH;
|
|
nullCh = NULCH;
|
|
if (n >= long(len) || n < 0)
|
|
return nullCh;
|
|
else
|
|
return sz[unsigned(n)];
|
|
}
|
|
|
|
const Simstr &
|
|
Simstr::null_()
|
|
{
|
|
static Simstr aNull_;
|
|
return aNull_;
|
|
}
|
|
|
|
|
|
Simstr
|
|
Simstr::operator+(const Simstr & S) const
|
|
{
|
|
Simstr ret = sz;
|
|
ret.push_back(S);
|
|
return ret;
|
|
}
|
|
|
|
Simstr &
|
|
Simstr::operator+=(const Simstr & S)
|
|
{
|
|
push_back(S);
|
|
return *this;
|
|
}
|
|
|
|
Simstr &
|
|
Simstr::operator+=(const char * s_)
|
|
{
|
|
Simstr a(s_);
|
|
push_back(a);
|
|
return *this;
|
|
}
|
|
|
|
|
|
// REL
|
|
|
|
bool
|
|
Simstr::operator==(const Simstr & S) const
|
|
{ return !strcmp(sz,S.sz) ? true : false; }
|
|
|
|
bool
|
|
Simstr::operator!=(const Simstr & S) const
|
|
{ return strcmp(sz,S.sz) ? true : false; }
|
|
|
|
bool
|
|
Simstr::operator<(const Simstr & S) const
|
|
{ return (strcmp(sz,S.sz) < 0) ? true : false; }
|
|
|
|
bool
|
|
Simstr::operator>(const Simstr & S) const
|
|
{ return (strcmp(sz,S.sz) > 0) ? true : false; }
|
|
|
|
bool
|
|
Simstr::operator<=(const Simstr & S) const
|
|
{ return (strcmp(sz,S.sz) <= 0) ? true : false; }
|
|
|
|
bool
|
|
Simstr::operator>=(const Simstr & S) const
|
|
{ return (strcmp(sz,S.sz) >= 0) ? true : false; }
|
|
|
|
|
|
|
|
|
|
// ************** LIST - Funktionen *****************
|
|
|
|
|
|
// Einzelzugriff
|
|
|
|
char
|
|
Simstr::get(int n) const { return (n >= len || n < 0) ? 0 : sz[n]; }
|
|
|
|
char
|
|
Simstr::get_front() const { return sz[0]; }
|
|
|
|
char
|
|
Simstr::get_back() const { return len ? sz[len-1] : 0; }
|
|
|
|
Simstr
|
|
Simstr::get(int startPos, int anzahl) const
|
|
{
|
|
if (startPos >= len || startPos < 0 || anzahl < 1)
|
|
return "";
|
|
|
|
int anz = len - startPos < anzahl ? len - startPos : anzahl;
|
|
|
|
Simstr ret(' ',anz);
|
|
memcpy(ret.sz, sz+startPos, anz);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
Simstr::get_front(int anzahl) const
|
|
{
|
|
int anz = len < anzahl ? len : anzahl;
|
|
if (anz < 1)
|
|
return "";
|
|
|
|
Simstr ret(' ',anz);
|
|
memcpy(ret.sz, sz, anz);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
Simstr::get_back(int anzahl) const
|
|
{
|
|
int anz = len < anzahl ? len : anzahl;
|
|
if (anz < 1)
|
|
return "";
|
|
int start = len-anz;
|
|
|
|
Simstr ret(' ',anz);
|
|
memcpy(ret.sz, sz+start, anz);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
Simstr::get_first_token(char c) const
|
|
{
|
|
int posc = pos_first(c);
|
|
if (posc != NO_POS)
|
|
return get_front(posc);
|
|
else
|
|
return sz;
|
|
}
|
|
|
|
Simstr
|
|
Simstr::get_last_token(char c) const
|
|
{
|
|
int posc = pos_last(c);
|
|
if (posc != NO_POS)
|
|
return get_back(len-posc-1);
|
|
else
|
|
return sz;
|
|
}
|
|
|
|
|
|
|
|
// Insert
|
|
|
|
void
|
|
Simstr::insert(int pos, char c)
|
|
{
|
|
if (pos < 0 || pos > len)
|
|
return;
|
|
|
|
char * result = new char[len+2];
|
|
|
|
memcpy(result,sz,pos);
|
|
result[pos] = c;
|
|
memcpy(result+pos+1,sz+pos,len-pos+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len++;
|
|
}
|
|
|
|
void
|
|
Simstr::push_front(char c)
|
|
{
|
|
char * result = new char[len+2];
|
|
|
|
result[0] = c;
|
|
memcpy(result+1,sz,len+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len++;
|
|
}
|
|
|
|
void
|
|
Simstr::push_back(char c)
|
|
{
|
|
char * result = new char[len+2];
|
|
|
|
memcpy(result,sz,len);
|
|
result[len] = c;
|
|
result[len+1] = 0;
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len++;
|
|
}
|
|
|
|
void
|
|
Simstr::insert(int pos, const Simstr & S)
|
|
{
|
|
if (pos < 0 || pos > len)
|
|
return;
|
|
|
|
char * result = new char[len+1+S.len];
|
|
|
|
memcpy(result,sz,pos);
|
|
memcpy(result+pos,S.sz,S.len);
|
|
memcpy(result+pos+S.len,sz+pos,len-pos+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len += S.len;
|
|
}
|
|
|
|
void
|
|
Simstr::push_front(const Simstr & S)
|
|
{
|
|
char * result = new char[len+1+S.len];
|
|
|
|
memcpy(result,S.sz,S.len);
|
|
memcpy(result+S.len,sz,len+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len += S.len;
|
|
}
|
|
|
|
void
|
|
Simstr::push_back(const Simstr & S)
|
|
{
|
|
char * result = new char[len+1+S.len];
|
|
|
|
memcpy(result,sz,len);
|
|
memcpy(result+len,S.sz,S.len+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len += S.len;
|
|
}
|
|
|
|
|
|
// Remove
|
|
|
|
void
|
|
Simstr::remove(int pos, int anzahl)
|
|
{
|
|
if (pos >= len || pos < 0 || anzahl < 1)
|
|
return;
|
|
|
|
int anz = len - pos < anzahl ? len - pos : anzahl;
|
|
|
|
char * result = new char[len-anz+1];
|
|
|
|
memcpy(result,sz,pos);
|
|
memcpy(result+pos,sz+pos+anz,len-pos-anz+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len -= anz;
|
|
}
|
|
|
|
void
|
|
Simstr::remove_trailing_blanks()
|
|
{
|
|
int newlen = len-1;
|
|
for ( ; newlen > 1 && sz[newlen] <= 32; --newlen ) {}
|
|
|
|
if (newlen < len-1)
|
|
remove ( newlen+1, len-newlen);
|
|
}
|
|
|
|
void
|
|
Simstr::pop_front(int anzahl)
|
|
{
|
|
if (anzahl < 1)
|
|
return;
|
|
int anz = len < anzahl ? len : anzahl;
|
|
|
|
char * result = new char[len-anz+1];
|
|
|
|
memcpy(result,sz+anz,len-anz+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len -= anz;
|
|
}
|
|
|
|
void
|
|
Simstr::pop_back(int anzahl)
|
|
{
|
|
if (anzahl < 1)
|
|
return;
|
|
|
|
int anz = len < anzahl ? len : anzahl;
|
|
|
|
char * result = new char[len-anz+1];
|
|
|
|
memcpy(result,sz,len-anz);
|
|
result[len-anz] = 0;
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len -= anz;
|
|
}
|
|
|
|
void
|
|
Simstr::rem_back_from(int removeStartPos)
|
|
{
|
|
if (removeStartPos != NO_POS)
|
|
pop_back(len-removeStartPos);
|
|
}
|
|
|
|
void
|
|
Simstr::remove_all(char c)
|
|
{
|
|
if (!len)
|
|
return;
|
|
char * result = new char[len];
|
|
int i,j=0;
|
|
for (i = 0; i < len; i++)
|
|
if (sz[i] != c)
|
|
result[j++] = sz[i];
|
|
|
|
delete [] sz;
|
|
sz = new char[j+1];
|
|
memcpy(sz,result,j);
|
|
sz[j] = 0;
|
|
len = j;
|
|
delete [] result;
|
|
}
|
|
|
|
void
|
|
Simstr::remove_all(const Simstr & S)
|
|
{
|
|
int pos;
|
|
while ( (pos=pos_first(S)) != NO_POS )
|
|
remove(pos,S.len);
|
|
}
|
|
|
|
void
|
|
Simstr::strip(char c)
|
|
{
|
|
int start = 0;
|
|
if (c == ' ')
|
|
{ // Sonderbehandlung: SPC entfernt auch TABs:
|
|
while ( start < len
|
|
? sz[start] == ' '
|
|
|| sz[start] == '\t'
|
|
: false )
|
|
start++;
|
|
}
|
|
else
|
|
{
|
|
while (start < len && sz[start] == c)
|
|
start++;
|
|
}
|
|
|
|
int ende = len-1;
|
|
if (c == ' ')
|
|
{ // Sonderbehandlung: SPC entfernt auch TABs:
|
|
while ( ende >= start
|
|
? sz[ende] == ' '
|
|
|| sz[ende] == '\t'
|
|
: false )
|
|
ende--;
|
|
}
|
|
else
|
|
{
|
|
while (ende >= start && sz[ende] == c)
|
|
ende--;
|
|
}
|
|
*this = get(start,ende-start+1);
|
|
}
|
|
|
|
void
|
|
Simstr::empty()
|
|
{
|
|
if (len > 0)
|
|
{
|
|
delete [] sz;
|
|
sz = new char[1];
|
|
*sz = 0;
|
|
len = 0;
|
|
}
|
|
}
|
|
|
|
Simstr
|
|
Simstr::take_first_token(char c)
|
|
{
|
|
Simstr ret;
|
|
int pos = pos_first(c);
|
|
if (pos != NO_POS)
|
|
{
|
|
ret = get_front(pos);
|
|
pop_front(pos+1);
|
|
}
|
|
else
|
|
{
|
|
ret = sz;
|
|
delete [] sz;
|
|
sz = new char[1];
|
|
*sz = NULCH;
|
|
len = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
Simstr::take_last_token(char c)
|
|
{
|
|
Simstr ret;
|
|
int pos = pos_last(c);
|
|
if (pos != NO_POS)
|
|
{
|
|
ret = get_back(len-pos-1);
|
|
pop_back(len-pos);
|
|
}
|
|
else
|
|
{
|
|
ret = sz;
|
|
delete [] sz;
|
|
sz = new char[1];
|
|
*sz = NULCH;
|
|
len = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
// Find
|
|
|
|
int
|
|
Simstr::pos_first(char c) const
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < len ? sz[i] != c : false; i++) ;
|
|
if (i >= len)
|
|
return NO_POS;
|
|
else
|
|
return i;
|
|
}
|
|
|
|
int
|
|
Simstr::pos_first_after( char c,
|
|
int startSearchPos) const
|
|
{
|
|
int i = 0;
|
|
if (startSearchPos >= i)
|
|
i = startSearchPos+1;
|
|
for (; i < len ? sz[i] != c : false; i++) ;
|
|
if (i >= len)
|
|
return NO_POS;
|
|
else
|
|
return i;
|
|
}
|
|
|
|
|
|
int
|
|
Simstr::pos_last(char c) const
|
|
{
|
|
int i = 0;
|
|
for (i = len-1; i >= 0 ? sz[i] != c : false; i--) ;
|
|
if (i < 0)
|
|
return NO_POS;
|
|
else
|
|
return i;
|
|
}
|
|
|
|
int
|
|
Simstr::pos_first(const Simstr & S) const
|
|
{
|
|
char * ptr = strstr(sz,S.sz);
|
|
if (ptr)
|
|
return int(ptr-sz);
|
|
else
|
|
return NO_POS;
|
|
}
|
|
|
|
int
|
|
Simstr::pos_last(const Simstr & S) const
|
|
{
|
|
Simstr vgl;
|
|
int i;
|
|
for (i = len-S.len; i >= 0 ; i--)
|
|
{
|
|
vgl = get(i,S.len);
|
|
if (vgl == S)
|
|
break;
|
|
}
|
|
if (i >= 0)
|
|
return i;
|
|
else
|
|
return NO_POS;
|
|
}
|
|
|
|
int
|
|
Simstr::count(char c) const
|
|
{
|
|
int ret = 0;
|
|
for (int i =0; i < len; i++)
|
|
if (sz[i] == c)
|
|
ret++;
|
|
return ret;
|
|
}
|
|
|
|
bool
|
|
Simstr::is_no_text() const
|
|
{
|
|
if (!len)
|
|
return true;
|
|
|
|
int i;
|
|
for (i = 0; sz[i] <= 32 && i < len; i++) ;
|
|
if (i < len)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
// Change
|
|
|
|
void
|
|
Simstr::replace(int pos, char c)
|
|
{
|
|
if (pos < 0 || pos >= len)
|
|
return;
|
|
else
|
|
sz[unsigned(pos)] = c;
|
|
}
|
|
|
|
void
|
|
Simstr::replace(int startPos, int anzahl, const Simstr & S)
|
|
{
|
|
if (startPos >= len || startPos < 0 || anzahl < 1)
|
|
return;
|
|
|
|
int anz = len - startPos < anzahl ? len - startPos : anzahl;
|
|
|
|
char * result = new char[len-anz+S.len+1];
|
|
|
|
memcpy(result,sz,startPos);
|
|
memcpy(result+startPos, S.sz, S.len);
|
|
memcpy(result+startPos+S.len, sz+startPos+anz, len-startPos-anz+1);
|
|
|
|
delete [] sz;
|
|
sz = result;
|
|
len = len-anz+S.len;
|
|
}
|
|
|
|
void
|
|
Simstr::replace_all(char oldCh, char newCh)
|
|
{
|
|
for (int i=0; i < len; i++)
|
|
if (sz[i] == oldCh)
|
|
sz[i] = newCh;
|
|
}
|
|
|
|
void
|
|
Simstr::replace_all(const Simstr & oldS, const Simstr & newS)
|
|
{
|
|
Simstr vgl;
|
|
int i = 0;
|
|
while (i <= len-oldS.len)
|
|
{
|
|
vgl = get(i,oldS.len);
|
|
if (strcmp(vgl.sz,oldS.sz) == 0)
|
|
{
|
|
replace(i,oldS.len,newS);
|
|
i += newS.len;
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void
|
|
Simstr::to_lower()
|
|
{
|
|
for (int i = 0; i < len; i++)
|
|
sz[i] = (char) tolower(sz[i]);
|
|
}
|
|
|
|
|
|
|
|
// Simstr addition
|
|
Simstr
|
|
operator+(const char * str, const Simstr & S)
|
|
{
|
|
Simstr ret = S;
|
|
ret.push_front(str);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
operator+(const Simstr & S, const char * str)
|
|
{
|
|
Simstr ret = S;
|
|
ret.push_back(str);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
operator+(char c, const Simstr & S)
|
|
{
|
|
Simstr ret = S;
|
|
ret.push_front(c);
|
|
return ret;
|
|
}
|
|
|
|
Simstr
|
|
operator+(const Simstr & S, char c)
|
|
{
|
|
Simstr ret = S;
|
|
ret.push_back(c);
|
|
return ret;
|
|
}
|
|
|
|
|
|
// Simstr-Vergleiche mit char *
|
|
bool
|
|
operator==(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) == 0;
|
|
}
|
|
|
|
bool
|
|
operator!=(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) != 0;
|
|
}
|
|
|
|
bool
|
|
operator<(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) < 0;
|
|
}
|
|
|
|
bool
|
|
operator>(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) > 0;
|
|
}
|
|
|
|
bool
|
|
operator<=(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) <= 0;
|
|
}
|
|
|
|
bool
|
|
operator>=(const Simstr & S, const char * str)
|
|
{
|
|
return strcmp(S,str) >= 0;
|
|
}
|
|
|
|
bool
|
|
operator==(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) == 0;
|
|
}
|
|
|
|
bool
|
|
operator!=(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) != 0;
|
|
}
|
|
|
|
bool
|
|
operator<(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) < 0;
|
|
}
|
|
|
|
bool
|
|
operator>(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) > 0;
|
|
}
|
|
|
|
bool
|
|
operator<=(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) <= 0;
|
|
}
|
|
|
|
bool
|
|
operator>=(const char * str, const Simstr & S)
|
|
{
|
|
return strcmp(str,S) >= 0;
|
|
}
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|