Logo Search packages:      
Sourcecode: blender version File versions

STR_String.cpp

/**
 * $Id: STR_String.cpp,v 1.4 2002/12/02 09:48:10 mein Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * 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. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * 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.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

/**

 * $Id: STR_String.cpp,v 1.4 2002/12/02 09:48:10 mein Exp $
 * Copyright (C) 2001 NaN Technologies B.V.
 * This file was formerly known as: GEN_StdString.cpp.
 * @date    April, 25, 2001
 */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h> 
#include "STR_String.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/*-------------------------------------------------------------------------------------------------
      Construction / destruction
-------------------------------------------------------------------------------------------------*/



//
// Construct an empty string
//
00058 STR_String::STR_String() :
      pData(new char [32]), 
      Len(0),
      Max(32)
{
      pData[0] = 0;
}



//
// Construct a string of one character
//
STR_String::STR_String(char c) :
      pData(new char [9]),
      Len(1),
      Max(9)
{
      pData[0] = c;
      pData[1] = 0;
}



//
// Construct a string of multiple repeating characters
//
STR_String::STR_String(char c, int len) :
      pData(new char [len+8]),
      Len(len),
      Max(len+8)
{
      assertd(pData != NULL);
      memset(pData, c, len);
      pData[len] = 0;
}



//
// Construct a string from a pointer-to-ASCIIZ-string
//
// MAART: Changed to test for null strings
STR_String::STR_String(const char *str)
{
      if (str) {
            Len = ::strlen(str);
            Max = Len + 8;
            pData = new char [Max];
            assertd(pData != NULL);
            ::memcpy(pData, str, Len);
            pData[Len] = 0;
      }
      else {
            pData = 0;
            Len = 0;
            Max = 8;
      }
}



//
// Construct a string from a pointer-to-ASCII-string and a length
//
STR_String::STR_String(const char *str, int len) :
      pData(new char [len+8]),
      Len(len),
      Max(len+8)
{
      assertd(pData != NULL);
      memcpy(pData, str, len);
      pData[len] = 0;
}



//
// Construct a string from another string
//
STR_String::STR_String(rcSTR_String str) :
      pData(new char [str.Length()+8]),
      Len(str.Length()),
      Max(str.Length()+8)
{
      assertd(pData != NULL);
      assertd(str.pData != NULL);
      memcpy(pData, str.pData, str.Length());
      pData[str.Length()] = 0;
}



//
// Construct a string from the first number of characters in another string
//
STR_String::STR_String(rcSTR_String str, int len) :
      pData(new char [len+8]),
      Len(len),
      Max(len+8)
{
      assertd(pData != NULL);
      assertd(str.pData != NULL);
      memcpy(pData, str.pData, str.Length());
      pData[str.Length()] = 0;
}



//
// Create a string by concatenating two sources
//
STR_String::STR_String(const char *src1, int len1, const char *src2, int len2) :
      pData(new char [len1+len2+8]),
      Len(len1+len2),
      Max(len1+len2+8)
{
      assertd(pData != NULL);
      memcpy(pData, src1, len1);
      memcpy(pData+len1, src2, len2);
      pData[len1+len2] = 0;
}



//
// Create a string with an integer value
//
STR_String::STR_String(int val) :
      pData(new char [32]),
      Max(32)
{
      assertd(pData != NULL);
      Len=sprintf(pData, "%d", val);
}
      



//
// Create a string with a dword value
//
STR_String::STR_String(dword val) :
      pData(new char [32]),
      Max(32)
{
      assertd(pData != NULL);
      Len=sprintf(pData, "%lu", val);
}



//
// Create a string with a floating point value
//
STR_String::STR_String(float val) :
      pData(new char [32]),
      Max(32)
{
      assertd(pData != NULL);
      Len=sprintf(pData, "%g", val);
}



//
// Create a string with a double value
//
STR_String::STR_String(double val) :
      pData(new char [32]),
      Max(32)
{
      assertd(pData != NULL);
      Len=sprintf(pData, "%g", val);
}



/*-------------------------------------------------------------------------------------------------
      Buffer management
-------------------------------------------------------------------------------------------------*/



//
// Make sure that the allocated buffer is at least <len> in size
//
void STR_String::AllocBuffer(int len, bool keep_contents)
{
      // Check if we have enough space
      if (len+1 <= Max) return;

      // Reallocate string
      char *new_data = new char [len+8];
      if (keep_contents) memcpy(new_data, pData, Len);
      delete[] pData;

      // Accept new data
      Max = len+8;
      pData = new_data;
      assertd(pData != NULL);
}
      


/*-------------------------------------------------------------------------------------------------
      Basic string operations
-------------------------------------------------------------------------------------------------*/



//
// Format string (as does sprintf)
//
STR_String& STR_String::Format(const char *fmt, ...)
{
      AllocBuffer(2048, false);

      assertd(pData != NULL);
      // Expand arguments and format to string
      va_list args;
      va_start(args, fmt);
      Len = vsprintf(pData, fmt, args);
      assertd(Len <= 2048);
      va_end(args);

      return *this;
}



