Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svtools/source/svrtf/svparser.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <svtools/svparser.hxx>
21
#include <svtools/htmltokn.h>
22
#include <tools/stream.hxx>
23
#include <tools/debug.hxx>
24
#include <rtl/textcvt.h>
25
#include <rtl/tencinfo.h>
26
#include <rtl/character.hxx>
27
#include <sal/log.hxx>
28
#include <unicode/ucsdet.h>
29
#include <comphelper/configuration.hxx>
30
31
#include <vector>
32
33
// structure to store the actual data
34
template<typename T>
35
struct SvParser_Impl
36
{
37
    OUString        aToken;             // parsed token
38
    sal_uInt64      nFilePos;           // actual position in stream
39
    sal_uInt32      nlLineNr;           // actual line number
40
    sal_uInt32      nlLinePos;          // actual column number
41
    tools::Long            nTokenValue;        // extra value (RTF)
42
    bool            bTokenHasValue;     // indicates whether nTokenValue is valid
43
    T               nToken;             // actual Token
44
    sal_uInt32      nNextCh;            // actual character
45
    T               nSaveToken;         // the token from Continue
46
47
    rtl_TextToUnicodeConverter hConv;
48
    rtl_TextToUnicodeContext   hContext;
49
50
    SvParser_Impl()
51
69.8k
        : nFilePos(0)
52
69.8k
        , nlLineNr(0)
53
69.8k
        , nlLinePos(0)
54
69.8k
        , nTokenValue(0)
55
69.8k
        , bTokenHasValue(false)
56
69.8k
        , nToken(static_cast<T>(0))
57
69.8k
        , nNextCh(0)
58
69.8k
        , nSaveToken(static_cast<T>(0))
59
69.8k
        , hConv( nullptr )
60
69.8k
        , hContext( reinterpret_cast<rtl_TextToUnicodeContext>(1) )
61
69.8k
    {
62
69.8k
    }
SvParser_Impl<int>::SvParser_Impl()
Line
Count
Source
51
25.3k
        : nFilePos(0)
52
25.3k
        , nlLineNr(0)
53
25.3k
        , nlLinePos(0)
54
25.3k
        , nTokenValue(0)
55
25.3k
        , bTokenHasValue(false)
56
25.3k
        , nToken(static_cast<T>(0))
57
25.3k
        , nNextCh(0)
58
25.3k
        , nSaveToken(static_cast<T>(0))
59
25.3k
        , hConv( nullptr )
60
25.3k
        , hContext( reinterpret_cast<rtl_TextToUnicodeContext>(1) )
61
25.3k
    {
62
25.3k
    }
SvParser_Impl<HtmlTokenId>::SvParser_Impl()
Line
Count
Source
51
44.4k
        : nFilePos(0)
52
44.4k
        , nlLineNr(0)
53
44.4k
        , nlLinePos(0)
54
44.4k
        , nTokenValue(0)
55
44.4k
        , bTokenHasValue(false)
56
44.4k
        , nToken(static_cast<T>(0))
57
44.4k
        , nNextCh(0)
58
44.4k
        , nSaveToken(static_cast<T>(0))
59
44.4k
        , hConv( nullptr )
60
44.4k
        , hContext( reinterpret_cast<rtl_TextToUnicodeContext>(1) )
61
44.4k
    {
62
44.4k
    }
63
64
};
65
66
67
template<typename T>
68
SvParser<T>::TokenStackType::TokenStackType()
69
260k
  : nTokenValue(0)
70
260k
    , bTokenHasValue(false)
71
260k
    , nTokenId(static_cast<T>(0))
72
260k
{
73
260k
}
SvParser<int>::TokenStackType::TokenStackType()
Line
Count
Source
69
126k
  : nTokenValue(0)
70
126k
    , bTokenHasValue(false)
71
126k
    , nTokenId(static_cast<T>(0))
72
126k
{
73
126k
}
SvParser<HtmlTokenId>::TokenStackType::TokenStackType()
Line
Count
Source
69
133k
  : nTokenValue(0)
70
133k
    , bTokenHasValue(false)
71
133k
    , nTokenId(static_cast<T>(0))
72
133k
{
73
133k
}
74
75
// Constructor
76
template<typename T>
77
SvParser<T>::SvParser( SvStream& rIn, sal_uInt8 nStackSize )
78
69.8k
    : rInput( rIn )
79
69.8k
    , nlLineNr( 1 )
80
69.8k
    , nlLinePos( 1 )
81
69.8k
    , nConversionErrors( 0 )
82
69.8k
    , pImplData( nullptr )
83
69.8k
    , m_nTokenIndex(0)
84
69.8k
    , nTokenValue( 0 )
85
69.8k
    , bTokenHasValue( false )
86
69.8k
    , bFuzzing(comphelper::IsFuzzing())
87
69.8k
    , eState( SvParserState::NotStarted )
88
69.8k
    , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
89
69.8k
    , nNextChPos(0)
90
69.8k
    , nNextCh(0)
91
69.8k
    , bSwitchToUCS2(false)
92
69.8k
    , bRTF_InTextRead(false)
93
69.8k
    , nTokenStackSize( nStackSize )
94
69.8k
    , nTokenStackPos( 0 )
95
69.8k
{
96
69.8k
    eState = SvParserState::NotStarted;
97
69.8k
    if( nTokenStackSize < 3 )
98
0
        nTokenStackSize = 3;
99
69.8k
    pTokenStack.reset(new TokenStackType[ nTokenStackSize ]);
100
69.8k
    pTokenStackPos = pTokenStack.get();
101
69.8k
}
SvParser<int>::SvParser(SvStream&, unsigned char)
Line
Count
Source
78
25.3k
    : rInput( rIn )
79
25.3k
    , nlLineNr( 1 )
80
25.3k
    , nlLinePos( 1 )
81
25.3k
    , nConversionErrors( 0 )
82
25.3k
    , pImplData( nullptr )
83
25.3k
    , m_nTokenIndex(0)
84
25.3k
    , nTokenValue( 0 )
85
25.3k
    , bTokenHasValue( false )
86
25.3k
    , bFuzzing(comphelper::IsFuzzing())
87
25.3k
    , eState( SvParserState::NotStarted )
88
25.3k
    , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
89
25.3k
    , nNextChPos(0)
90
25.3k
    , nNextCh(0)
91
25.3k
    , bSwitchToUCS2(false)
92
25.3k
    , bRTF_InTextRead(false)
93
25.3k
    , nTokenStackSize( nStackSize )
94
25.3k
    , nTokenStackPos( 0 )
95
25.3k
{
96
25.3k
    eState = SvParserState::NotStarted;
97
25.3k
    if( nTokenStackSize < 3 )
98
0
        nTokenStackSize = 3;
99
25.3k
    pTokenStack.reset(new TokenStackType[ nTokenStackSize ]);
100
25.3k
    pTokenStackPos = pTokenStack.get();
101
25.3k
}
SvParser<HtmlTokenId>::SvParser(SvStream&, unsigned char)
Line
Count
Source
78
44.4k
    : rInput( rIn )
79
44.4k
    , nlLineNr( 1 )
80
44.4k
    , nlLinePos( 1 )
81
44.4k
    , nConversionErrors( 0 )
82
44.4k
    , pImplData( nullptr )
83
44.4k
    , m_nTokenIndex(0)
84
44.4k
    , nTokenValue( 0 )
85
44.4k
    , bTokenHasValue( false )
86
44.4k
    , bFuzzing(comphelper::IsFuzzing())
87
44.4k
    , eState( SvParserState::NotStarted )
88
44.4k
    , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
89
44.4k
    , nNextChPos(0)
90
44.4k
    , nNextCh(0)
91
44.4k
    , bSwitchToUCS2(false)
92
44.4k
    , bRTF_InTextRead(false)
93
44.4k
    , nTokenStackSize( nStackSize )
94
44.4k
    , nTokenStackPos( 0 )
95
44.4k
{
96
44.4k
    eState = SvParserState::NotStarted;
97
44.4k
    if( nTokenStackSize < 3 )
98
0
        nTokenStackSize = 3;
99
44.4k
    pTokenStack.reset(new TokenStackType[ nTokenStackSize ]);
100
44.4k
    pTokenStackPos = pTokenStack.get();
101
44.4k
}
102
103
template<typename T>
104
SvParser<T>::~SvParser()
105
69.8k
{
106
69.8k
    if( pImplData && pImplData->hConv )
107
68.8k
    {
108
68.8k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
109
68.8k
                                         pImplData->hContext );
110
68.8k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
111
68.8k
    }
112
113
69.8k
    pTokenStack.reset();
