Coverage Report

Created: 2026-07-25 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wxwidgets/include/wx/stringops.h
Line
Count
Source
1
///////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/stringops.h
3
// Purpose:     implementation of wxString primitive operations
4
// Author:      Vaclav Slavik
5
// Created:     2007-04-16
6
// Copyright:   (c) 2007 REA Elektronik GmbH
7
// Licence:     wxWindows licence
8
///////////////////////////////////////////////////////////////////////////////
9
10
#ifndef _WX_WXSTRINGOPS_H__
11
#define _WX_WXSTRINGOPS_H__
12
13
#include "wx/chartype.h"
14
#include "wx/unichar.h"
15
#include "wx/buffer.h"
16
17
#include "wx/beforestd.h"
18
#include <string>
19
#include "wx/afterstd.h"
20
21
// This header contains wxStringOperations "namespace" class that implements
22
// elementary operations on string data as static methods; wxString methods and
23
// iterators are implemented in terms of it. Two implementations are available,
24
// one for UTF-8 encoded char* string and one for "raw" wchar_t* strings (or
25
// char* in ANSI build).
26
27
#if wxUSE_UNICODE_WCHAR
28
struct WXDLLIMPEXP_BASE wxStringOperationsWchar
29
{
30
    // moves the iterator to the next Unicode character
31
    template <typename Iterator>
32
3.00M
    static void IncIter(Iterator& i) { ++i; }
Unexecuted instantiation: void wxStringOperationsWchar::IncIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>&)
void wxStringOperationsWchar::IncIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*>&)
Line
Count
Source
32
3.00M
    static void IncIter(Iterator& i) { ++i; }
33
34
    // moves the iterator to the previous Unicode character
35
    template <typename Iterator>
36
39.3k
    static void DecIter(Iterator& i) { --i; }
void wxStringOperationsWchar::DecIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>&)
Line
Count
Source
36
39.3k
    static void DecIter(Iterator& i) { --i; }
Unexecuted instantiation: void wxStringOperationsWchar::DecIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*>&)
37
38
    // moves the iterator by n Unicode characters
39
    template <typename Iterator>
40
    static Iterator AddToIter(const Iterator& i, ptrdiff_t n)
41
106k
        { return i + n; }
std::__1::__wrap_iter<wchar_t*> wxStringOperationsWchar::AddToIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*> const&, long)
Line
Count
Source
41
106k
        { return i + n; }
std::__1::__wrap_iter<wchar_t const*> wxStringOperationsWchar::AddToIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*> const&, long)
Line
Count
Source
41
548
        { return i + n; }
42
43
    // returns distance of the two iterators in Unicode characters
44
    template <typename Iterator>
45
    static ptrdiff_t DiffIters(const Iterator& i1, const Iterator& i2)
46
0
        { return i1 - i2; }
Unexecuted instantiation: long wxStringOperationsWchar::DiffIters<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*> const&, std::__1::__wrap_iter<wchar_t*> const&)
Unexecuted instantiation: long wxStringOperationsWchar::DiffIters<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*> const&, std::__1::__wrap_iter<wchar_t const*> const&)
47
48
#if wxUSE_UNICODE_UTF16
49
    // encodes the characters as UTF-16:
50
    struct Utf16CharBuffer
51
    {
52
        // Notice that data is left uninitialized, it is filled by EncodeChar()
53
        // which is the only function creating objects of this class.
54
55
        wchar_t data[3];
56
        operator const wchar_t*() const { return data; }
57
    };
58
    static Utf16CharBuffer EncodeChar(const wxUniChar& ch);
59
    static wxWCharBuffer EncodeNChars(size_t n, const wxUniChar& ch);
60
    static bool IsSingleCodeUnitCharacter(const wxUniChar& ch)
61
        { return !ch.IsSupplementary(); }
62
#else
63
    // encodes the character to a form used to represent it in internal
64
    // representation
65
    struct SingleCharBuffer
66
    {
67
        wxChar data[2];
68
0
        operator const wxChar*() const { return data; }
69
    };
70
    static SingleCharBuffer EncodeChar(const wxUniChar& ch)
71
0
    {
72
0
        SingleCharBuffer buf;
73
0
        buf.data[0] = (wxChar)ch;
74
0
        buf.data[1] = 0;
75
0
        return buf;
76
0
    }
77
    static wxWCharBuffer EncodeNChars(size_t n, const wxUniChar& ch);
78
6.50M
    static bool IsSingleCodeUnitCharacter(const wxUniChar&) { return true; }
