// String.C -*- C++ -*- // Copyright (c) 1997, 1998 Etienne BERNARD // Copyright (C) 2002,2005 Clinton Ebadi // 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 #include #include 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; // We do this instead of just s.length () because there might be a // \0 in the string before the end (e.g. this is a message from the // Socket's buffer). const char* temp_str = s.c_str (); len = strlen (temp_str); p->s = new char[len + 1]; std::strcpy (p->s, temp_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::substr (int s, int e) { return subString (s, e); } String String::subString(int debut) { return subString(debut, len - 1); } String String::substr (int s) { return subString (s); } 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[j] == '\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; }