114
69.8k
}
SvParser<int>::~SvParser()
Line
Count
Source
105
25.3k
{
106
25.3k
    if( pImplData && pImplData->hConv )
107
24.8k
    {
108
24.8k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
109
24.8k
                                         pImplData->hContext );
110
24.8k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
111
24.8k
    }
112
113
25.3k
    pTokenStack.reset();
114
25.3k
}
SvParser<HtmlTokenId>::~SvParser()
Line
Count
Source
105
44.4k
{
106
44.4k
    if( pImplData && pImplData->hConv )
107
43.9k
    {
108
43.9k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
109
43.9k
                                         pImplData->hContext );
110
43.9k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
111
43.9k
    }
112
113
44.4k
    pTokenStack.reset();
114
44.4k
}
115
116
1.08M
template<typename T> SvParserState SvParser<T>::GetStatus() const { return eState; }
SvParser<int>::GetStatus() const
Line
Count
Source
116
24.8k
template<typename T> SvParserState SvParser<T>::GetStatus() const { return eState; }
SvParser<HtmlTokenId>::GetStatus() const
Line
Count
Source
116
1.06M
template<typename T> SvParserState SvParser<T>::GetStatus() const { return eState; }
117
3.77M
template<typename T> sal_uInt32 SvParser<T>::GetLineNr() const       { return nlLineNr; }
Unexecuted instantiation: SvParser<int>::GetLineNr() const
SvParser<HtmlTokenId>::GetLineNr() const
Line
Count
Source
117
3.77M
template<typename T> sal_uInt32 SvParser<T>::GetLineNr() const       { return nlLineNr; }
118
3.96M
template<typename T> sal_uInt32 SvParser<T>::GetLinePos() const      { return nlLinePos; }
Unexecuted instantiation: SvParser<int>::GetLinePos() const
SvParser<HtmlTokenId>::GetLinePos() const
Line
Count
Source
118
3.96M
template<typename T> sal_uInt32 SvParser<T>::GetLinePos() const      { return nlLinePos; }
119
2.43M
template<typename T> void       SvParser<T>::IncLineNr()             { ++nlLineNr; }
SvParser<int>::IncLineNr()
Line
Count
Source
119
1.07M
template<typename T> void       SvParser<T>::IncLineNr()             { ++nlLineNr; }
SvParser<HtmlTokenId>::IncLineNr()
Line
Count
Source
119
1.35M
template<typename T> void       SvParser<T>::IncLineNr()             { ++nlLineNr; }
120
115M
template<typename T> sal_uInt32 SvParser<T>::IncLinePos()            { return ++nlLinePos; }
SvParser<int>::IncLinePos()
Line
Count
Source
120
22.2M
template<typename T> sal_uInt32 SvParser<T>::IncLinePos()            { return ++nlLinePos; }
SvParser<HtmlTokenId>::IncLinePos()
Line
Count
Source
120
93.4M
template<typename T> sal_uInt32 SvParser<T>::IncLinePos()            { return ++nlLinePos; }
121
50.1k
template<typename T> void       SvParser<T>::SetLineNr( sal_uInt32 nlNum ) { nlLineNr = nlNum; }
Unexecuted instantiation: SvParser<int>::SetLineNr(unsigned int)
SvParser<HtmlTokenId>::SetLineNr(unsigned int)
Line
Count
Source
121
50.1k
template<typename T> void       SvParser<T>::SetLineNr( sal_uInt32 nlNum ) { nlLineNr = nlNum; }
122
2.48M
template<typename T> void       SvParser<T>::SetLinePos( sal_uInt32 nlPos ) {   nlLinePos = nlPos; }
SvParser<int>::SetLinePos(unsigned int)
Line
Count
Source
122
1.07M
template<typename T> void       SvParser<T>::SetLinePos( sal_uInt32 nlPos ) {   nlLinePos = nlPos; }
SvParser<HtmlTokenId>::SetLinePos(unsigned int)
Line
Count
Source
122
1.40M
template<typename T> void       SvParser<T>::SetLinePos( sal_uInt32 nlPos ) {   nlLinePos = nlPos; }
123
154M
template<typename T> bool       SvParser<T>::IsParserWorking() const { return SvParserState::Working == eState; }
SvParser<int>::IsParserWorking() const
Line
Count
Source
123
17.2M
template<typename T> bool       SvParser<T>::IsParserWorking() const { return SvParserState::Working == eState; }
SvParser<HtmlTokenId>::IsParserWorking() const
Line
Count
Source
123
137M
template<typename T> bool       SvParser<T>::IsParserWorking() const { return SvParserState::Working == eState; }
124
370k
template<typename T> rtl_TextEncoding SvParser<T>::GetSrcEncoding() const { return eSrcEnc; }
SvParser<int>::GetSrcEncoding() const
Line
Count
Source
124
367k
template<typename T> rtl_TextEncoding SvParser<T>::GetSrcEncoding() const { return eSrcEnc; }
SvParser<HtmlTokenId>::GetSrcEncoding() const
Line
Count
Source
124
3.55k
template<typename T> rtl_TextEncoding SvParser<T>::GetSrcEncoding() const { return eSrcEnc; }
125
44.4k
template<typename T> void       SvParser<T>::SetSwitchToUCS2( bool bSet ) { bSwitchToUCS2 = bSet; }
Unexecuted instantiation: SvParser<int>::SetSwitchToUCS2(bool)
SvParser<HtmlTokenId>::SetSwitchToUCS2(bool)
Line
Count
Source
125
44.4k
template<typename T> void       SvParser<T>::SetSwitchToUCS2( bool bSet ) { bSwitchToUCS2 = bSet; }
126
0
template<typename T> bool       SvParser<T>::IsSwitchToUCS2() const { return bSwitchToUCS2; }
Unexecuted instantiation: SvParser<int>::IsSwitchToUCS2() const
Unexecuted instantiation: SvParser<HtmlTokenId>::IsSwitchToUCS2() const
127
11.6k
template<typename T> sal_uInt16 SvParser<T>::GetCharSize() const { return (RTL_TEXTENCODING_UCS2 == eSrcEnc) ? 2 : 1; }
Unexecuted instantiation: SvParser<int>::GetCharSize() const
SvParser<HtmlTokenId>::GetCharSize() const
Line
Count
Source
127
11.6k
template<typename T> sal_uInt16 SvParser<T>::GetCharSize() const { return (RTL_TEXTENCODING_UCS2 == eSrcEnc) ? 2 : 1; }
128
template<typename T> Link<LinkParamNone*,void> SvParser<T>::GetAsynchCallLink() const
129
0
{
130
0
    return LINK( const_cast<SvParser*>(this), SvParser, NewDataRead );
131
0
}
Unexecuted instantiation: SvParser<int>::GetAsynchCallLink() const
Unexecuted instantiation: SvParser<HtmlTokenId>::GetAsynchCallLink() const
132
133
template<typename T>
134
void SvParser<T>::ClearTxtConvContext()
135
101k
{
136
101k
    if( pImplData && pImplData->hConv )
137
95.5k
        rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
138
101k
}
Unexecuted instantiation: SvParser<int>::ClearTxtConvContext()
SvParser<HtmlTokenId>::ClearTxtConvContext()
Line
Count
Source
135
101k
{
136
101k
    if( pImplData && pImplData->hConv )
137
95.5k
        rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
138
101k
}
139
140
template<typename T>
141
void SvParser<T>::SetSrcEncoding( rtl_TextEncoding eEnc )
142
373k
{
143
373k
    if( eEnc == eSrcEnc )
144
220k
        return;
145
146
153k
    if( pImplData && pImplData->hConv )
147
79.0k
    {
148
79.0k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
149
79.0k
                                         pImplData->hContext );
150
79.0k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
151
79.0k
        pImplData->hConv = nullptr;
152
79.0k
        pImplData->hContext = reinterpret_cast<rtl_TextToUnicodeContext>(1);
153
79.0k
    }
154
155
153k
    if( rtl_isOctetTextEncoding(eEnc) ||
156
2.99k
        RTL_TEXTENCODING_UCS2 == eEnc  )
157
150k
    {
158
150k
        eSrcEnc = eEnc;
159
150k
        if( !pImplData )
160
69.8k
            pImplData.reset(new SvParser_Impl<T>);
161
150k
        pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
162
150k
        DBG_ASSERT( pImplData->hConv,
163
150k
                    "SvParser::SetSrcEncoding: no converter for source encoding" );
164
150k
        if( !pImplData->hConv )
165
2.79k
            eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
166
147k
        else
167
147k
            pImplData->hContext =
168
147k
                rtl_createTextToUnicodeContext( pImplData->hConv );
169
150k
    }
170
2.99k
    else
