/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_soltools.hxx"


#include <simstr.hxx>

#include <string.h>  // strlen(), memcpy(), memset()
#include <ctype.h>   // tolower()
#include <limits.h>  // INT_MAX

const char NULCH = '\0';
const int  NO_POS = -1;


Simstr::Simstr(const char * s_)
{
   if (s_ == 0)
      {
         len = 0;
         sz = new char[1];
         *sz = 0;
      }
   else
      {
         len = strlen(s_);
         sz = new char[len+1];
         memcpy(sz,s_,len+1);
      }
}

Simstr::Simstr(const char * anybytes, int  nrOfBytes)
{
    if (anybytes == 0)
    {
	    len = 0;
		sz = new char[1];
		*sz = 0;
        return;
    }

    int slen = static_cast<int>( strlen(anybytes) );

    len =  slen < nrOfBytes
                  ? slen
                  : nrOfBytes;
    sz = new char[len+1];
    memcpy( sz, anybytes, len );
    *( sz + len ) = 0;
}

Simstr::Simstr(char c, int anzahl)
{
   if (anzahl < 1)
      {
         len = 0;
         sz = new char[1];
         *sz = 0;
      }
   else
      {
         len = anzahl;
         sz = new char[len+1];
         memset(sz,c,anzahl);
         sz[len] = 0;
      }
}

Simstr::Simstr( const char *   anybytes,
				int            firstBytesPos,
				int            nrOfBytes)
{
   unsigned slen = strlen(anybytes);
   if (anybytes == 0 || slen <= unsigned(firstBytesPos))
	  {
		 len = 0;
		 sz = new char[1];
		 *sz = 0;
	  }
   else
	  {
         int maxLen = slen - unsigned(firstBytesPos);
         len =  maxLen < nrOfBytes
                  ? maxLen
                  : nrOfBytes;
         sz = new char[len+1];
         memcpy(sz,anybytes+firstBytesPos,len);
         *(sz+len) = 0;
      }
}


Simstr::Simstr(const Simstr & S)
{
   len = S.len;
   sz = new char[len+1];
   memcpy(sz,S.sz,len+1);
}

Simstr & Simstr::operator=(const Simstr & S)
{
   if (sz == S.sz)
      return *this;

   delete [] sz;

   len = S.len;
   sz = new char[len+1];
   memcpy(sz,S.sz,len+1);

   return *this;
}

Simstr::~Simstr()
{
   delete [] sz;
}

char &
Simstr::ch(int  n)
{
   static char nullCh = NULCH;
   nullCh = NULCH;
   if (n >= long(len) || n < 0)
      return nullCh;
   else
      return sz[unsigned(n)];
}

const Simstr &
Simstr::null_()
{
    static Simstr aNull_;
    return aNull_;
}


Simstr
Simstr::operator+(const Simstr & S) const
{
   Simstr ret = sz;
   ret.push_back(S);                                         
   return ret;
}

Simstr &     
Simstr::operator+=(const Simstr & S)
{
   push_back(S);
   return *this;
}

Simstr &
Simstr::operator+=(const char * s_)
{
    Simstr a(s_);
    push_back(a);
    return *this;
}


// REL

bool
Simstr::operator==(const Simstr & S) const
{ return !strcmp(sz,S.sz) ? true : false; }

bool
Simstr::operator!=(const Simstr & S) const
{ return strcmp(sz,S.sz) ? true : false; }

bool  
Simstr::operator<(const Simstr & S) const 
{ return (strcmp(sz,S.sz) < 0) ? true : false; }

bool  
Simstr::operator>(const Simstr & S) const 
{ return (strcmp(sz,S.sz) > 0) ? true : false; }

bool
Simstr::operator<=(const Simstr & S) const 
{ return (strcmp(sz,S.sz) <= 0) ? true : false; }

bool  
Simstr::operator>=(const Simstr & S) const 
{ return (strcmp(sz,S.sz) >= 0) ? true : false; }




// **************          LIST - Funktionen        *****************

   
// Einzelzugriff

