/*
 * MyString.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * 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
 * (at your option) 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 (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include "stdafx.h"

#include "MyString.h"

MyString     &MyString::operator =(const MyString &s)
{
    if ((!--_stringBuf->refs) && (_stringBuf->len != 0))
        delete _stringBuf;
    _stringBuf = s._stringBuf; 
    if (_stringBuf->refs < 0)
        assert(0); 
    _stringBuf->refs++;
    return *this;
}

MyString::MyString()
{
    _stringBuf = new StringBuf("");
}

MyString::MyString(const char *str)
{
    _stringBuf = new StringBuf(str); 
}

MyString::MyString(char c)
{
    char str[2];

    str[0] = c;  
    str[1] = '\0';
    _stringBuf = new StringBuf(str);
}

MyString::MyString(const MyString &s)
{
    _stringBuf = s._stringBuf; 
    _stringBuf->refs++; 
}

MyString::~MyString()
{
    if (!--_stringBuf->refs) 
        delete _stringBuf;
}

int
MyString::operator ==(const MyString &str) const
{
    return _stringBuf == str._stringBuf
                         || !strcmp(_stringBuf->data, str._stringBuf->data);
}

MyString &
MyString::operator +=(const char *s)
{
    int len = strlen(s);
    int newLen = _stringBuf->len + len;

    if (newLen >= _stringBuf->capacity) {
        while (newLen >= _stringBuf->capacity) {
            _stringBuf->capacity <<= 1;
        }
        _stringBuf->data = (char *) realloc(_stringBuf->data, _stringBuf->capacity);
    }
    strcpy(_stringBuf->data + _stringBuf->len, s);
    _stringBuf->len = newLen;
    return *this;
}

MyString &
MyString::operator +=(char c)
{
    char str[2];

    str[0] = c;  str[1] = '\0';
    return operator +=(str);
}

MyString &
MyString::copy(void)
{
    return *(new MyString(mystrdup((const char *)this)));
}

 
int MyString::write(int f)
{
   return mywritestr(f, _stringBuf->data);
}

int hash(MyString key) 
{
    const char  *p;
    unsigned     h = 0, g;
    for (p = (const char *) key; *p; p++) {
        h = (h << 4) + (*p);
        g = h & 0xf0000000;
        if (g) {
            h = h ^ (g >> 24);
            h = h ^ g;
        }
    }
    return h;
}

// replace string "what" with string "with"
// but do not replace if "with" is found

bool
MyString::gsubOnce(MyString what, MyString with)
{
    MyString temp = *this;
    MyString newString = "";
    for (int i = 0; i < length(); i++)
        if (strncmp(&temp[i], with, with.length()) == 0) {
            newString += with;
            i += with.length() - 1;
        } else if (strncmp(&temp[i], what, what.length()) == 0) {
            newString += with;
            i += what.length() - 1;
        } else
            newString += temp[i];
    _stringBuf = new StringBuf((const char *)newString);
    return true;
}