171
2.99k
    {
172
2.99k
        SAL_WARN( "svtools",
173
2.99k
                    "SvParser::SetSrcEncoding: invalid source encoding" );
174
2.99k
        eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
175
2.99k
    }
176
153k
}
SvParser<int>::SetSrcEncoding(unsigned short)
Line
Count
Source
142
261k
{
143
261k
    if( eEnc == eSrcEnc )
144
212k
        return;
145
146
48.5k
    if( pImplData && pImplData->hConv )
147
18.5k
    {
148
18.5k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
149
18.5k
                                         pImplData->hContext );
150
18.5k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
151
18.5k
        pImplData->hConv = nullptr;
152
18.5k
        pImplData->hContext = reinterpret_cast<rtl_TextToUnicodeContext>(1);
153
18.5k
    }
154
155
48.5k
    if( rtl_isOctetTextEncoding(eEnc) ||
156
2.99k
        RTL_TEXTENCODING_UCS2 == eEnc  )
157
45.5k
    {
158
45.5k
        eSrcEnc = eEnc;
159
45.5k
        if( !pImplData )
160
25.3k
            pImplData.reset(new SvParser_Impl<T>);
161
45.5k
        pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
162
45.5k
        DBG_ASSERT( pImplData->hConv,
163
45.5k
                    "SvParser::SetSrcEncoding: no converter for source encoding" );
164
45.5k
        if( !pImplData->hConv )
165
2.13k
            eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
166
43.4k
        else
167
43.4k
            pImplData->hContext =
168
43.4k
                rtl_createTextToUnicodeContext( pImplData->hConv );
169
45.5k
    }
170
2.99k
    else
171
2.99k
    {
172
2.99k
        SAL_WARN( "svtools",
173
2.99k
                    "SvParser::SetSrcEncoding: invalid source encoding" );
174
2.99k
        eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
175
2.99k
    }
176
48.5k
}
SvParser<HtmlTokenId>::SetSrcEncoding(unsigned short)
Line
Count
Source
142
112k
{
143
112k
    if( eEnc == eSrcEnc )
144
7.74k
        return;
145
146
105k
    if( pImplData && pImplData->hConv )
147
60.4k
    {
148
60.4k
        rtl_destroyTextToUnicodeContext( pImplData->hConv,
149
60.4k
                                         pImplData->hContext );
150
60.4k
        rtl_destroyTextToUnicodeConverter( pImplData->hConv );
151
60.4k
        pImplData->hConv = nullptr;
152
60.4k
        pImplData->hContext = reinterpret_cast<rtl_TextToUnicodeContext>(1);
153
60.4k
    }
154
155
105k
    if( rtl_isOctetTextEncoding(eEnc) ||
156
0
        RTL_TEXTENCODING_UCS2 == eEnc  )
157
105k
    {
158
105k
        eSrcEnc = eEnc;
159
105k
        if( !pImplData )
160
44.4k
            pImplData.reset(new SvParser_Impl<T>);
161
105k
        pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
162
105k
        DBG_ASSERT( pImplData->hConv,
163
105k
                    "SvParser::SetSrcEncoding: no converter for source encoding" );
164
105k
        if( !pImplData->hConv )
165
661
            eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
166
104k
        else
167
104k
            pImplData->hContext =
168
104k
                rtl_createTextToUnicodeContext( pImplData->hConv );
169
105k
    }
170
0
    else
171
0
    {
172
0
        SAL_WARN( "svtools",
173
0
                    "SvParser::SetSrcEncoding: invalid source encoding" );
174
0
        eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
175
0
    }
176
105k
}
177
178
template<typename T>
179
void SvParser<T>::RereadLookahead()
180
58.4k
{
181
58.4k
    rInput.Seek(nNextChPos);
182
58.4k
    nNextCh = GetNextChar();
183
58.4k
}
SvParser<int>::RereadLookahead()
Line
Count
Source
180
58.4k
{
181
58.4k
    rInput.Seek(nNextChPos);
182
58.4k
    nNextCh = GetNextChar();
183
58.4k
}
Unexecuted instantiation: SvParser<HtmlTokenId>::RereadLookahead()
184
185
template<typename T>
186
sal_uInt32 SvParser<T>::GetNextChar()
187
120M
{
188
120M
    sal_uInt32 c = 0U;
189
190
    // When reading multiple bytes, we don't have to care about the file
191
    // position when we run into the pending state. The file position is
192
    // maintained by SaveState/RestoreState.
193
120M
    if( bSwitchToUCS2 && 0 == rInput.Tell() )
194
44.4k
    {
195
44.4k
        rInput.DetectEncoding(65535); // Arbitrarily chosen 64KiB buffer
196
44.4k
        if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UCS2)
197
923
            eSrcEnc = RTL_TEXTENCODING_UCS2;
198
43.5k
        else if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UTF8)
199
4.94k
            SetSrcEncoding(RTL_TEXTENCODING_UTF8);
200
44.4k
        bSwitchToUCS2 = false;
201
44.4k
    }
202
203
120M
    bool bErr;
204
120M
    nNextChPos = rInput.Tell();
205
206
120M
    if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
207
1.08M
    {
208
1.08M
        sal_Unicode cUC;
209
1.08M
        rInput.ReadUtf16(cUC);
210
1.08M
        bErr = !rInput.good();
211
1.08M
        if( !bErr )
212
1.08M
        {
213
1.08M
            c = cUC;
214
1.08M
            if (rtl::isHighSurrogate(cUC))
215
186k
            {
216
186k
                const sal_uInt64 nPos = rInput.Tell();
217
186k
                rInput.ReadUtf16(cUC);
218
186k
                if (rtl::isLowSurrogate(cUC)) // can only be true when ReadUtf16 succeeded
219
454
                    c = rtl::combineSurrogates(c, cUC);
220
185k
                else
221
185k
                    rInput.Seek(nPos); // process lone high surrogate
222
186k
            }
223
1.08M
        }
224
1.08M
    }
225
119M
    else
226
119M
    {
227
119M
        sal_Size nChars = 0;
228
119M
        do
229
119M
        {
230
119M
            char c1;    // signed, that's the text converter expects
231
119M
            rInput.ReadChar( c1 );
232
119M
            bErr = !rInput.good();
233
119M
            if( !bErr )
234
119M
            {
235
119M
                if (
236
119M
                     RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
237
114M
                     RTL_TEXTENCODING_SYMBOL == eSrcEnc
238
119M
                   )
239
5.09M
                {
240
                    // no conversion shall take place
241
5.09M
                    c = reinterpret_cast<unsigned char&>( c1 );
242
5.09M
                    nChars = 1;
243
5.09M
                }
244
113M
                else
245
113M
                {
246
113M
                    assert(pImplData && pImplData->hConv && "no text converter!");
247
248
113M
                    sal_Unicode cUC;
249
113M
                    sal_uInt32 nInfo = 0;
250
113M
                    sal_Size nCvtBytes;
251
113M
                    nChars = rtl_convertTextToUnicode(
252
113M
                                pImplData->hConv, pImplData->hContext,
253
113M
                                &c1, 1, &cUC, 1,
254
113M
                                RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
255
113M
                                RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
256
113M
                                RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
257
113M
                                &nInfo, &nCvtBytes);
258
113M
                    if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
259
673k
                    {
260
                        // The conversion wasn't successful because we haven't
261
                        // read enough characters.
262
673k
                        if( pImplData->hContext != reinterpret_cast<rtl_TextToUnicodeContext>(1) )
263
653k
                        {
264
653k
                            sal_Unicode sCh[2];
265
1.57M
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
266
918k
                            {
267
918k
                                rInput.ReadChar( c1 );
268
918k
                                bErr = !rInput.good();
269
918k
                                if( bErr )
270
1.41k
                                    break;
271
272
917k
                                nChars = rtl_convertTextToUnicode(
273
917k
                                            pImplData->hConv, pImplData->hContext,
274
917k
                                            &c1, 1, sCh , 2,
275
917k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
276
917k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
277
917k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
278
917k
                                            &nInfo, &nCvtBytes);
279
917k
                            }
280
653k
                            if( !bErr )
281
652k
                            {
282
652k
                                if( 1 == nChars && 0 == nInfo )
283
256k
                                {
284
256k
                                    c = sal_uInt32( sCh[0] );
285
256k
                                }
286
395k
                                else if( 2 == nChars && 0 == nInfo )
287
60.8k
                                {
288
60.8k
                                    c = rtl::combineSurrogates( sCh[0], sCh[1] );
289
60.8k
                                }
290
334k
                                else if( 0 != nChars || 0 != nInfo )
291
334k
                                {
292
334k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
293
334k
                                        "source buffer is too small" );
294
334k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
295
334k
                                         "there is a conversion error" );
296
334k
                                    DBG_ASSERT( 0 == nChars,
297
334k
                                       "there is a converted character, but an error" );
298
                                    // There are still errors, but nothing we can
299
                                    // do
300
334k
                                    c = '?';
301
334k
                                    nChars = 1;
302
334k
                                    ++nConversionErrors;
303
334k
                                }
304
652k
                            }
305
653k
                        }
306
20.0k
                        else
307
20.0k
                        {
308
20.0k
                            char sBuffer[10];
309
20.0k
                            sBuffer[0] = c1;
310
20.0k
                            sal_uInt16 nLen = 1;
311
39.9k
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 &&
312
20.0k
                                    nLen < 10 )
313
20.0k
                            {
314
20.0k
                                rInput.ReadChar( c1 );
315
20.0k
                                bErr = !rInput.good();
316
20.0k
                                if( bErr )
317
147
                                    break;
318
319
19.9k
                                sBuffer[nLen++] = c1;
320
19.9k
                                nChars = rtl_convertTextToUnicode(
321
19.9k
                                            pImplData->hConv, nullptr, sBuffer, nLen, &cUC, 1,
322
19.9k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
323
19.9k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
324
19.9k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
325
19.9k
                                            &nInfo, &nCvtBytes);
326
19.9k
                            }
327
20.0k
                            if( !bErr )
328
19.9k
                            {
329
19.9k
                                if( 1 == nChars && 0 == nInfo )
330
11.1k
                                {
331
11.1k
                                    DBG_ASSERT( nCvtBytes == nLen,
332
11.1k
                                                "no all bytes have been converted!" );
333
11.1k
                                    c = cUC;
334
11.1k
                                }
335
8.77k
                                else
336
8.77k
                                {
337
8.77k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
338
8.77k
                                        "source buffer is too small" );
339
8.77k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
340
8.77k
                                         "there is a conversion error" );
341
8.77k
                                    DBG_ASSERT( 0 == nChars,
342
8.77k
                                       "there is a converted character, but an error" );
343
344
                                    // There are still errors, so we use the first
345
                                    // character and restart after that.
346
8.77k
                                    c = reinterpret_cast<unsigned char&>( sBuffer[0] );
347
8.77k
                                    rInput.SeekRel( -(nLen-1) );
348
8.77k
                                    nChars = 1;
349
8.77k
                                    ++nConversionErrors;
350
8.77k
                                }
351
19.9k
                            }
352
20.0k
                        }