char
Simstr::get(int  n) const     { return (n >= len || n < 0) ? 0 : sz[n]; }

char 
Simstr::get_front() const        { return sz[0]; }

char 
Simstr::get_back() const        { return  len ? sz[len-1] : 0; }

Simstr 
Simstr::get(int  startPos, int  anzahl) const
{
   if (startPos >= len || startPos < 0 || anzahl < 1)
      return "";

   int anz = len - startPos < anzahl ? len - startPos : anzahl;

   Simstr ret(' ',anz);
   memcpy(ret.sz, sz+startPos, anz);
   return ret;
}

Simstr
Simstr::get_front(int  anzahl) const
{
   int anz = len < anzahl ? len : anzahl;
   if (anz < 1)
      return "";

   Simstr ret(' ',anz);
   memcpy(ret.sz, sz, anz);
   return ret;
}

Simstr
Simstr::get_back(int  anzahl) const
{
   int anz = len < anzahl ? len : anzahl;
   if (anz < 1)
      return "";
   int start = len-anz;

   Simstr ret(' ',anz);
   memcpy(ret.sz, sz+start, anz);
   return ret;
}

Simstr 
Simstr::get_first_token(char c) const
{
   int posc = pos_first(c);
   if (posc != NO_POS)
      return get_front(posc);
   else
      return sz;
}

Simstr
Simstr::get_last_token(char c) const
{
   int posc = pos_last(c);
   if (posc != NO_POS)
      return get_back(len-posc-1);
   else
      return sz;
}



// Insert

void
Simstr::insert(int  pos, char c)
{
   if (pos < 0 || pos > len)
      return;

   char * result = new char[len+2];

   memcpy(result,sz,pos);
   result[pos] = c;
   memcpy(result+pos+1,sz+pos,len-pos+1);

   delete [] sz;
   sz = result;
   len++;
}

void
Simstr::push_front(char c)
{
   char * result = new char[len+2];

   result[0] = c;
   memcpy(result+1,sz,len+1);

   delete [] sz;
   sz = result;
   len++;
}

void 
Simstr::push_back(char c)
{
   char * result = new char[len+2];

   memcpy(result,sz,len);
   result[len] = c;
   result[len+1] = 0;

   delete [] sz;
   sz = result;
   len++;
}

void 
Simstr::insert(int  pos, const Simstr & S)
{
   if (pos < 0 || pos > len)
      return;

   char * result = new char[len+1+S.len];

   memcpy(result,sz,pos);
   memcpy(result+pos,S.sz,S.len);
   memcpy(result+pos+S.len,sz+pos,len-pos+1);

   delete [] sz;
   sz = result;
   len += S.len;
}

void
Simstr::push_front(const Simstr & S)
{
   char * result = new char[len+1+S.len];

   memcpy(result,S.sz,S.len);
   memcpy(result+S.len,sz,len+1);

   delete [] sz;
   sz = result;
   len += S.len;
}

void
Simstr::push_back(const Simstr & S)
{
   char * result = new char[len+1+S.len];

   memcpy(result,sz,len);
   memcpy(result+len,S.sz,S.len+1);

   delete [] sz;
   sz = result;
   len += S.len;
}


// Remove

void 
Simstr::remove(int  pos, int  anzahl)
{
   if (pos >= len || pos < 0 || anzahl < 1)
      return;

	int anz = len - pos < anzahl ? len - pos : anzahl;

	char * result = new char[len-anz+1];

	memcpy(result,sz,pos);
   memcpy(result+pos,sz+pos+anz,len-pos-anz+1);

   delete [] sz;
   sz = result;
   len -= anz;
}

void
Simstr::remove_trailing_blanks()
{
	int newlen = len-1;
	for ( ; newlen > 1 && sz[newlen] <= 32; --newlen ) {}

	if (newlen < len-1)
    	remove ( newlen+1, len-newlen);
}