79
#endif
80
81
    static wxUniChar DecodeChar(const std::wstring::const_iterator& i)
82
11.0M
        { return *i; }
83
};
84
#endif // wxUSE_UNICODE_WCHAR
85
86
87
#if wxUSE_UNICODE_UTF8
88
struct WXDLLIMPEXP_BASE wxStringOperationsUtf8
89
{
90
    // checks correctness of UTF-8 sequence
91
    static bool IsValidUtf8String(const char *c,
92
                                  size_t len = std::string::npos);
93
    static bool IsValidUtf8LeadByte(unsigned char c)
94
    {
95
        return (c <= 0x7F) || (c >= 0xC2 && c <= 0xF4);
96
    }
97
98
    // returns offset to skip forward when iterating over UTF-8 sequence
99
    static unsigned char GetUTF8IterOffset(unsigned char c);
100
101
102
    template<typename Iterator>
103
    static void IncIter(Iterator& i)
104
    {
105
        wxASSERT( IsValidUtf8LeadByte(*i) );
106
        i += GetUTF8IterOffset(*i);
107
    }
108
109
    template<typename Iterator>
110
    static void DecIter(Iterator& i)
111
    {
112
        // Non-lead bytes are all in the 0x80..0xBF range (i.e. 10xxxxxx in
113
        // binary), so we just have to go back until we hit a byte that is
114
        // either < 0x80 (i.e. 0xxxxxxx in binary) or 0xC0..0xFF (11xxxxxx in
115
        // binary; this includes some invalid values, but we can ignore it
116
        // here, because we assume valid UTF-8 input for the purpose of
117
        // efficient implementation).
118
        --i;
119
        while ( ((*i) & 0xC0) == 0x80 /* 2 highest bits are '10' */ )
120
            --i;
121
    }
122
123
    template<typename Iterator>
124
    static Iterator AddToIter(const Iterator& i, ptrdiff_t n)
125
    {
126
        Iterator out(i);
127
128
        if ( n > 0 )
129
        {
130
            for ( ptrdiff_t j = 0; j < n; ++j )
131
                IncIter(out);
132
        }
133
        else if ( n < 0 )
134
        {
135
            for ( ptrdiff_t j = 0; j > n; --j )
136
                DecIter(out);
137
        }
138
139
        return out;
140
    }
141
142
    template<typename Iterator>
143
    static ptrdiff_t DiffIters(Iterator i1, Iterator i2)
144
    {
145
        ptrdiff_t dist = 0;
146
147
        if ( i1 < i2 )
148
        {
149
            while ( i1 != i2 )
150
            {
151
                IncIter(i1);
152
                dist--;
153
            }
154
        }
155
        else if ( i2 < i1 )
156
        {
157
            while ( i2 != i1 )
158
            {
159
                IncIter(i2);
160
                dist++;
161
            }
162
        }
163
164
        return dist;
165
    }
166
167
    static bool IsSingleCodeUnitCharacter(const wxUniChar& ch)
168
        { return ch.IsAscii(); }
169
170
    // encodes the character as UTF-8:
171
    typedef wxUniChar::Utf8CharBuffer Utf8CharBuffer;
172
    static Utf8CharBuffer EncodeChar(const wxUniChar& ch)
173
        { return ch.AsUTF8(); }
174
175
    // returns n copies of ch encoded in UTF-8 string
176
    static wxCharBuffer EncodeNChars(size_t n, const wxUniChar& ch);
177
178
    // returns the length of UTF-8 encoding of the character with lead byte 'c'
179
    static size_t GetUtf8CharLength(char c)
180
    {
181
        wxASSERT( IsValidUtf8LeadByte(c) );
182
        return GetUTF8IterOffset(c);
183
    }
184
185
    // decodes single UTF-8 character from UTF-8 string
186
    static wxUniChar DecodeChar(std::string::const_iterator i)
187
    {
188
        if ( (unsigned char)*i < 0x80 )
189
            return (int)*i;
190
        return DecodeNonAsciiChar(i);
191
    }
192
193
private:
194
    static wxUniChar DecodeNonAsciiChar(std::string::const_iterator i);
195
};
196
#endif // wxUSE_UNICODE_UTF8
197
198
199
#if wxUSE_UNICODE_UTF8
200
typedef wxStringOperationsUtf8 wxStringOperations;
201
#else
202
typedef wxStringOperationsWchar wxStringOperations;
203
#endif
204
205
#endif  // _WX_WXSTRINGOPS_H_