//
// Format string (as does sprintf)
//
STR_String& STR_String::FormatAdd(const char *fmt, ...)
{
      AllocBuffer(2048, false);

      assertd(pData != NULL);
      // Expand arguments and format to string
      va_list args;
      va_start(args, fmt);
      Len += vsprintf(pData+Len, fmt, args);
      assertd(Len <= 2048);
      va_end(args);

      return *this;
}



/*-------------------------------------------------------------------------------------------------
      Properties
-------------------------------------------------------------------------------------------------*/



//
// Check if string is entirely in UPPERCase
//
bool STR_String::IsUpper() const
{
      for (int i=0; i<Len; i++)
            if (isLower(pData[i]))
                  return false;

      return true;
}



//
// Check if string is entirely in lowerCase
//
bool STR_String::IsLower() const
{
      for (int i=0; i<Len; i++)
            if (isUpper(pData[i]))
                  return false;

      return true;
}



/*-------------------------------------------------------------------------------------------------
      Search/Replace
-------------------------------------------------------------------------------------------------*/



//
// Find the first orccurence of <c> in the string
//
int STR_String::Find(char c, int pos) const
{
      assertd(pos >= 0);
      assertd(Len==0 || pos<Len);
      assertd(pData != NULL);
      char *find_pos = strchr(pData+pos, c);
      return (find_pos) ? (find_pos-pData) : -1;
}



//
// Find the first occurence of <str> in the string
//
int   STR_String::Find(const char *str, int pos) const
{
      assertd(pos >= 0);
      assertd(Len==0 || pos<Len);
      assertd(pData != NULL);
      char *find_pos = strstr(pData+pos, str);
      return (find_pos) ? (find_pos-pData) : -1;
}



//
// Find the first occurence of <str> in the string
//
int   STR_String::Find(rcSTR_String str, int pos) const
{
      assertd(pos >= 0);
      assertd(Len==0 || pos<Len);
      assertd(pData != NULL);
      char *find_pos = strstr(pData+pos, str.ReadPtr());
      return (find_pos) ? (find_pos-pData) : -1;
}



//
// Find the last occurence of <c> in the string
//
int STR_String::RFind(char c) const
{
      assertd(pData != NULL);
      char *pos = strrchr(pData, c);
      return (pos) ? (pos-pData) : -1;
}



//
// Find the first occurence of any character in character set <set> in the string
//
int STR_String::FindOneOf(const char *set, int pos) const
{
      assertd(pos >= 0);
      assertd(Len==0 || pos<Len);
      assertd(pData != NULL);
      char *find_pos = strpbrk(pData+pos, set);
      return (find_pos) ? (find_pos-pData) : -1;
}



//
// Replace a character in this string with another string
//
void STR_String::Replace(int pos, rcSTR_String str)
{
      //bounds(pos, 0, Length()-1);

      if (str.Length() < 1)
      {
            // Remove one character from the string
            memcpy(pData+pos, pData+pos+1, Len-pos);
      }
      else
      {
            // Insert zero or more characters into the string
            AllocBuffer(Len + str.Length() - 1, true);
            if (str.Length() != 1) memcpy(pData+pos+str.Length(), pData+pos+1, Length()-pos);
            memcpy(pData+pos, str.ReadPtr(), str.Length());
      }

      Len += str.Length()-1;
}



//
// Replace a substring of this string with another string
//
void STR_String::Replace(int pos, int num, rcSTR_String str)
{
      //bounds(pos, 0, Length()-1);
      //bounds(pos+num, 0, Length());
      assertd(num >= 1);

      if (str.Length() < num)
      {
            // Remove some data from the string by replacement
            memcpy(pData+pos+str.Length(), pData+pos+num, Len-pos-num+1);
            memcpy(pData+pos, str.ReadPtr(), str.Length());
      }
      else
      {
            // Insert zero or more characters into the string
            AllocBuffer(Len + str.Length() - num, true);
            if (str.Length() != num) memcpy(pData+pos+str.Length(), pData+pos+num, Length()-pos-num+1);
            memcpy(pData+pos, str.ReadPtr(), str.Length());
      }

      Len += str.Length()-num;
}



/*-------------------------------------------------------------------------------------------------
      Comparison
-------------------------------------------------------------------------------------------------*/



//
// Compare two strings and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
//
int   STR_String::Compare(rcSTR_String rhs) const
{
      return strcmp(pData, rhs.pData);
}



//
// Compare two strings without respecting case and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
//
int STR_String::CompareNoCase(rcSTR_String rhs) const
{
#ifdef WIN32
      return stricmp(pData, rhs.pData);
#else
      return strcasecmp(pData, rhs.pData);
#endif
}



/*-------------------------------------------------------------------------------------------------
      Formatting
-------------------------------------------------------------------------------------------------*/