353
673k
                    }
354
113M
                    else if( 1 == nChars && 0 == nInfo )
355
112M
                    {
356
                        // The conversion was successful
357
112M
                        DBG_ASSERT( nCvtBytes == 1,
358
112M
                                    "no all bytes have been converted!" );
359
112M
                        c = cUC;
360
112M
                    }
361
965k
                    else if( 0 != nChars || 0 != nInfo )
362
965k
                    {
363
965k
                        DBG_ASSERT( 0 == nChars,
364
965k
                                "there is a converted character, but an error" );
365
965k
                        DBG_ASSERT( 0 != nInfo,
366
965k
                                "there is no converted character and no error" );
367
                        // #73398#: If the character could not be converted,
368
                        // because a conversion is not available, do no conversion at all.
369
965k
                        c = reinterpret_cast<unsigned char&>( c1 );
370
965k
                        nChars = 1;
371
965k
                        ++nConversionErrors;
372
965k
                    }
373
113M
                }
374
119M
            }
375
119M
        }
376
119M
        while( 0 == nChars  && !bErr );
377
119M
    }
378
379
120M
    if ( ! rtl::isUnicodeScalarValue( c ) )
380
189k
        c = '?' ;
381
382
120M
    if (bFuzzing && nConversionErrors > 128)
383
1.96M
    {
384
1.96M
        SAL_WARN("svtools", "SvParser::GetNextChar too many conversion errors while fuzzing, abandoning for performance");
385
1.96M
        bErr = true;
386
1.96M
    }
387
388
120M
    if( bErr )
389
2.10M
    {
390
2.10M
        if( ERRCODE_IO_PENDING == rInput.GetError() )
391
0
        {
392
0
            eState = SvParserState::Pending;
393
0
            return c;
394
0
        }
395
2.10M
        else
396
2.10M
            return sal_Unicode(EOF);
397
2.10M
    }
398
399
118M
    if( c == '\n' )
400
2.43M
    {
401
2.43M
        IncLineNr();
402
2.43M
        SetLinePos( 1 );
403
2.43M
    }
404
115M
    else
405
115M
        IncLinePos();
406
407
118M
    return c;
408
120M
}
SvParser<int>::GetNextChar()
Line
Count
Source
187
23.3M
{
188
23.3M
    sal_uInt32 c = 0U;
189
190
    // When reading multiple bytes, we don't have to care about the file
191
    // position when we run into the pending state. The file position is
192
    // maintained by SaveState/RestoreState.
193
23.3M
    if( bSwitchToUCS2 && 0 == rInput.Tell() )
194
0
    {
195
0
        rInput.DetectEncoding(65535); // Arbitrarily chosen 64KiB buffer
196
0
        if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UCS2)
197
0
            eSrcEnc = RTL_TEXTENCODING_UCS2;
198
0
        else if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UTF8)
199
0
            SetSrcEncoding(RTL_TEXTENCODING_UTF8);
200
0
        bSwitchToUCS2 = false;
201
0
    }
202
203
23.3M
    bool bErr;
204
23.3M
    nNextChPos = rInput.Tell();
205
206
23.3M
    if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
207
0
    {
208
0
        sal_Unicode cUC;
209
0
        rInput.ReadUtf16(cUC);
210
0
        bErr = !rInput.good();
211
0
        if( !bErr )
212
0
        {
213
0
            c = cUC;
214
0
            if (rtl::isHighSurrogate(cUC))
215
0
            {
216
0
                const sal_uInt64 nPos = rInput.Tell();
217
0
                rInput.ReadUtf16(cUC);
218
0
                if (rtl::isLowSurrogate(cUC)) // can only be true when ReadUtf16 succeeded
219
0
                    c = rtl::combineSurrogates(c, cUC);
220
0
                else
221
0
                    rInput.Seek(nPos); // process lone high surrogate
222
0
            }
223
0
        }
224
0
    }
225
23.3M
    else
