git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59829 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			141 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // Name:        wx/anystr.h
 | |
| // Purpose:     wxAnyStrPtr class declaration
 | |
| // Author:      Vadim Zeitlin
 | |
| // Created:     2009-03-23
 | |
| // RCS-ID:      $Id$
 | |
| // Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
 | |
| // Licence:     wxWindows licence
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #ifndef _WX_ANYSTR_H_
 | |
| #define _WX_ANYSTR_H_
 | |
| 
 | |
| #include "wx/string.h"
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // wxAnyStrPtr
 | |
| //
 | |
| // Notice that this is an internal and intentionally not documented class. It
 | |
| // is only used by wxWidgets itself to ensure compatibility with previous
 | |
| // versions and shouldn't be used by user code. When you see a function
 | |
| // returning it you should just know that you can treat it as a string pointer.
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| // This is a helper class convertible to either narrow or wide string pointer.
 | |
| // It is similar to wxCStrData but, unlike it, can be NULL which is required to
 | |
| // represent the return value of wxDateTime::ParseXXX() methods for example.
 | |
| //
 | |
| // NB: this class is fully inline and so doesn't need to be DLL-exported
 | |
| class wxAnyStrPtr
 | |
| {
 | |
| public:
 | |
|     // ctors: this class must be created from the associated string or using
 | |
|     // its default ctor for an invalid NULL-like object; notice that it is
 | |
|     // immutable after creation.
 | |
| 
 | |
|     // ctor for invalid pointer
 | |
|     wxAnyStrPtr()
 | |
|         : m_str(NULL)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     // ctor for valid pointer into the given string (whose lifetime must be
 | |
|     // greater than ours and which should remain constant while we're used)
 | |
|     wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
 | |
|         : m_str(&str),
 | |
|           m_iter(iter)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     // default copy ctor is ok and so is default dtor, in particular we do not
 | |
|     // free the string
 | |
| 
 | |
| 
 | |
|     // various operators meant to make this class look like a superposition of
 | |
|     // char* and wchar_t*
 | |
| 
 | |
|     // this one is needed to allow boolean expressions involving these objects,
 | |
|     // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
 | |
|     // unspecified_bool_type here wouldn't help with ambiguity between all the
 | |
|     // different conversions to pointers)
 | |
|     operator bool() const { return m_str != NULL; }
 | |
| 
 | |
|     // at least VC6 and VC7 also need this one or they complain about ambiguity
 | |
|     // for !anystr expressions
 | |
|     bool operator!() const { return !((bool)*this); }
 | |
| 
 | |
| 
 | |
|     // and these are the conversions operator which allow to assign the result
 | |
|     // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
 | |
|     operator const char *() const
 | |
|     {
 | |
|         if ( !m_str )
 | |
|             return NULL;
 | |
| 
 | |
|         // check if the string is convertible to char at all
 | |
|         //
 | |
|         // notice that this pointer points into wxString internal buffer
 | |
|         // containing its char* representation and so it can be kept for as
 | |
|         // long as wxString is not modified -- which is long enough for our
 | |
|         // needs
 | |
|         const char *p = m_str->c_str().AsChar();
 | |
|         if ( *p )
 | |
|         {
 | |
|             // find the offset of the character corresponding to this iterator
 | |
|             // position in bytes: we don't have any direct way to do it so we
 | |
|             // need to redo the conversion again for the part of the string
 | |
|             // before the iterator to find its length in bytes in current
 | |
|             // locale
 | |
|             //
 | |
|             // NB: conversion won't fail as it succeeded for the entire string
 | |
|             p += strlen(wxString(m_str->begin(), m_iter).mb_str());
 | |
|         }
 | |
|         //else: conversion failed, return "" as we can't do anything else
 | |
| 
 | |
|         return p;
 | |
|     }
 | |
| 
 | |
|     operator const wchar_t *() const
 | |
|     {
 | |
|         if ( !m_str )
 | |
|             return NULL;
 | |
| 
 | |
|         // no complications with wide strings (as long as we discount
 | |
|         // surrogates as we do for now)
 | |
|         //
 | |
|         // just remember that this works as long as wxString keeps an internal
 | |
|         // buffer with its wide wide char representation, just as with AsChar()
 | |
|         // above
 | |
|         return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
 | |
|     }
 | |
| 
 | |
|     // Because the objects of this class are only used as return type for
 | |
|     // functions which can return NULL we can skip providing dereferencing
 | |
|     // operators: the code using this class must test it for NULL first and if
 | |
|     // it does anything else with it it has to assign it to either char* or
 | |
|     // wchar_t* itself, before dereferencing.
 | |
|     //
 | |
|     // IOW this
 | |
|     //
 | |
|     //      if ( *FuncReturningAnyStrPtr() )
 | |
|     //
 | |
|     // is invalid because it could crash. And this
 | |
|     //
 | |
|     //      const char *p = FuncReturningAnyStrPtr();
 | |
|     //      if ( p && *p )
 | |
|     //
 | |
|     // already works fine.
 | |
| 
 | |
| private:
 | |
|     // the original string and the position in it we correspond to, if the
 | |
|     // string is NULL this object is NULL pointer-like
 | |
|     const wxString * const m_str;
 | |
|     const wxString::const_iterator m_iter;
 | |
| 
 | |
|     wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
 | |
| };
 | |
| 
 | |
| #endif // _WX_ANYSTR_H_
 | |
| 
 |