string.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,635 行 · 第 1/3 页

CPP
1,635
字号
    }
    else
    {
        // nothing to convert
        nLen = 0;
    }

    // anything to do?
    if ( (nLen != 0) && (nLen != (size_t)-1) )
    {
        //Convert string
        size_t nRealSize;
        wxCharBuffer theBuffer = conv.cWC2MB(pwz, nLen, &nRealSize);

        //Copy
        if (nRealSize)
            assign( theBuffer.data() , nRealSize - 1 );
    }
}

//Converts this string to a wide character string if unicode
//mode is not enabled and wxUSE_WCHAR_T is enabled
const wxWCharBuffer wxString::wc_str(wxMBConv& conv) const
{
    size_t dwOutSize;
    return conv.cMB2WC(c_str(), length(), &dwOutSize);
}

#endif // wxUSE_WCHAR_T

#endif // Unicode/ANSI

// shrink to minimal size (releasing extra memory)
bool wxString::Shrink()
{
  wxString tmp(begin(), end());
  swap(tmp);
  return tmp.length() == length();
}

#if !wxUSE_STL
// get the pointer to writable buffer of (at least) nLen bytes
wxChar *wxString::GetWriteBuf(size_t nLen)
{
  if ( !AllocBeforeWrite(nLen) ) {
    // allocation failure handled by caller
    return NULL;
  }

  wxASSERT( GetStringData()->nRefs == 1 );
  GetStringData()->Validate(false);

  return m_pchData;
}

// put string back in a reasonable state after GetWriteBuf
void wxString::UngetWriteBuf()
{
  GetStringData()->nDataLength = wxStrlen(m_pchData);
  GetStringData()->Validate(true);
}

void wxString::UngetWriteBuf(size_t nLen)
{
  GetStringData()->nDataLength = nLen;
  GetStringData()->Validate(true);
}
#endif

// ---------------------------------------------------------------------------
// data access
// ---------------------------------------------------------------------------

// all functions are inline in string.h

// ---------------------------------------------------------------------------
// assignment operators
// ---------------------------------------------------------------------------

#if !wxUSE_UNICODE

// same as 'signed char' variant
wxString& wxString::operator=(const unsigned char* psz)
{
  *this = (const char *)psz;
  return *this;
}

#if wxUSE_WCHAR_T
wxString& wxString::operator=(const wchar_t *pwz)
{
  wxString str(pwz);
  swap(str);
  return *this;
}
#endif

#endif

/*
 * concatenation functions come in 5 flavours:
 *  string + string
 *  char   + string      and      string + char
 *  C str  + string      and      string + C str
 */

wxString operator+(const wxString& str1, const wxString& str2)
{
#if !wxUSE_STL
  wxASSERT( str1.GetStringData()->IsValid() );
  wxASSERT( str2.GetStringData()->IsValid() );
#endif

  wxString s = str1;
  s += str2;

  return s;
}

wxString operator+(const wxString& str, wxChar ch)
{
#if !wxUSE_STL
  wxASSERT( str.GetStringData()->IsValid() );
#endif

  wxString s = str;
  s += ch;

  return s;
}

wxString operator+(wxChar ch, const wxString& str)
{
#if !wxUSE_STL
  wxASSERT( str.GetStringData()->IsValid() );
#endif

  wxString s = ch;
  s += str;

  return s;
}

wxString operator+(const wxString& str, const wxChar *psz)
{
#if !wxUSE_STL
  wxASSERT( str.GetStringData()->IsValid() );
#endif

  wxString s;
  if ( !s.Alloc(wxStrlen(psz) + str.Len()) ) {
    wxFAIL_MSG( _T("out of memory in wxString::operator+") );
  }
  s += str;
  s += psz;

  return s;
}

wxString operator+(const wxChar *psz, const wxString& str)
{
#if !wxUSE_STL
  wxASSERT( str.GetStringData()->IsValid() );
#endif

  wxString s;
  if ( !s.Alloc(wxStrlen(psz) + str.Len()) ) {
    wxFAIL_MSG( _T("out of memory in wxString::operator+") );
  }
  s = psz;
  s += str;

  return s;
}

// ===========================================================================
// other common string functions
// ===========================================================================

int wxString::Cmp(const wxString& s) const
{
    return compare(s);
}

int wxString::Cmp(const wxChar* psz) const
{
    return compare(psz);
}

static inline int wxDoCmpNoCase(const wxChar* s1, size_t l1,
                                const wxChar* s2, size_t l2)
{
    size_t i;

    if( l1 == l2 )
    {
        for(i = 0; i < l1; ++i)
        {
            if(wxTolower(s1[i]) != wxTolower(s2[i]))
                break;
        }
        return i == l1 ? 0 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
    }
    else if( l1 < l2 )
    {
        for(i = 0; i < l1; ++i)
        {
            if(wxTolower(s1[i]) != wxTolower(s2[i]))
                break;
        }
        return i == l1 ? -1 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
    }
    else
    {
        for(i = 0; i < l2; ++i)
        {
            if(wxTolower(s1[i]) != wxTolower(s2[i]))
                break;
        }
        return i == l2 ? 1 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
    }
}

int wxString::CmpNoCase(const wxString& s) const
{
    return wxDoCmpNoCase(data(), length(), s.data(), s.length());
}

int wxString::CmpNoCase(const wxChar* psz) const
{
    int nLen = wxStrlen(psz);

    return wxDoCmpNoCase(data(), length(), psz, nLen);
}


#if wxUSE_UNICODE

#ifdef __MWERKS__
#ifndef __SCHAR_MAX__
#define __SCHAR_MAX__ 127
#endif
#endif

wxString wxString::FromAscii(const char *ascii)
{
    if (!ascii)
       return wxEmptyString;

    size_t len = strlen( ascii );
    wxString res;

    if ( len )
    {
        wxStringBuffer buf(res, len);

        wchar_t *dest = buf;

        for ( ;; )
        {
           if ( (*dest++ = (wchar_t)(unsigned char)*ascii++) == L'\0' )
               break;
        }
    }

    return res;
}

wxString wxString::FromAscii(const char ascii)
{
    // What do we do with '\0' ?

    wxString res;
    res += (wchar_t)(unsigned char) ascii;

    return res;
}

const wxCharBuffer wxString::ToAscii() const
{
    // this will allocate enough space for the terminating NUL too
    wxCharBuffer buffer(length());


    char *dest = buffer.data();

    const wchar_t *pwc = c_str();
    for ( ;; )
    {
        *dest++ = (char)(*pwc > SCHAR_MAX ? wxT('_') : *pwc);

        // the output string can't have embedded NULs anyhow, so we can safely
        // stop at first of them even if we do have any
        if ( !*pwc++ )
            break;
    }

    return buffer;
}

#endif // Unicode

// extract string of length nCount starting at nFirst
wxString wxString::Mid(size_t nFirst, size_t nCount) const
{
    size_t nLen = length();

    // default value of nCount is npos and means "till the end"
    if ( nCount == npos )
    {
        nCount = nLen - nFirst;
    }

    // out-of-bounds requests return sensible things
    if ( nFirst + nCount > nLen )
    {
        nCount = nLen - nFirst;
    }

    if ( nFirst > nLen )
    {
        // AllocCopy() will return empty string
        return wxEmptyString;
    }

    wxString dest(*this, nFirst, nCount);
    if ( dest.length() != nCount )
    {
        wxFAIL_MSG( _T("out of memory in wxString::Mid") );
    }

    return dest;
}

// check that the string starts with prefix and return the rest of the string
// in the provided pointer if it is not NULL, otherwise return false
bool wxString::StartsWith(const wxChar *prefix, wxString *rest) const
{
    wxASSERT_MSG( prefix, _T("invalid parameter in wxString::StartsWith") );

    // first check if the beginning of the string matches the prefix: note
    // that we don't have to check that we don't run out of this string as
    // when we reach the terminating NUL, either prefix string ends too (and
    // then it's ok) or we break out of the loop because there is no match
    const wxChar *p = c_str();
    while ( *prefix )
    {
        if ( *prefix++ != *p++ )
        {
            // no match
            return false;
        }
    }

    if ( rest )
    {
        // put the rest of the string into provided pointer
        *rest = p;
    }

    return true;
}

// extract nCount last (rightmost) characters
wxString wxString::Right(size_t nCount) const
{
  if ( nCount > length() )
    nCount = length();

  wxString dest(*this, length() - nCount, nCount);
  if ( dest.length() != nCount ) {
    wxFAIL_MSG( _T("out of memory in wxString::Right") );
  }
  return dest;
}