226
23.3M
    {
227
23.3M
        sal_Size nChars = 0;
228
23.3M
        do
229
23.3M
        {
230
23.3M
            char c1;    // signed, that's the text converter expects
231
23.3M
            rInput.ReadChar( c1 );
232
23.3M
            bErr = !rInput.good();
233
23.3M
            if( !bErr )
234
23.3M
            {
235
23.3M
                if (
236
23.3M
                     RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
237
22.6M
                     RTL_TEXTENCODING_SYMBOL == eSrcEnc
238
23.3M
                   )
239
731k
                {
240
                    // no conversion shall take place
241
731k
                    c = reinterpret_cast<unsigned char&>( c1 );
242
731k
                    nChars = 1;
243
731k
                }
244
22.6M
                else
245
22.6M
                {
246
22.6M
                    assert(pImplData && pImplData->hConv && "no text converter!");
247
248
22.6M
                    sal_Unicode cUC;
249
22.6M
                    sal_uInt32 nInfo = 0;
250
22.6M
                    sal_Size nCvtBytes;
251
22.6M
                    nChars = rtl_convertTextToUnicode(
252
22.6M
                                pImplData->hConv, pImplData->hContext,
253
22.6M
                                &c1, 1, &cUC, 1,
254
22.6M
                                RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
255
22.6M
                                RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
256
22.6M
                                RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
257
22.6M
                                &nInfo, &nCvtBytes);
258
22.6M
                    if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
259
61.0k
                    {
260
                        // The conversion wasn't successful because we haven't
261
                        // read enough characters.
262
61.0k
                        if( pImplData->hContext != reinterpret_cast<rtl_TextToUnicodeContext>(1) )
263
48.5k
                        {
264
48.5k
                            sal_Unicode sCh[2];
265
135k
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
266
86.8k
                            {
267
86.8k
                                rInput.ReadChar( c1 );
268
86.8k
                                bErr = !rInput.good();
269
86.8k
                                if( bErr )
270
131
                                    break;
271
272
86.6k
                                nChars = rtl_convertTextToUnicode(
273
86.6k
                                            pImplData->hConv, pImplData->hContext,
274
86.6k
                                            &c1, 1, sCh , 2,
275
86.6k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
276
86.6k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
277
86.6k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
278
86.6k
                                            &nInfo, &nCvtBytes);
279
86.6k
                            }
280
48.5k
                            if( !bErr )
281
48.4k
                            {
282
48.4k
                                if( 1 == nChars && 0 == nInfo )
283
27.3k
                                {
284
27.3k
                                    c = sal_uInt32( sCh[0] );
285
27.3k
                                }
286
21.0k
                                else if( 2 == nChars && 0 == nInfo )
287
6.07k
                                {
288
6.07k
                                    c = rtl::combineSurrogates( sCh[0], sCh[1] );
289
6.07k
                                }
290
15.0k
                                else if( 0 != nChars || 0 != nInfo )
291
15.0k
                                {
292
15.0k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
293
15.0k
                                        "source buffer is too small" );
294
15.0k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
295
15.0k
                                         "there is a conversion error" );
296
15.0k
                                    DBG_ASSERT( 0 == nChars,
297
15.0k
                                       "there is a converted character, but an error" );
298
                                    // There are still errors, but nothing we can
299
                                    // do
300
15.0k
                                    c = '?';
301
15.0k
                                    nChars = 1;
302
15.0k
                                    ++nConversionErrors;
303
15.0k
                                }
304
48.4k
                            }
305
48.5k
                        }
306
12.4k
                        else
307
12.4k
                        {
308
12.4k
                            char sBuffer[10];
309
12.4k
                            sBuffer[0] = c1;
310
12.4k
                            sal_uInt16 nLen = 1;
311
24.8k
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 &&
312
12.4k
                                    nLen < 10 )
313
12.4k
                            {
314
12.4k
                                rInput.ReadChar( c1 );
315
12.4k
                                bErr = !rInput.good();
316
12.4k
                                if( bErr )
317
47
                                    break;
318
319
12.3k
                                sBuffer[nLen++] = c1;
320
12.3k
                                nChars = rtl_convertTextToUnicode(
321
12.3k
                                            pImplData->hConv, nullptr, sBuffer, nLen, &cUC, 1,
322
12.3k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
323
12.3k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
324
12.3k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
325
12.3k
                                            &nInfo, &nCvtBytes);
326
12.3k
                            }
327
12.4k
                            if( !bErr )
328
12.3k
                            {
329
12.3k
                                if( 1 == nChars && 0 == nInfo )
330
7.64k
                                {
331
7.64k
                                    DBG_ASSERT( nCvtBytes == nLen,
332
7.64k
                                                "no all bytes have been converted!" );
333
7.64k
                                    c = cUC;
334
7.64k
                                }
335
4.75k
                                else
336
4.75k
                                {
337
4.75k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
338
4.75k
                                        "source buffer is too small" );
339
4.75k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
340
4.75k
                                         "there is a conversion error" );
341
4.75k
                                    DBG_ASSERT( 0 == nChars,
342
4.75k
                                       "there is a converted character, but an error" );
343
344
                                    // There are still errors, so we use the first
345
                                    // character and restart after that.
346
4.75k
                                    c = reinterpret_cast<unsigned char&>( sBuffer[0] );
347
4.75k
                                    rInput.SeekRel( -(nLen-1) );
348
4.75k
                                    nChars = 1;
349
4.75k
                                    ++nConversionErrors;
350
4.75k
                                }
351
12.3k
                            }
352
12.4k
                        }
353
61.0k
                    }
354
22.5M
                    else if( 1 == nChars && 0 == nInfo )
355
22.4M
                    {
356
                        // The conversion was successful
357
22.4M
                        DBG_ASSERT( nCvtBytes == 1,
358
22.4M
                                    "no all bytes have been converted!" );
359
22.4M
                        c = cUC;
360
22.4M
                    }
361
84.5k
                    else if( 0 != nChars || 0 != nInfo )
362
84.5k
                    {
363
84.5k
                        DBG_ASSERT( 0 == nChars,
364
84.5k
                                "there is a converted character, but an error" );
365
84.5k
                        DBG_ASSERT( 0 != nInfo,
366
84.5k
                                "there is no converted character and no error" );
367
                        // #73398#: If the character could not be converted,
368
                        // because a conversion is not available, do no conversion at all.
369
84.5k
                        c = reinterpret_cast<unsigned char&>( c1 );
370
84.5k
                        nChars = 1;
371
84.5k
                        ++nConversionErrors;
372
84.5k
                    }
373
22.6M
                }
374
23.3M
            }
375
23.3M
        }
376
23.3M
        while( 0 == nChars  && !bErr );
377
23.3M
    }
378
379
23.3M
    if ( ! rtl::isUnicodeScalarValue( c ) )
380
0
        c = '?' ;
381
382
23.3M
    if (bFuzzing && nConversionErrors > 128)
383
415
    {
384
415
        SAL_WARN("svtools", "SvParser::GetNextChar too many conversion errors while fuzzing, abandoning for performance");
385
415
        bErr = true;
386
415
    }
387
388
23.3M
    if( bErr )
389
57.9k
    {
390
57.9k
        if( ERRCODE_IO_PENDING == rInput.GetError() )
391
0
        {
392
0
            eState = SvParserState::Pending;
393
0
            return c;
394
0
        }
395
57.9k
        else
396
57.9k
            return sal_Unicode(EOF);
397
57.9k
    }
398
399
23.3M
    if( c == '\n' )
400
1.07M
    {
401
1.07M
        IncLineNr();
402
1.07M
        SetLinePos( 1 );
403
1.07M
    }
404
22.2M
    else
405
22.2M
        IncLinePos();
406
407
23.3M
    return c;
408
23.3M
}
SvParser<HtmlTokenId>::GetNextChar()
Line
Count
Source
187
96.8M
{
188
96.8M
    sal_uInt32 c = 0U;
189
190
    // When reading multiple bytes, we don't have to care about the file
191
    // position when we run into the pending state. The file position is
192
    // maintained by SaveState/RestoreState.
193
96.8M
    if( bSwitchToUCS2 && 0 == rInput.Tell() )
194
44.4k
    {
195
44.4k
        rInput.DetectEncoding(65535); // Arbitrarily chosen 64KiB buffer
196
44.4k
        if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UCS2)
197
923
            eSrcEnc = RTL_TEXTENCODING_UCS2;
198
43.5k
        else if (rInput.GetStreamEncoding() == RTL_TEXTENCODING_UTF8)
199
4.94k
            SetSrcEncoding(RTL_TEXTENCODING_UTF8);
200
44.4k
        bSwitchToUCS2 = false;
201
44.4k
    }
202
203
96.8M
    bool bErr;
204
96.8M
    nNextChPos = rInput.Tell();
205
206
96.8M
    if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
207
1.08M
    {
208
1.08M
        sal_Unicode cUC;
209
1.08M
        rInput.ReadUtf16(cUC);
210
1.08M
        bErr = !rInput.good();
211
1.08M
        if( !bErr )
212
1.08M
        {
213
1.08M
            c = cUC;
214
1.08M
            if (rtl::isHighSurrogate(cUC))
215
186k
            {
216
186k
                const sal_uInt64 nPos = rInput.Tell();
217
186k
                rInput.ReadUtf16(cUC);
218
186k
                if (rtl::isLowSurrogate(cUC)) // can only be true when ReadUtf16 succeeded
219
454
                    c = rtl::combineSurrogates(c, cUC);
220
185k
                else
221
185k
                    rInput.Seek(nPos); // process lone high surrogate
222
186k
            }
223
1.08M
        }
224
1.08M
    }
225
95.7M
    else
