// String.C -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "String.H"
#include <cstring>
#include <cctype>
#include <sstream>
String::String()
{
p = new srep;
len = 0;
p->s = 0;
}
String::String(const char *s)
{
p = new srep;
len = strlen(s);
p->s = new char[len + 1];
std::strcpy(p->s, s);
}
String::String(const std::string & s)
{
p = new srep;
len = s.length ();
p->s = new char[len + 1];
std::strcpy (p->s, s.c_str ());
}
String::String(const String & s)
{
s.p->n++;
p = s.p;
len = s.len;
}
String::String(long i)
{
std::ostringstream temp;
temp << i;
p = new srep;
len = strlen(temp.str().c_str ());
p->s = new char[len + 1];
strcpy(p->s, temp.str().c_str ());
}
String::String(char c)
{
p = new srep;
p->s = new char[2];
p->s[0] = c;
p->s[1] = '\0';
len = 1;
}
String::~String()
{
if (--p->n == 0) {
delete[] p->s;
delete p;
}
}
String &
String::operator=(const char *s)
{
if (p->n > 1) {
p->n--;
p = new srep;
}
else
delete[] p->s;
len = strlen(s);
p->s = new char[len + 1];
strcpy(p->s, s);
return *this;
}
String &
String::operator=(const String & s)
{
s.p->n++; // protection contre st = st
if (--p->n == 0) {
delete[] p->s;
delete p;
}
p = s.p;
len = s.len;
return *this;
}
String &
String::operator=(const std::string & s)
{
if (p->n > 1) {
p->n--;
p = new srep;
}
else
delete[] p->s;
len = s.length ();
p->s = new char[len + 1];
strcpy(p->s, s.c_str ());
return *this;
}
int
String::length() const
{
return len;
}
int
String::find(char c)
{
if (!strchr(p->s, c))
return -1;
return (int)(strchr(p->s, c) - p->s);
}
void
String::fill(char c)
{
for (char * s = p->s; *s; s++)
*s = c;
}
String
String::pad(int n)
{
int l = len;
if (n <= l)
return subString(0, n-1);
char *temp = new char[n+1];
strcpy(temp, p->s);
for (int i = l; i < n; i++)
temp[i] = ' ';
temp[n] = '\0';
String res(temp);
delete temp;
return res;
}
String
String::subString(int debut, int fin)
{
if (fin < debut) return "";
char * temp = new char[fin-debut+2];
strncpy(temp, p->s + debut, fin - debut + 1);
temp[fin - debut + 1] = '\0';
String res(temp);
delete temp;
return res;
}
String
String::subString(int debut)
{
return subString(debut, len - 1);
}
String
String::toLower()
{
char *temp = new char[len + 1];
for (int i = 0; i < len + 1; i++)
if (isupper(p->s[i]))
temp[i] = tolower(p->s[i]);
else
temp[i] = p->s[i];
String res(temp);
delete temp;
return res;
}
String
String::toUpper()
{
char *temp = new char[len + 1];
for (int i = 0; i < len + 1; i++)
if (islower(p->s[i]))
temp[i] = toupper(p->s[i]);
else
temp[i] = p->s[i];
String res(temp);
delete temp;
return res;
}
String
String::trim()
{
int i = 0, j = len - 1;
while (i < j && (p->s[i] == ' ' || p->s[i] == '\t' || p->s[i] == '\r'))
i++;
while (j > 0 && (p->s[j] == ' ' || p->s[j] == '\t' || p->s[i] == '\r'))
j--;
return subString(i, j);
}
int
String::indexOf(char c)
{
char *s = std::strchr(p->s, c);
if (s)
return p->s - s;
return -1;
}
char &
String::operator[](int i)
{
if (i < 0 || len < i) {
std::cerr << "String index out of range\n";
std::exit(1);
}
return p->s[i];
}
const char &
String::operator[](int i) const
{
if (i < 0 || len < i) {
std::cerr << "String index out of range\n";
exit(1);
}
return p->s[i];
}
bool
String::operator==(const char *s) const
{
return std::strcmp(p->s, s) == 0;
}
bool
String::operator==(const String & s) const
{
return (p == s.p) || (std::strcmp(p->s, s.p->s) == 0);
}
bool
String::operator==(const std::string & s) const
{
return (p->s == s.c_str ()) || (std::strcmp (p->s, s.c_str()) == 0);
}
bool
String::operator!=(const char *s) const
{
return std::strcmp(p->s, s) != 0;
}
bool
String::operator!=(const String & s) const
{
return std::strcmp(p->s, s.p->s) != 0;
}
bool
String::operator!=(const std::string & s) const
{
return ! (*this == s);
}
bool
String::operator<(const String & s) const
{
return std::strcmp(p->s, s.p->s) < 0;
}
bool
String::operator<(const std::string & s) const
{
return std::strcmp(p->s, s.c_str ()) < 0;
}
bool
String::operator>(const String & s) const
{
return std::strcmp(p->s, s.p->s) > 0;
}
bool
String::operator<=(const String & s) const
{
return std::strcmp(p->s, s.p->s) <= 0;
}
bool
String::operator<=(const std::string & s) const
{
return (*this < s) || (*this == s);
}
bool
String::operator>=(const String & s) const
{
return std::strcmp(p->s, s.p->s) >= 0;
}
bool String::operator>=(const std::string & s) const
{
return ! (*this < s);
}
String
String::operator+(const char *s)
{
char *temp = new char[len + std::strlen(s) + 1];
std::strcpy(temp, p->s);
std::strcat(temp, s);
String res(temp);
delete temp;
return res;
}
String
String::operator+(const String & s)
{
char * temp = new char[len + s.len + 1];
std::strcpy(temp, p->s);
std::strcat(temp, s.p->s);
String res(temp);
delete temp;
return res;
}
String
String::operator+(const std::string & s)
{
char * temp = new char[len + s.length () + 1];
std::strcpy (temp, p->s);
std::strcat (temp, s.c_str ());
String res (temp);
delete temp;
return res;
}
String::operator const char *() const
{
return p->s;
}
String::operator std::string () const
{
return std::string (p->s);
}
std::ostream &
operator<<(std::ostream & s, const String & st)
{
return s << st.p->s;
}
std::istream &
operator>>(std::istream & s, String & st)
{
if (st.p->n > 1) {
st.p->n--;
st.p = new String::srep;
}
else
delete[] st.p->s;
char buf[2048];
char c;
s.getline (buf, 2048, '\n');
//s.get(c);
st.len = strlen(buf);
st.p->s = new char[st.len + 1];
strcpy(st.p->s, buf);
return s;
}
std::string operator+(const std::string & s, const String & p)
{
std::string temp = s;
temp += p.p->s;
return temp;
}
bool operator==(const std::string & s, const String & p)
{
return p == s;
}
bool operator!=(const std::string & s, const String & p)
{
return p != s;
}
bool operator>(const std::string & s, const String & p)
{
return p <= s;
}
bool operator<(const std::string & s, const String & p)
{
return p >= s;
}
bool operator<=(const std::string & s, const String & p)
{
return p > s;
}
bool operator>=(const std::string & s, const String & p)
{
return p < s;
}
syntax highlighted by Code2HTML, v. 0.9.1