/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 picocpp - basic objects library for picoSQL 

 Copyright (C) Picosoft s.r.l. 1994-2002

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library 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 for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
# include "pstring.h"
static char rcsid[] = "$Id: pstring.cpp 1.2 96/09/16 15:52:14 picoSoft Exp Locker: ROOT_DOS $";
static char rcsidh[] = pstring_h;

extern "C" {
#   include <stdio.h>
#   include <string.h>
#   include <ctype.h>
#   include <stdarg.h>
#   include <stdlib.h>
}

static char intBuffer[MAX_STRING +1];

PCLASSID(PString)

char *
PString::gets() const
{
   char *Return = (char *)*data;
   return Return;
}



PString::PString(int len, char c)
{
   data = new PMemManObj(len + 1, 0, c);
   ((char *) *data)[len] = '\0';
   data->Unlock();
}

PString::PString()
{
   data = new PMemManObj(0);
}

PString::PString(const char *str)
{
   data = new PMemManObj(0);
   if (str)
      puts(str);
}

PString 
PString::operator()(long start, long len) const
{    
   start = (start < 0) ? 0 : start;
   len = (len <= size()) ?  len : size();
   long end = start + len;
   PString Return (len, ' ');
 
   char *pnt = Return.gets();
   for (int i =  start; i < end; i++)
      *(pnt++) = (*this)[i];
   return Return;
}

int
PString::compare(const char *str) const
{
   int Return = strcmp(gets(), str);
   data->Unlock();
   return Return;
}

int
PString::compare(const PString &str) const
{
   int Return = strcmp(gets(), str.gets());
   data->Unlock();
   str.data->Unlock();
   return Return;
}


long
PString::concatTo(PString *str)
{
   return(str->concat(this));
}

long
PString::concat(const PString *str)
{
   return concat(str->gets(), str->size());
}

long
PString::concat(char c)
{
   char b[2];
   b[0] = c;
   b[1] = 0;
   return concat (b,1);
}

long
PString::concat(const char *str, long n)
{
   long Return = 0;
   char *ptr;
   long i = size();
   PMemManObj tmp = *data;

   data->Alloc(i + n + 1);
   ptr = (char *)*data;
   if (ptr != NULL) {
      strcpy(ptr, (char *)tmp);
      strncpy(ptr + i, str, n);
      ptr[i+n] = '\0';
      Return = n;
   }
   data->Unlock();
   return Return;
}

long
PString::puts(const PString *str)
{
   long n = str->size();
   if (n == 0)
      data->Alloc(0);
   else {
      if (n != size())
         data->Alloc (n + 1);
      if (size() == str->size())
         strcpy((char*)*data, (char *)str->data);
      data->Unlock();
      str->data->Unlock();
   }
   return(n);
}

long
PString::puts(const char *str, int len)
{
   long n = 0;
   if (str == 0 || len <= 0)
      data->Alloc(0);
   else {
      if (len != size())
         data->Alloc (len + 1);
      if (data->sizeOf() > 0) {
         memcpy((char *)*data, str, len);
         ((char *)*data)[len] = 0;
      }
      data->Unlock();
   }
   return size();
}
long
PString::puts(const char *str)
{
   long n = 0;
   if (str) {
      n = strlen(str);
      if (n == 0)
         data->Alloc(0);
      else {
         if (n != size())
            data->Alloc (n + 1);
         if (size() == n)
            strcpy((char *)*data, str);
         data->Unlock();
      }
   }
   return(n);
}

long
PString::prints(const char *p...)
{
   va_list a;

   va_start(a, p);
   vsprintf(intBuffer, p, a);
   return(puts(intBuffer));
}

PString &
PString::operator= (char c)
{
   char b[2];
   b[0] = c;
   b[1] = 0;
   puts(b);
   return(*this);
}

PString::PString(const PString &s)
{
   data = new PMemManObj(0);
   *data = *(s.data);
}


PString::~PString()
{
   delete data;
}

PString &
PString::operator+= (const char *s)
{
   concat(s, strlen(s));
   return(*this);
}

PString
PString::operator+ (const PString &s) const
{
   PString ns(*this);
   ns += s;
   return(ns);
}

PString
PString::operator+ (const char *s) const
{
   PString ns(*this);
   ns += s;
   return(ns);
}

PString
operator+ (const char *s, const PString &p)
{
   PString ns(s);
   ns += p;
   return(ns);
}

PString
operator+ (const char c, const PString &p)
{
   char b[2];
   b[0] = c;
   b[1] = 0;
   PString ns(b);
   ns += p;
   return(ns);
}

PString
PString::operator+ (char c) const
{
   PString s(*this);
   s += c;
   return(s);
}

PString &
PString::toLower ()
{
   char *ptr = gets();

   for ( ; *ptr; ptr++)
      *ptr = tolower(*ptr);
   return *this;
}

PString &
PString::toUpper ()
{
   char *ptr = gets();

   for ( ; *ptr; ptr++)
      *ptr = toupper(*ptr);
   return *this;
}

long
PString::ToLong ()
{
   return atol (gets());
}

double
PString::ToDouble ()
{  
   return atof (gets());
} 

PString
ToPString (long num)
{
   int len;
   long t=num;
   int minus = 0;

   if (num < 0) {
      num *= -1;
      minus = 1;
   }
   for ( t=num, len=0; t > 9; t/=10 )
      len++;
   if (minus)
      len++;
   PString Return(len + 1, '0');
   for ( ; num > 9; num/=10, len-- ) {
      Return[len] = ( num%10 ) + '0';
   }
   Return[len] = num + '0';
   if (minus)
      Return[0] = '-';
   return Return;
}