226
95.7M
    {
227
95.7M
        sal_Size nChars = 0;
228
95.7M
        do
229
95.7M
        {
230
95.7M
            char c1;    // signed, that's the text converter expects
231
95.7M
            rInput.ReadChar( c1 );
232
95.7M
            bErr = !rInput.good();
233
95.7M
            if( !bErr )
234
95.7M
            {
235
95.7M
                if (
236
95.7M
                     RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
237
91.3M
                     RTL_TEXTENCODING_SYMBOL == eSrcEnc
238
95.7M
                   )
239
4.36M
                {
240
                    // no conversion shall take place
241
4.36M
                    c = reinterpret_cast<unsigned char&>( c1 );
242
4.36M
                    nChars = 1;
243
4.36M
                }
244
91.3M
                else
245
91.3M
                {
246
91.3M
                    assert(pImplData && pImplData->hConv && "no text converter!");
247
248
91.3M
                    sal_Unicode cUC;
249
91.3M
                    sal_uInt32 nInfo = 0;
250
91.3M
                    sal_Size nCvtBytes;
251
91.3M
                    nChars = rtl_convertTextToUnicode(
252
91.3M
                                pImplData->hConv, pImplData->hContext,
253
91.3M
                                &c1, 1, &cUC, 1,
254
91.3M
                                RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
255
91.3M
                                RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
256
91.3M
                                RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
257
91.3M
                                &nInfo, &nCvtBytes);
258
91.3M
                    if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
259
612k
                    {
260
                        // The conversion wasn't successful because we haven't
261
                        // read enough characters.
262
612k
                        if( pImplData->hContext != reinterpret_cast<rtl_TextToUnicodeContext>(1) )
263
605k
                        {
264
605k
                            sal_Unicode sCh[2];
265
1.43M
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 )
266
831k
                            {
267
831k
                                rInput.ReadChar( c1 );
268
831k
                                bErr = !rInput.good();
269
831k
                                if( bErr )
270
1.27k
                                    break;
271
272
830k
                                nChars = rtl_convertTextToUnicode(
273
830k
                                            pImplData->hConv, pImplData->hContext,
274
830k
                                            &c1, 1, sCh , 2,
275
830k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
276
830k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
277
830k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
278
830k
                                            &nInfo, &nCvtBytes);
279
830k
                            }
280
605k
                            if( !bErr )
281
603k
                            {
282
603k
                                if( 1 == nChars && 0 == nInfo )
283
229k
                                {
284
229k
                                    c = sal_uInt32( sCh[0] );
285
229k
                                }
286
374k
                                else if( 2 == nChars && 0 == nInfo )
287
54.8k
                                {
288
54.8k
                                    c = rtl::combineSurrogates( sCh[0], sCh[1] );
289
54.8k
                                }
290
319k
                                else if( 0 != nChars || 0 != nInfo )
291
319k
                                {
292
319k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
293
319k
                                        "source buffer is too small" );
294
319k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
295
319k
                                         "there is a conversion error" );
296
319k
                                    DBG_ASSERT( 0 == nChars,
297
319k
                                       "there is a converted character, but an error" );
298
                                    // There are still errors, but nothing we can
299
                                    // do
300
319k
                                    c = '?';
301
319k
                                    nChars = 1;
302
319k
                                    ++nConversionErrors;
303
319k
                                }
304
603k
                            }
305
605k
                        }
306
7.62k
                        else
307
7.62k
                        {
308
7.62k
                            char sBuffer[10];
309
7.62k
                            sBuffer[0] = c1;
310
7.62k
                            sal_uInt16 nLen = 1;
311
15.1k
                            while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0 &&
312
7.62k
                                    nLen < 10 )
313
7.62k
                            {
314
7.62k
                                rInput.ReadChar( c1 );
315
7.62k
                                bErr = !rInput.good();
316
7.62k
                                if( bErr )
317
100
                                    break;
318
319
7.52k
                                sBuffer[nLen++] = c1;
320
7.52k
                                nChars = rtl_convertTextToUnicode(
321
7.52k
                                            pImplData->hConv, nullptr, sBuffer, nLen, &cUC, 1,
322
7.52k
                                            RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
323
7.52k
                                            RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
324
7.52k
                                            RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
325
7.52k
                                            &nInfo, &nCvtBytes);
326
7.52k
                            }
327
7.62k
                            if( !bErr )
328
7.52k
                            {
329
7.52k
                                if( 1 == nChars && 0 == nInfo )
330
3.50k
                                {
331
3.50k
                                    DBG_ASSERT( nCvtBytes == nLen,
332
3.50k
                                                "no all bytes have been converted!" );
333
3.50k
                                    c = cUC;
334
3.50k
                                }
335
4.01k
                                else
336
4.01k
                                {
337
4.01k
                                    DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0,
338
4.01k
                                        "source buffer is too small" );
339
4.01k
                                    DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)) == 0,
340
4.01k
                                         "there is a conversion error" );
341
4.01k
                                    DBG_ASSERT( 0 == nChars,
342
4.01k
                                       "there is a converted character, but an error" );
343
344
                                    // There are still errors, so we use the first
345
                                    // character and restart after that.
346
4.01k
                                    c = reinterpret_cast<unsigned char&>( sBuffer[0] );
347
4.01k
                                    rInput.SeekRel( -(nLen-1) );
348
4.01k
                                    nChars = 1;
349
4.01k
                                    ++nConversionErrors;
350
4.01k
                                }
351
7.52k
                            }
352
7.62k
                        }
353
612k
                    }
354
90.7M
                    else if( 1 == nChars && 0 == nInfo )
355
89.8M
                    {
356
                        // The conversion was successful
357
89.8M
                        DBG_ASSERT( nCvtBytes == 1,
358
89.8M
                                    "no all bytes have been converted!" );
359
89.8M
                        c = cUC;
360
89.8M
                    }
361
881k
                    else if( 0 != nChars || 0 != nInfo )
362
881k
                    {
363
881k
                        DBG_ASSERT( 0 == nChars,
364
881k
                                "there is a converted character, but an error" );
365
881k
                        DBG_ASSERT( 0 != nInfo,
366
881k
                                "there is no converted character and no error" );
367
                        // #73398#: If the character could not be converted,
368
                        // because a conversion is not available, do no conversion at all.
369
881k
                        c = reinterpret_cast<unsigned char&>( c1 );
370
881k
                        nChars = 1;
371
881k
                        ++nConversionErrors;
372
881k
                    }
373
91.3M
                }
374
95.7M
            }
375
95.7M
        }
376
95.7M
        while( 0 == nChars  && !bErr );
377
95.7M
    }
378
379
96.8M
    if ( ! rtl::isUnicodeScalarValue( c ) )
380
189k
        c = '?' ;
381
382
96.8M
    if (bFuzzing && nConversionErrors > 128)
383
1.96M
    {
384
1.96M
        SAL_WARN("svtools", "SvParser::GetNextChar too many conversion errors while fuzzing, abandoning for performance");
385
1.96M
        bErr = true;
386
1.96M
    }
387
388
96.8M
    if( bErr )
389
2.04M
    {
390
2.04M
        if( ERRCODE_IO_PENDING == rInput.GetError() )
391
0
        {
392
0
            eState = SvParserState::Pending;
393
0
            return c;
394
0
        }
395
2.04M
        else
396
2.04M
            return sal_Unicode(EOF);
397
2.04M
    }
398
399
94.8M
    if( c == '\n' )
400
1.35M
    {
401
1.35M
        IncLineNr();
402
1.35M
        SetLinePos( 1 );
403
1.35M
    }
404
93.4M
    else
405
93.4M
        IncLinePos();
406
407
94.8M
    return c;