//
// Capitalize string, "heLLo" -> "HELLO"
//
STR_String& STR_String::Upper()
{
      assertd(pData != NULL);
#ifdef WIN32
      _strupr(pData);
#else
      for (int i=0;i<Len;i++)
            pData[i] = (pData[i] >= 'a' && pData[i] <= 'z')?pData[i]+'A'-'a':pData[i];
#endif
      return *this;
}



//
// Lower string, "heLLo" -> "hello"
//
STR_String& STR_String::Lower()
{
      assertd(pData != NULL);
#ifdef WIN32
      _strlwr(pData);
#else
      for (int i=0;i<Len;i++)
            pData[i] = (pData[i] >= 'A' && pData[i] <= 'Z')?pData[i]+'a'-'A':pData[i];
#endif
      return *this;
}



//
// Capitalize string, "heLLo" -> "Hello"
//
STR_String& STR_String::Capitalize()
{
      assertd(pData != NULL);
#ifdef WIN32
      if (Len>0) pData[0] = toupper(pData[0]);
      if (Len>1) _strlwr(pData+1);
#else
      if (Len > 0)
            pData[0] = (pData[0] >= 'A' && pData[0] <= 'A')?pData[0]+'a'-'A':pData[0];
      for (int i=1;i<Len;i++)
            pData[i] = (pData[i] >= 'a' && pData[i] <= 'z')?pData[i]+'A'-'a':pData[i];
#endif
      return *this;
}



//
// Trim whitespace from the left side of the string
//
STR_String& STR_String::TrimLeft()
{
      int skip;
      assertd(pData != NULL);
      for (skip=0; isSpace(pData[skip]); skip++, Len--);
      memmove(pData, pData+skip, Len+1);
      return *this;
}



//
// Trim whitespaces from the right side of the string
//
STR_String& STR_String::TrimRight()
{
      assertd(pData != NULL);
      while (Len && isSpace(pData[Len-1])) Len--;
      pData[Len]=0;
      return *this;
}



//
// Trim spaces from both sides of the character set
//
STR_String& STR_String::Trim()
{
      TrimRight();
      TrimLeft();
      return *this;
}



//
// Trim characters from the character set <set> from the left side of the string
//
STR_String& STR_String::TrimLeft(char *set)
{
      int skip;
      assertd(pData != NULL);
      for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--);
      memmove(pData, pData+skip, Len+1);
      return *this;
}



//
// Trim characters from the character set <set> from the right side of the string
//
STR_String& STR_String::TrimRight(char *set)
{
      assertd(pData != NULL);
      while (Len && strchr(set, pData[Len-1])) Len--;
      pData[Len]=0;
      return *this;
}



//
// Trim characters from the character set <set> from both sides of the character set
//
STR_String& STR_String::Trim(char *set)
{
      TrimRight(set);
      TrimLeft(set);
      return *this;
}



//
// Trim quotes from both sides of the string
//
STR_String& STR_String::TrimQuotes()
{
      // Trim quotes if they are on both sides of the string
      assertd(pData != NULL);
      if ((Len >= 2) && (pData[0] == '\"') && (pData[Len-1] == '\"'))
      {
            memmove(pData, pData+1, Len-2+1);
            Len-=2;
      }
      return *this;
}



/*-------------------------------------------------------------------------------------------------
      Assignment/Concatenation
-------------------------------------------------------------------------------------------------*/



//
// Set the string's conents to a copy of <src> with length <len>
//
rcSTR_String STR_String::Copy(const char *src, int len)
{
      assertd(len>=0);
      assertd(src);
      assertd(pData != NULL);

      AllocBuffer(len, false);
      Len = len;
      memcpy(pData, src, len);
      pData[Len] = 0;

      return *this;
}



//
// Concate a number of bytes to the current string
//
rcSTR_String STR_String::Concat(const char *data, int len)
{
      assertd(Len>=0);
      assertd(len>=0);
      assertd(data);
      assertd(pData != NULL);

      AllocBuffer(Len+len, true);
      memcpy(pData+Len, data, len);
      Len+=len;
      pData[Len] = 0;

      return *this;
}





vector<STR_String>      STR_String::Explode(char c) const
{
      STR_String                    lcv   = *this;
      vector<STR_String>            uc;

      while (lcv.Length())
      {
            int pos = lcv.Find(c);
            if (pos < 0)
            {
                  uc.push_back(lcv);
                  lcv.Clear();
            } else
            {
                  uc.push_back(lcv.Left(pos));
                  lcv = lcv.Mid(pos+1);
            }
      }

      //uc. -= STR_String("");

      return uc;
}


/*

int         STR_String::Serialize(pCStream stream)
{
      if (stream->GetAccess() == CStream::Access_Read)
      {
            int ln;
            stream->Read(&ln, sizeof(ln));
            AllocBuffer(ln, false);
            stream->Read(pData, ln); 
            pData[ln]   = '\0';
            Len               = ln;
      } else
      {
            stream->Write(&Len, sizeof(Len));
            stream->Write(pData, Len);
      }

      return Len + sizeof(Len);
}
*/


Generated by  Doxygen 1.6.0   Back to index