void
Simstr::pop_front(int  anzahl)
{
   if (anzahl < 1)
      return;
   int anz = len < anzahl ? len : anzahl;

   char * result = new char[len-anz+1];

   memcpy(result,sz+anz,len-anz+1);

   delete [] sz;
   sz = result;
   len -= anz;
}

void
Simstr::pop_back(int  anzahl)
{
   if (anzahl < 1)
      return;

   int anz = len < anzahl ? len : anzahl;

   char * result = new char[len-anz+1];

   memcpy(result,sz,len-anz);
   result[len-anz] = 0;

   delete [] sz;
   sz = result;
   len -= anz;
}

void
Simstr::rem_back_from(int  removeStartPos)
{
   if (removeStartPos != NO_POS)
      pop_back(len-removeStartPos);
}

void
Simstr::remove_all(char c)
{
   if (!len)
      return;
   char * result = new char[len];
   int i,j=0;
   for (i = 0; i < len; i++)
       if (sz[i] != c)
          result[j++] = sz[i];

   delete [] sz;
   sz = new char[j+1];
   memcpy(sz,result,j);
   sz[j] = 0;
   len = j;
   delete [] result;
}

void 
Simstr::remove_all(const Simstr & S)
{
   int  pos;
   while ( (pos=pos_first(S)) != NO_POS )  
      remove(pos,S.len);
}

void
Simstr::strip(char c)
{
	int start = 0;
   if (c == ' ')
   {  // Sonderbehandlung: SPC entfernt auch TABs:
   	while ( start < len
                 ?  sz[start] == ' '
                    || sz[start] == '\t'
                 :  false )
	   	start++;
   }
   else
   {
   	while (start < len && sz[start] == c)
	   	start++;
   }

	int ende = len-1;
   if (c == ' ')
   {  // Sonderbehandlung: SPC entfernt auch TABs:
   	while ( ende >= start
                 ?  sz[ende] == ' '
                    || sz[ende] == '\t'
                 :  false  )
	   	ende--;
   }
   else
   {
   	while (ende >= start && sz[ende] == c)
	   	ende--;
   }
	*this = get(start,ende-start+1);
}

void
Simstr::empty()
{
   if (len > 0)
   {
      delete [] sz;
      sz = new char[1];
      *sz = 0;
      len = 0;
   }
}

Simstr
Simstr::take_first_token(char c)
{
   Simstr ret;
   int pos = pos_first(c);
   if (pos != NO_POS)
      {
         ret = get_front(pos);
         pop_front(pos+1);
      }
   else
      {
         ret = sz;
         delete [] sz;
         sz = new char[1];
         *sz = NULCH;
         len = 0;
      }

   return ret;
}

Simstr
Simstr::take_last_token(char c)
{
   Simstr ret;
   int pos = pos_last(c);
   if (pos != NO_POS)
      {
         ret = get_back(len-pos-1);
         pop_back(len-pos);
      }
   else
      {
         ret = sz;
         delete [] sz;
         sz = new char[1];
         *sz = NULCH;
         len = 0;
      }

   return ret;
}



// Find

int
Simstr::pos_first(char c) const
{
   int i = 0;
   for (i = 0; i < len ? sz[i] != c : false; i++) ;
   if (i >= len)
      return NO_POS;
   else
      return i;
}

int
Simstr::pos_first_after( char           c,
                         int            startSearchPos) const
{
   int i = 0;
   if (startSearchPos >= i)
      i = startSearchPos+1;
   for (; i < len ? sz[i] != c : false; i++) ;
   if (i >= len)
      return NO_POS;
   else
      return i;
}


int
Simstr::pos_last(char c) const
{
   int i = 0;
   for (i = len-1; i >= 0 ? sz[i] != c : false; i--) ;
   if (i < 0)
      return NO_POS;
   else
      return i;
}

int
Simstr::pos_first(const Simstr & S) const
{
   char * ptr = strstr(sz,S.sz);
   if (ptr)
      return int(ptr-sz);
   else
      return NO_POS;
}