408
96.8M
}
409
410
template<typename T>
411
T SvParser<T>::GetNextToken()
412
12.5M
{
413
12.5M
    T nRet = static_cast<T>(0);
414
415
12.5M
    if( !nTokenStackPos )
416
11.5M
    {
417
11.5M
        aToken.setLength( 0 );     // empty token buffer
418
11.5M
        nTokenValue = -1;   // marker for no value read
419
11.5M
        bTokenHasValue = false;
420
421
11.5M
        nRet = GetNextToken_();
422
11.5M
        if( SvParserState::Pending == eState )
423
0
            return nRet;
424
11.5M
    }
425
426
12.5M
    ++pTokenStackPos;
427
12.5M
    if( pTokenStackPos == pTokenStack.get() + nTokenStackSize )
428
3.47M
        pTokenStackPos = pTokenStack.get();
429
430
    // pop from stack ??
431
12.5M
    if( nTokenStackPos )
432
1.00M
    {
433
1.00M
        --nTokenStackPos;
434
1.00M
        nTokenValue = pTokenStackPos->nTokenValue;
435
1.00M
        bTokenHasValue = pTokenStackPos->bTokenHasValue;
436
1.00M
        aToken = pTokenStackPos->sToken;
437
1.00M
        nRet = pTokenStackPos->nTokenId;
438
1.00M
        ++m_nTokenIndex;
439
1.00M
    }
440
    // no, now push actual value on stack
441
11.5M
    else if( SvParserState::Working == eState )
442
11.1M
    {
443
11.1M
        pTokenStackPos->sToken = aToken;
444
11.1M
        pTokenStackPos->nTokenValue = nTokenValue;
445
11.1M
        pTokenStackPos->bTokenHasValue = bTokenHasValue;
446
11.1M
        pTokenStackPos->nTokenId = nRet;
447
11.1M
        ++m_nTokenIndex;
448
11.1M
    }
449
342k
    else if( SvParserState::Accepted != eState && SvParserState::Pending != eState )
450
13.6k
        eState = SvParserState::Error;       // an error occurred
451
452
12.5M
    return nRet;
453
12.5M
}
SvParser<int>::GetNextToken()
Line
Count
Source
412
5.07M
{
413
5.07M
    T nRet = static_cast<T>(0);
414
415
5.07M
    if( !nTokenStackPos )
416
4.41M
    {
417
4.41M
        aToken.setLength( 0 );     // empty token buffer
418
4.41M
        nTokenValue = -1;   // marker for no value read
419
4.41M
        bTokenHasValue = false;
420
421
4.41M
        nRet = GetNextToken_();
422
4.41M
        if( SvParserState::Pending == eState )
423
0
            return nRet;
424
4.41M
    }
425
426
5.07M
    ++pTokenStackPos;
427
5.07M
    if( pTokenStackPos == pTokenStack.get() + nTokenStackSize )
428
1.00M
        pTokenStackPos = pTokenStack.get();
429
430
    // pop from stack ??
431
5.07M
    if( nTokenStackPos )
432
667k
    {
433
667k
        --nTokenStackPos;
434
667k
        nTokenValue = pTokenStackPos->nTokenValue;
435
667k
        bTokenHasValue = pTokenStackPos->bTokenHasValue;
436
667k
        aToken = pTokenStackPos->sToken;
437
667k
        nRet = pTokenStackPos->nTokenId;
438
667k
        ++m_nTokenIndex;
439
667k
    }
440
    // no, now push actual value on stack
441
4.41M
    else if( SvParserState::Working == eState )
442
4.38M
    {
443
4.38M
        pTokenStackPos->sToken = aToken;
444
4.38M
        pTokenStackPos->nTokenValue = nTokenValue;
445
4.38M
        pTokenStackPos->bTokenHasValue = bTokenHasValue;
446
4.38M
        pTokenStackPos->nTokenId = nRet;
447
4.38M
        ++m_nTokenIndex;
448
4.38M
    }
449
25.5k
    else if( SvParserState::Accepted != eState && SvParserState::Pending != eState )
450
1.81k
        eState = SvParserState::Error;       // an error occurred
451
452
5.07M
    return nRet;
453
5.07M
}
SvParser<HtmlTokenId>::GetNextToken()
Line
Count
Source
412
7.43M
{
413
7.43M
    T nRet = static_cast<T>(0);
414
415
7.43M
    if( !nTokenStackPos )
416
7.08M
    {
417
7.08M
        aToken.setLength( 0 );     // empty token buffer
418
7.08M
        nTokenValue = -1;   // marker for no value read
419
7.08M
        bTokenHasValue = false;
420
421
7.08M
        nRet = GetNextToken_();
422
7.08M
        if( SvParserState::Pending == eState )
423
0
            return nRet;
424
7.08M
    }
425
426
7.43M
    ++pTokenStackPos;
427
7.43M
    if( pTokenStackPos == pTokenStack.get() + nTokenStackSize )
428
2.46M
        pTokenStackPos = pTokenStack.get();
429
430
    // pop from stack ??
431
7.43M
    if( nTokenStackPos )
432
340k
    {
433
340k
        --nTokenStackPos;
434
340k
        nTokenValue = pTokenStackPos->nTokenValue;
435
340k
        bTokenHasValue = pTokenStackPos->bTokenHasValue;
436
340k
        aToken = pTokenStackPos->sToken;
437
340k
        nRet = pTokenStackPos->nTokenId;
438
340k
        ++m_nTokenIndex;
439
340k
    }
440
    // no, now push actual value on stack
441
7.08M
    else if( SvParserState::Working == eState )
442
6.77M
    {
443
6.77M
        pTokenStackPos->sToken = aToken;
444
6.77M
        pTokenStackPos->nTokenValue = nTokenValue;
445
6.77M
        pTokenStackPos->bTokenHasValue = bTokenHasValue;
446
6.77M
        pTokenStackPos->nTokenId = nRet;
447
6.77M
        ++m_nTokenIndex;
448
6.77M
    }
449
316k
    else if( SvParserState::Accepted != eState && SvParserState::Pending != eState )
450
11.8k
        eState = SvParserState::Error;       // an error occurred
451
452
7.43M
    return nRet;
453
7.43M
}
454
455
template<typename T>
456
T SvParser<T>::SkipToken( short nCnt )       // "skip" n Tokens backward
457
982k
{
458
982k
    pTokenStackPos = GetStackPtr( nCnt );
459
982k
    short nTmp = nTokenStackPos - nCnt;
460
982k
    if( nTmp < 0 )
461
2
        nTmp = 0;
462
982k
    else if( nTmp > nTokenStackSize )
463
0
        nTmp = nTokenStackSize;
464
982k
    nTokenStackPos = sal_uInt8(nTmp);
465
466
982k
    m_nTokenIndex -= nTmp;
467
468
    // restore values
469
982k
    aToken = pTokenStackPos->sToken;
470
982k
    nTokenValue = pTokenStackPos->nTokenValue;
471
982k
    bTokenHasValue = pTokenStackPos->bTokenHasValue;
472
473
982k
    return pTokenStackPos->nTokenId;
474
982k
}
SvParser<int>::SkipToken(short)
Line
Count
Source
457
642k
{
458
642k
    pTokenStackPos = GetStackPtr( nCnt );
459
642k
    short nTmp = nTokenStackPos - nCnt;
460
642k
    if( nTmp < 0 )
461
2
        nTmp = 0;
462
642k
    else if( nTmp > nTokenStackSize )
463
0
        nTmp = nTokenStackSize;
464
642k
    nTokenStackPos = sal_uInt8(nTmp);
465
466
642k
    m_nTokenIndex -= nTmp;
467
468
    // restore values
469
642k
    aToken = pTokenStackPos->sToken;
470
642k
    nTokenValue = pTokenStackPos->nTokenValue;
471
642k
    bTokenHasValue = pTokenStackPos->bTokenHasValue;
472
473
642k
    return pTokenStackPos->nTokenId;
474
642k
}
SvParser<HtmlTokenId>::SkipToken(short)
Line
Count
Source
457
340k
{
458
340k
    pTokenStackPos = GetStackPtr( nCnt );
459
340k
    short nTmp = nTokenStackPos - nCnt;
460
340k
    if( nTmp < 0 )
461
0
        nTmp = 0;
462
340k
    else if( nTmp > nTokenStackSize )
463
0
        nTmp = nTokenStackSize;
464
340k
    nTokenStackPos = sal_uInt8(nTmp);
465
466
340k
    m_nTokenIndex -= nTmp;
467
468
    // restore values
469
340k
    aToken = pTokenStackPos->sToken;
470
340k
    nTokenValue = pTokenStackPos->nTokenValue;
471
340k
    bTokenHasValue = pTokenStackPos->bTokenHasValue;
472
473
340k
    return pTokenStackPos->nTokenId;
474
340k
}
475
476
template<typename T>
477
typename SvParser<T>::TokenStackType* SvParser<T>::GetStackPtr( short nCnt )
478
1.32M
{
479
1.32M
    sal_uInt8 nCurrentPos = sal_uInt8(pTokenStackPos - pTokenStack.get());
480
1.32M
    if( nCnt > 0 )
481
1.41k
    {
482
1.41k
        if( nCnt >= nTokenStackSize )
483
0
            nCnt = (nTokenStackSize-1);
484
1.41k
        if( nCurrentPos + nCnt < nTokenStackSize )
485
967
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
486
445
        else
487
445
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
488
445
                nCurrentPos + (nCnt - nTokenStackSize));
489
1.41k
    }
490
1.31M
    else if( nCnt < 0 )
491
1.31M
    {
492
1.31M
        if( -nCnt >= nTokenStackSize )
493
0
            nCnt = -nTokenStackSize+1;
494
1.31M
        if( -nCnt <= nCurrentPos )
495
999k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
496
320k
        else
497
320k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
498
320k
                nCurrentPos + (nCnt + nTokenStackSize));
499
1.31M
    }
500
1.32M
    return pTokenStack.get() + nCurrentPos;
501
1.32M
}
SvParser<int>::GetStackPtr(short)
Line
Count
Source
478
980k
{
479
980k
    sal_uInt8 nCurrentPos = sal_uInt8(pTokenStackPos - pTokenStack.get());
480
980k
    if( nCnt > 0 )
481
1.41k
    {
482
1.41k
        if( nCnt >= nTokenStackSize )
483
0
            nCnt = (nTokenStackSize-1);
484
1.41k
        if( nCurrentPos + nCnt < nTokenStackSize )
485
967
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
486
445
        else
487
445
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
488
445
                nCurrentPos + (nCnt - nTokenStackSize));
489
1.41k
    }
490
978k
    else if( nCnt < 0 )
491
978k
    {
492
978k
        if( -nCnt >= nTokenStackSize )
493
0
            nCnt = -nTokenStackSize+1;
494
978k
        if( -nCnt <= nCurrentPos )
495
773k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
496
205k
        else
497
205k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
498
205k
                nCurrentPos + (nCnt + nTokenStackSize));
499
978k
    }
500
980k
    return pTokenStack.get() + nCurrentPos;
