/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: */ |