--- /dev/null
+// 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 <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;
+ // 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;
+}