501
980k
}
SvParser<HtmlTokenId>::GetStackPtr(short)
Line
Count
Source
478
340k
{
479
340k
    sal_uInt8 nCurrentPos = sal_uInt8(pTokenStackPos - pTokenStack.get());
480
340k
    if( nCnt > 0 )
481
0
    {
482
0
        if( nCnt >= nTokenStackSize )
483
0
            nCnt = (nTokenStackSize-1);
484
0
        if( nCurrentPos + nCnt < nTokenStackSize )
485
0
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
486
0
        else
487
0
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
488
0
                nCurrentPos + (nCnt - nTokenStackSize));
489
0
    }
490
340k
    else if( nCnt < 0 )
491
340k
    {
492
340k
        if( -nCnt >= nTokenStackSize )
493
0
            nCnt = -nTokenStackSize+1;
494
340k
        if( -nCnt <= nCurrentPos )
495
225k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(nCurrentPos + nCnt);
496
114k
        else
497
114k
            nCurrentPos = sal::static_int_cast< sal_uInt8 >(
498
114k
                nCurrentPos + (nCnt + nTokenStackSize));
499
340k
    }
500
340k
    return pTokenStack.get() + nCurrentPos;
501
340k
}
502
503
// to read asynchronous from SvStream
504
505
template<typename T>
506
T SvParser<T>::GetSaveToken() const
507
0
{
508
0
    return pImplData ? pImplData->nSaveToken : static_cast<T>(0);
509
0
}
Unexecuted instantiation: SvParser<int>::GetSaveToken() const
Unexecuted instantiation: SvParser<HtmlTokenId>::GetSaveToken() const
510
511
template<typename T>
512
void SvParser<T>::SaveState( T nToken )
513
22.0M
{
514
    // save actual status
515
22.0M
    if( !pImplData )
516
0
    {
517
0
        pImplData.reset(new SvParser_Impl<T>);
518
0
        pImplData->nSaveToken = static_cast<T>(0);
519
0
    }
520
521
22.0M
    pImplData->nFilePos = rInput.Tell();
522
22.0M
    pImplData->nToken = nToken;
523
524
22.0M
    pImplData->aToken = aToken;
525
22.0M
    pImplData->nlLineNr = nlLineNr;
526
22.0M
    pImplData->nlLinePos = nlLinePos;
527
22.0M
    pImplData->nTokenValue= nTokenValue;
528
22.0M
    pImplData->bTokenHasValue = bTokenHasValue;
529
22.0M
    pImplData->nNextCh = nNextCh;
530
22.0M
}
SvParser<int>::SaveState(int)
Line
Count
Source
513
7.27M
{
514
    // save actual status
515
7.27M
    if( !pImplData )
516
0
    {
517
0
        pImplData.reset(new SvParser_Impl<T>);
518
0
        pImplData->nSaveToken = static_cast<T>(0);
519
0
    }
520
521
7.27M
    pImplData->nFilePos = rInput.Tell();
522
7.27M
    pImplData->nToken = nToken;
523
524
7.27M
    pImplData->aToken = aToken;
525
7.27M
    pImplData->nlLineNr = nlLineNr;
526
7.27M
    pImplData->nlLinePos = nlLinePos;
527
7.27M
    pImplData->nTokenValue= nTokenValue;
528
7.27M
    pImplData->bTokenHasValue = bTokenHasValue;
529
7.27M
    pImplData->nNextCh = nNextCh;
530
7.27M
}
SvParser<HtmlTokenId>::SaveState(HtmlTokenId)
Line
Count
Source
513
14.7M
{
514
    // save actual status
515
14.7M
    if( !pImplData )
516
0
    {
517
0
        pImplData.reset(new SvParser_Impl<T>);
518
0
        pImplData->nSaveToken = static_cast<T>(0);
519
0
    }
520
521
14.7M
    pImplData->nFilePos = rInput.Tell();
522
14.7M
    pImplData->nToken = nToken;
523
524
14.7M
    pImplData->aToken = aToken;
525
14.7M
    pImplData->nlLineNr = nlLineNr;
526
14.7M
    pImplData->nlLinePos = nlLinePos;
527
14.7M
    pImplData->nTokenValue= nTokenValue;
528
14.7M
    pImplData->bTokenHasValue = bTokenHasValue;
529
14.7M
    pImplData->nNextCh = nNextCh;
530
14.7M
}
531
532
template<typename T>
533
void SvParser<T>::RestoreState()
534
0
{
535
    // restore old status
536
0
    if( !pImplData )
537
0
        return;
538
539
0
    if( ERRCODE_IO_PENDING == rInput.GetError() )
540
0
        rInput.ResetError();
541
0
    aToken = pImplData->aToken;
542
0
    nlLineNr = pImplData->nlLineNr;
543
0
    nlLinePos = pImplData->nlLinePos;
544
0
    nTokenValue= pImplData->nTokenValue;
545
0
    bTokenHasValue=pImplData->bTokenHasValue;
546
0
    nNextCh = pImplData->nNextCh;
547
548
0
    pImplData->nSaveToken = pImplData->nToken;
549
550
0
    rInput.Seek( pImplData->nFilePos );
551
0
}
Unexecuted instantiation: SvParser<int>::RestoreState()
Unexecuted instantiation: SvParser<HtmlTokenId>::RestoreState()
552
553
template<typename T>
554
void SvParser<T>::Continue( T )
555
0
{
556
0
}
Unexecuted instantiation: SvParser<int>::Continue(int)
Unexecuted instantiation: SvParser<HtmlTokenId>::Continue(HtmlTokenId)
557
558
559
// expanded out version of
560
//   IMPL_LINK_NOARG( SvParser, NewDataRead, LinkParamNone*, void )
561
// since it can't cope with template methods
562
template<typename T>
563
0
void SvParser<T>::LinkStubNewDataRead(void * instance, LinkParamNone* data) {
564
0
    return static_cast<SvParser<T> *>(instance)->NewDataRead(data);
565
0
}
Unexecuted instantiation: SvParser<int>::LinkStubNewDataRead(void*, LinkParamNone*)
Unexecuted instantiation: SvParser<HtmlTokenId>::LinkStubNewDataRead(void*, LinkParamNone*)
566
template<typename T>
567
void SvParser<T>::NewDataRead(SAL_UNUSED_PARAMETER LinkParamNone*)
568
0
{
569
0
    switch( eState )
570
0
    {
571
0
    case SvParserState::Pending:
572
0
        eState = SvParserState::Working;
573
0
        RestoreState();
574
575
0
        Continue( pImplData->nToken );
576
577
0
        if( ERRCODE_IO_PENDING == rInput.GetError() )
578
0
            rInput.ResetError();
579
580
0
        if( SvParserState::Pending != eState )
581
0
            ReleaseRef();                    // ready otherwise!
582
0
        break;
583
584
0
    case SvParserState::NotStarted:
585
0
    case SvParserState::Working:
586
0
        break;
587
588
0
    default:
589
0
        ReleaseRef();                    // ready otherwise!
590
0
        break;
591
0
    }
592
0
}
Unexecuted instantiation: SvParser<int>::NewDataRead(LinkParamNone*)
Unexecuted instantiation: SvParser<HtmlTokenId>::NewDataRead(LinkParamNone*)
593
594
template class SVT_DLLPUBLIC SvParser<int>;
595
template class SVT_DLLPUBLIC SvParser<HtmlTokenId>;
596
597
/*========================================================================
598
 *
599
 * SvKeyValueIterator.
600
 *
601
 *======================================================================*/
602
603
typedef std::vector<SvKeyValue> SvKeyValueList_Impl;
604
605
struct SvKeyValueIterator::Impl
606
{
607
    SvKeyValueList_Impl maList;
608
    sal_uInt16 mnPos;
609
610
59.8k
    Impl() : mnPos(0) {}
611
};
612
613
59.8k
SvKeyValueIterator::SvKeyValueIterator() : mpImpl(new Impl) {}
614
615
59.8k
SvKeyValueIterator::~SvKeyValueIterator() = default;
616
617
bool SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
618
81.0k
{
619
81.0k
    mpImpl->mnPos = mpImpl->maList.size();
620
81.0k
    return GetNext (rKeyVal);
621
81.0k
}
622
623
bool SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
624
141k
{
625
141k
    if (mpImpl->mnPos > 0)
626
60.2k
    {
627
60.2k
        rKeyVal = mpImpl->maList[--mpImpl->mnPos];
628
60.2k
        return true;
629
60.2k
    }
630
81.0k
    else
631
81.0k
    {
632
        // Nothing to do.
633
81.0k
        return false;
634
81.0k
    }
635
141k
}
636
637
void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
638
34.8k
{
639
34.8k
    mpImpl->maList.push_back(rKeyVal);
640
34.8k
}
641
642
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */