⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.h

📁 浙江大学的悟空嵌入式系统模拟器
💻 H
📖 第 1 页 / 共 4 页
字号:
///////////////////////////////////////////////////////////////////////////////
// Name:        string.h
// Purpose:     wxString and wxArrayString classes
// Author:      Vadim Zeitlin
// Modified by:
// Created:     29/01/98
// RCS-ID:      $Id: string.h,v 1.1 2005/03/16 06:49:27 kehc Exp $
// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence:     wxWindows license
///////////////////////////////////////////////////////////////////////////////

/*
    Efficient string class [more or less] compatible with MFC CString,
    wxWindows version 1 wxString and std::string and some handy functions
    missing from string.h.
*/

#ifndef _WX_WXSTRINGH__
#define _WX_WXSTRINGH__

#if defined(__GNUG__) && !defined(__APPLE__)
    #pragma interface "string.h"
#endif

// ----------------------------------------------------------------------------
// conditinal compilation
// ----------------------------------------------------------------------------

// compile the std::string compatibility functions if defined
#define   wxSTD_STRING_COMPATIBILITY

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#include "wx/defs.h"        // everybody should include this

#if defined(__WXMAC__) || defined(__VISAGECPP__)
    #include <ctype.h>
#endif

#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
   // problem in VACPP V4 with including stdlib.h multiple times
   // strconv includes it anyway
#  include <stdio.h>
#  include <string.h>
#  include <stdarg.h>
#  include <limits.h>
#else
#  include <string.h>
#  include <stdio.h>
#  include <stdarg.h>
#  include <limits.h>
#  include <stdlib.h>
#endif

#ifdef HAVE_STRINGS_H
    #include <strings.h>    // for strcasecmp()
#endif // HAVE_STRINGS_H

#include "wx/wxchar.h"      // for wxChar
#include "wx/buffer.h"      // for wxCharBuffer
#include "wx/strconv.h"     // for wxConvertXXX() macros and wxMBConv classes

// ---------------------------------------------------------------------------
// macros
// ---------------------------------------------------------------------------

// casts [unfortunately!] needed to call some broken functions which require
// "char *" instead of "const char *"
#define   WXSTRINGCAST (wxChar *)(const wxChar *)
#define   wxCSTRINGCAST (wxChar *)(const wxChar *)
#define   wxMBSTRINGCAST (char *)(const char *)
#define   wxWCSTRINGCAST (wchar_t *)(const wchar_t *)

// implementation only
#define   wxASSERT_VALID_INDEX(i) \
    wxASSERT_MSG( (size_t)(i) <= Len(), _T("invalid index in wxString") )

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
// must define this static for VA or else you get multiply defined symbols everywhere
extern const unsigned int wxSTRING_MAXLEN;

#else
// maximum possible length for a string means "take all string" everywhere
//  (as sizeof(StringData) is unknown here, we substract 100)
const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;

#endif

// ----------------------------------------------------------------------------
// global data
// ----------------------------------------------------------------------------

// global pointer to empty string
WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;

// ---------------------------------------------------------------------------
// global functions complementing standard C string library replacements for
// strlen() and portable strcasecmp()
//---------------------------------------------------------------------------

// Use wxXXX() functions from wxchar.h instead! These functions are for
// backwards compatibility only.

// checks whether the passed in pointer is NULL and if the string is empty
inline bool IsEmpty(const char *p) { return (!p || !*p); }

// safe version of strlen() (returns 0 if passed NULL pointer)
inline size_t Strlen(const char *psz)
  { return psz ? strlen(psz) : 0; }

// portable strcasecmp/_stricmp
inline int Stricmp(const char *psz1, const char *psz2)
{
#if defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) )
  return _stricmp(psz1, psz2);
#elif defined(__SC__)
  return _stricmp(psz1, psz2);
#elif defined(__SALFORDC__)
  return stricmp(psz1, psz2);
#elif defined(__BORLANDC__)
  return stricmp(psz1, psz2);
#elif defined(__WATCOMC__)
  return stricmp(psz1, psz2);
#elif defined(__DJGPP__)
  return stricmp(psz1, psz2);
#elif defined(__EMX__)
  return stricmp(psz1, psz2);
#elif defined(__WXPM__)
  return stricmp(psz1, psz2);
#elif defined(__UNIX__) || defined(__GNUWIN32__)
  return strcasecmp(psz1, psz2);
#elif defined(__MWERKS__) && !defined(__INTEL__)
  register char c1, c2;
  do {
    c1 = tolower(*psz1++);
    c2 = tolower(*psz2++);
  } while ( c1 && (c1 == c2) );

  return c1 - c2;
#else
  // almost all compilers/libraries provide this function (unfortunately under
  // different names), that's why we don't implement our own which will surely
  // be more efficient than this code (uncomment to use):
  /*
    register char c1, c2;
    do {
      c1 = tolower(*psz1++);
      c2 = tolower(*psz2++);
    } while ( c1 && (c1 == c2) );

    return c1 - c2;
  */

  #error  "Please define string case-insensitive compare for your OS/compiler"
#endif  // OS/compiler
}

// return an empty wxString
class WXDLLEXPORT wxString; // not yet defined
inline const wxString& wxGetEmptyString() { return *(wxString *)&wxEmptyString; }

// ---------------------------------------------------------------------------
// string data prepended with some housekeeping info (used by wxString class),
// is never used directly (but had to be put here to allow inlining)
// ---------------------------------------------------------------------------

struct WXDLLEXPORT wxStringData
{
  int     nRefs;        // reference count
  size_t  nDataLength,  // actual string length
          nAllocLength; // allocated memory size

  // mimics declaration 'wxChar data[nAllocLength]'
  wxChar* data() const { return (wxChar*)(this + 1); }

  // empty string has a special ref count so it's never deleted
  bool  IsEmpty()   const { return (nRefs == -1); }
  bool  IsShared()  const { return (nRefs > 1);   }

  // lock/unlock
  void  Lock()   { if ( !IsEmpty() ) nRefs++;                    }

  // VC++ will refuse to inline Unlock but profiling shows that it is wrong
#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
  __forceinline
#endif
  // VC++ free must take place in same DLL as allocation when using non dll
  // run-time library (e.g. Multithreaded instead of Multithreaded DLL)
#if defined(__VISUALC__) && defined(_MT) && !defined(_DLL)
  void  Unlock() { if ( !IsEmpty() && --nRefs == 0) Free();  }
  // we must not inline deallocation since allocation is not inlined
  void  Free();
#else
  void  Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this);  }
#endif

  // if we had taken control over string memory (GetWriteBuf), it's
  // intentionally put in invalid state
  void  Validate(bool b)  { nRefs = (b ? 1 : 0); }
  bool  IsValid() const   { return (nRefs != 0); }
};

// ---------------------------------------------------------------------------
// This is (yet another one) String class for C++ programmers. It doesn't use
// any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
// thus you should be able to compile it with practicaly any C++ compiler.
// This class uses copy-on-write technique, i.e. identical strings share the
// same memory as long as neither of them is changed.
//
// This class aims to be as compatible as possible with the new standard
// std::string class, but adds some additional functions and should be at
// least as efficient than the standard implementation.
//
// Performance note: it's more efficient to write functions which take "const
// String&" arguments than "const char *" if you assign the argument to
// another string.
//
// It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
//
// To do:
//  - ressource support (string tables in ressources)
//  - more wide character (UNICODE) support
//  - regular expressions support
// ---------------------------------------------------------------------------

class WXDLLEXPORT wxString
{
friend class WXDLLEXPORT wxArrayString;

  // NB: special care was taken in arranging the member functions in such order
  //     that all inline functions can be effectively inlined, verify that all
  //     performace critical functions are still inlined if you change order!
private:
  // points to data preceded by wxStringData structure with ref count info
  wxChar *m_pchData;

  // accessor to string data
  wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }

  // string (re)initialization functions
    // initializes the string to the empty value (must be called only from
    // ctors, use Reinit() otherwise)
  void Init() { m_pchData = (wxChar *)wxEmptyString; }
    // initializaes the string with (a part of) C-string
  void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = wxSTRING_MAXLEN);
    // as Init, but also frees old data
  void Reinit() { GetStringData()->Unlock(); Init(); }

  // memory allocation
    // allocates memory for string of length nLen
  bool AllocBuffer(size_t nLen);
    // copies data to another string
  bool AllocCopy(wxString&, int, int) const;
    // effectively copies data to string
  bool AssignCopy(size_t, const wxChar *);

  // append a (sub)string
  bool ConcatSelf(int nLen, const wxChar *src);

  // functions called before writing to the string: they copy it if there
  // are other references to our data (should be the only owner when writing)
  bool CopyBeforeWrite();
  bool AllocBeforeWrite(size_t);

  // if we hadn't made these operators private, it would be possible to
  // compile "wxString s; s = 17;" without any warnings as 17 is implicitly
  // converted to char in C and we do have operator=(char)
  //
  // NB: we don't need other versions (short/long and unsigned) as attempt
  //     to assign another numeric type to wxString will now result in
  //     ambiguity between operator=(char) and operator=(int)
  wxString& operator=(int);

  // these methods are not implemented - there is _no_ conversion from int to
  // string, you're doing something wrong if the compiler wants to call it!
  //
  // try `s << i' or `s.Printf("%d", i)' instead
  wxString(int);

public:
  // constructors and destructor
    // ctor for an empty string
  wxString() : m_pchData(NULL) { Init(); }
    // copy ctor
  wxString(const wxString& stringSrc) : m_pchData(NULL)
  {
    wxASSERT_MSG( stringSrc.GetStringData()->IsValid(),
                  _T("did you forget to call UngetWriteBuf()?") );

    if ( stringSrc.IsEmpty() ) {
      // nothing to do for an empty string
      Init();
    }
    else {
      m_pchData = stringSrc.m_pchData;            // share same data
      GetStringData()->Lock();                    // => one more copy
    }
  }
    // string containing nRepeat copies of ch
  wxString(wxChar ch, size_t nRepeat = 1);
    // ctor takes first nLength characters from C string
    // (default value of wxSTRING_MAXLEN means take all the string)
  wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN)
      : m_pchData(NULL)
      { InitWith(psz, 0, nLength); }
  wxString(const wxChar *psz, wxMBConv& WXUNUSED(conv), size_t nLength = wxSTRING_MAXLEN)
      : m_pchData(NULL)
      { InitWith(psz, 0, nLength); }

#if wxUSE_UNICODE
    // from multibyte string
    // (NB: nLength is right now number of Unicode characters, not
    //  characters in psz! So try not to use it yet!)

⌨️ 快捷键说明

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