// get all characters after the last occurence of ch
// (returns the whole string if ch not found)
wxString wxString::AfterLast(wxChar ch) const
{
  wxString str;
  int iPos = Find(ch, true);
  if ( iPos == wxNOT_FOUND )
    str = *this;
  else
    str = c_str() + iPos + 1;

  return str;
}

// extract nCount first (leftmost) characters
wxString wxString::Left(size_t nCount) const
{
  if ( nCount > length() )
    nCount = length();

  wxString dest(*this, 0, nCount);
  if ( dest.length() != nCount ) {
    wxFAIL_MSG( _T("out of memory in wxString::Left") );
  }
  return dest;
}

// get all characters before the first occurence of ch
// (returns the whole string if ch not found)
wxString wxString::BeforeFirst(wxChar ch) const
{
  int iPos = Find(ch);
  if ( iPos == wxNOT_FOUND ) iPos = length();
  return wxString(*this, 0, iPos);
}

/// get all characters before the last occurence of ch
/// (returns empty string if ch not found)
wxString wxString::BeforeLast(wxChar ch) const
{
  wxString str;
  int iPos = Find(ch, true);
  if ( iPos != wxNOT_FOUND && iPos != 0 )
    str = wxString(c_str(), iPos);

  return str;
}

/// get all characters after the first occurence of ch
/// (returns empty string if ch not found)
wxString wxString::AfterFirst(wxChar ch) const
{
  wxString str;
  int iPos = Find(ch);
  if ( iPos != wxNOT_FOUND )
    str = c_str() + iPos + 1;

  return str;
}

// replace first (or all) occurences of some substring with another one
size_t wxString::Replace(const wxChar *szOld,
                  const wxChar *szNew, bool bReplaceAll)
{
    // if we tried to replace an empty string we'd enter an infinite loop below
    wxCHECK_MSG( szOld && *szOld && szNew, 0,
                 _T("wxString::Replace(): invalid parameter") );

    size_t uiCount = 0;   // count of replacements made

    size_t uiOldLen = wxStrlen(szOld);
    size_t uiNewLen = wxStrlen(szNew);

    size_t dwPos = 0;

    while ( this->c_str()[dwPos] != wxT('\0') )
    {
        //DO NOT USE STRSTR HERE
        //this string can contain embedded null characters,
        //so strstr will function incorrectly
        dwPos = find(szOld, dwPos);
        if ( dwPos == npos )
            break;                  // exit the loop
        else
        {
            //replace this occurance of the old string with the new one
            replace(dwPos, uiOldLen, szNew, uiNewLen);

            //move up pos past the string that was replaced
            dwPos += uiNewLen;

            //increase replace count
            ++uiCount;

            // stop now?
            if ( !bReplaceAll )
                break;                  // exit the loop
        }
    }

    return uiCount;
}

bool wxString::IsAscii() const
{
  const wxChar *s = (const wxChar*) *this;
  while(*s){
    if(!isascii(*s)) return(false);
    s++;
  }
  return(true);
}

bool wxString::IsWord() const
{
  const wxChar *s = (const wxChar*) *this;
  while(*s){
    if(!wxIsalpha(*s)) return(false);
    s++;
  }
  return(true);
}

bool wxString::IsNumber() const
{
  const wxChar *s = (const wxChar*) *this;
  if (wxStrlen(s))
     if ((s[0] == wxT('-')) || (s[0] == wxT('+'))) s++;
  while(*s){
    if(!wxIsdigit(*s)) return(false);
    s++;
  }
  return(true);
}

wxString wxString::Strip(stripType w) const
{
    wxString s = *this;
    if ( w & leading ) s.Trim(false);
    if ( w & trailing ) s.Trim(true);
    return s;
}

// ---------------------------------------------------------------------------
// case conversion
// ---------------------------------------------------------------------------

wxString& wxString::MakeUpper()
{
  for ( iterator it = begin(), en = end(); it != en; ++it )
    *it = (wxChar)wxToupper(*it);

  return *this;
}

wxString& wxString::MakeLower()
{
  for ( iterator it = begin(), en = end(); it != en; ++it )
    *it = (wxChar)wxTolower(*it);

  return *this;
}

// ---------------------------------------------------------------------------
// trimming and padding
// ---------------------------------------------------------------------------

// some compilers (VC++ 6.0 not to name them) return true for a call to
// isspace('

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?