int
Simstr::pos_last(const Simstr & S) const
{
   Simstr vgl;
   int i;
   for (i = len-S.len; i >= 0 ; i--)
      {
         vgl = get(i,S.len);
         if (vgl == S)
            break;
      }
   if (i >= 0)
      return i;
   else
      return NO_POS;
}

int
Simstr::count(char c) const
{
   int ret = 0;
   for (int i =0; i < len; i++)
	  if (sz[i] == c)
		 ret++;
   return ret;
}

bool
Simstr::is_no_text() const
{ 
   if (!len)
	  return true;

   int i;
   for (i = 0; sz[i] <= 32 && i < len; i++) ;
   if (i < len)
		return false;
	return true;
}

// Change

void 
Simstr::replace(int  pos, char c)
{
	if (pos < 0 || pos >= len)
      return;
   else
      sz[unsigned(pos)] = c;
}

void
Simstr::replace(int  startPos, int  anzahl, const Simstr & S)
{
   if (startPos >= len || startPos < 0 || anzahl < 1)
      return;

   int anz = len - startPos < anzahl ? len - startPos : anzahl;

   char * result = new char[len-anz+S.len+1];

   memcpy(result,sz,startPos);
   memcpy(result+startPos, S.sz, S.len);
   memcpy(result+startPos+S.len, sz+startPos+anz, len-startPos-anz+1);

   delete [] sz;
   sz = result;
   len = len-anz+S.len;
}

void
Simstr::replace_all(char oldCh, char newCh)
{
   for (int i=0; i < len; i++)
      if (sz[i] == oldCh)
         sz[i] = newCh;
}

void
Simstr::replace_all(const Simstr & oldS, const Simstr & newS)
{
   Simstr vgl;
   int i = 0;
	while (i <= len-oldS.len)
		{
         vgl = get(i,oldS.len);
         if (strcmp(vgl.sz,oldS.sz) == 0)
            {
               replace(i,oldS.len,newS);
               i += newS.len;
            }
         else
            i++;
      }
}

void
Simstr::to_lower()
{
	for (int i = 0; i < len; i++)
   	sz[i] = (char) tolower(sz[i]);
}



//   Simstr addition
Simstr
operator+(const char * str, const Simstr & S)
{
   Simstr ret = S;
   ret.push_front(str);
   return ret;
}

Simstr
operator+(const Simstr & S, const char * str)
{
   Simstr ret = S;
   ret.push_back(str);
   return ret;
}

Simstr
operator+(char c, const Simstr & S)
{
   Simstr ret = S;
   ret.push_front(c);
   return ret;
}

Simstr
operator+(const Simstr & S, char c)
{
   Simstr ret = S;
   ret.push_back(c);
   return ret;
}


// Simstr-Vergleiche mit char *
bool
operator==(const Simstr & S, const char * str)
{
   return strcmp(S,str) == 0;
}

bool
operator!=(const Simstr & S, const char * str)
{
   return strcmp(S,str) != 0;
}

bool
operator<(const Simstr & S, const char * str)
{
   return strcmp(S,str) < 0;
}

bool
operator>(const Simstr & S, const char * str)
{
   return strcmp(S,str) > 0;
}

bool
operator<=(const Simstr & S, const char * str)
{
   return strcmp(S,str) <= 0;
}

bool
operator>=(const Simstr & S, const char * str)
{
   return strcmp(S,str) >= 0;
}

bool
operator==(const char * str, const Simstr & S)
{
   return strcmp(str,S) == 0;
}

bool
operator!=(const char * str, const Simstr & S)
{
   return strcmp(str,S) != 0;
}

bool
operator<(const char * str, const Simstr & S)
{
   return strcmp(str,S) < 0;
}

bool
operator>(const char * str, const Simstr & S)
{
   return strcmp(str,S) > 0;
}

bool
operator<=(const char * str, const Simstr & S)
{
   return strcmp(str,S) <= 0;
}

bool
operator>=(const char * str, const Simstr & S)
{
   return strcmp(str,S) >= 0;
}


