]>
Commit | Line | Data |
---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/anystr.h | |
3 | // Purpose: wxAnyStrPtr class declaration | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2009-03-23 | |
6 | // RCS-ID: $Id$ | |
7 | // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org> | |
8 | // Licence: wxWindows licence | |
9 | /////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | #ifndef _WX_ANYSTR_H_ | |
12 | #define _WX_ANYSTR_H_ | |
13 | ||
14 | #include "wx/string.h" | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // wxAnyStrPtr | |
18 | // | |
19 | // Notice that this is an internal and intentionally not documented class. It | |
20 | // is only used by wxWidgets itself to ensure compatibility with previous | |
21 | // versions and shouldn't be used by user code. When you see a function | |
22 | // returning it you should just know that you can treat it as a string pointer. | |
23 | // ---------------------------------------------------------------------------- | |
24 | ||
25 | // This is a helper class convertible to either narrow or wide string pointer. | |
26 | // It is similar to wxCStrData but, unlike it, can be NULL which is required to | |
27 | // represent the return value of wxDateTime::ParseXXX() methods for example. | |
28 | // | |
29 | // NB: this class is fully inline and so doesn't need to be DLL-exported | |
30 | class wxAnyStrPtr | |
31 | { | |
32 | public: | |
33 | // ctors: this class must be created from the associated string or using | |
34 | // its default ctor for an invalid NULL-like object; notice that it is | |
35 | // immutable after creation. | |
36 | ||
37 | // ctor for invalid pointer | |
38 | wxAnyStrPtr() | |
39 | : m_str(NULL) | |
40 | { | |
41 | } | |
42 | ||
43 | // ctor for valid pointer into the given string (whose lifetime must be | |
44 | // greater than ours and which should remain constant while we're used) | |
45 | wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter) | |
46 | : m_str(&str), | |
47 | m_iter(iter) | |
48 | { | |
49 | } | |
50 | ||
51 | // default copy ctor is ok and so is default dtor, in particular we do not | |
52 | // free the string | |
53 | ||
54 | ||
55 | // various operators meant to make this class look like a superposition of | |
56 | // char* and wchar_t* | |
57 | ||
58 | // this one is needed to allow boolean expressions involving these objects, | |
59 | // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using | |
60 | // unspecified_bool_type here wouldn't help with ambiguity between all the | |
61 | // different conversions to pointers) | |
62 | operator bool() const { return m_str != NULL; } | |
63 | ||
64 | // at least VC6 and VC7 also need this one or they complain about ambiguity | |
65 | // for !anystr expressions | |
66 | bool operator!() const { return !((bool)*this); } | |
67 | ||
68 | ||
69 | // and these are the conversions operator which allow to assign the result | |
70 | // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*) | |
71 | operator const char *() const | |
72 | { | |
73 | if ( !m_str ) | |
74 | return NULL; | |
75 | ||
76 | // check if the string is convertible to char at all | |
77 | // | |
78 | // notice that this pointer points into wxString internal buffer | |
79 | // containing its char* representation and so it can be kept for as | |
80 | // long as wxString is not modified -- which is long enough for our | |
81 | // needs | |
82 | const char *p = m_str->c_str().AsChar(); | |
83 | if ( *p ) | |
84 | { | |
85 | // find the offset of the character corresponding to this iterator | |
86 | // position in bytes: we don't have any direct way to do it so we | |
87 | // need to redo the conversion again for the part of the string | |
88 | // before the iterator to find its length in bytes in current | |
89 | // locale | |
90 | // | |
91 | // NB: conversion won't fail as it succeeded for the entire string | |
92 | p += strlen(wxString(m_str->begin(), m_iter).mb_str()); | |
93 | } | |
94 | //else: conversion failed, return "" as we can't do anything else | |
95 | ||
96 | return p; | |
97 | } | |
98 | ||
99 | operator const wchar_t *() const | |
100 | { | |
101 | if ( !m_str ) | |
102 | return NULL; | |
103 | ||
104 | // no complications with wide strings (as long as we discount | |
105 | // surrogates as we do for now) | |
106 | // | |
107 | // just remember that this works as long as wxString keeps an internal | |
108 | // buffer with its wide wide char representation, just as with AsChar() | |
109 | // above | |
110 | return m_str->c_str().AsWChar() + (m_iter - m_str->begin()); | |
111 | } | |
112 | ||
113 | // Because the objects of this class are only used as return type for | |
114 | // functions which can return NULL we can skip providing dereferencing | |
115 | // operators: the code using this class must test it for NULL first and if | |
116 | // it does anything else with it it has to assign it to either char* or | |
117 | // wchar_t* itself, before dereferencing. | |
118 | // | |
119 | // IOW this | |
120 | // | |
121 | // if ( *FuncReturningAnyStrPtr() ) | |
122 | // | |
123 | // is invalid because it could crash. And this | |
124 | // | |
125 | // const char *p = FuncReturningAnyStrPtr(); | |
126 | // if ( p && *p ) | |
127 | // | |
128 | // already works fine. | |
129 | ||
130 | private: | |
131 | // the original string and the position in it we correspond to, if the | |
132 | // string is NULL this object is NULL pointer-like | |
133 | const wxString * const m_str; | |
134 | const wxString::const_iterator m_iter; | |
135 | ||
136 | wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr); | |
137 | }; | |
138 | ||
139 | #endif // _WX_ANYSTR_H_ | |
140 |