3
3
4
4
using System . Text ;
5
5
using System . Diagnostics ;
6
- using System . Globalization ;
6
+ using System . Diagnostics . CodeAnalysis ;
7
7
8
8
namespace System . Xml
9
9
{
10
- //
11
- // CharEntityEncoderFallback
12
- //
13
10
internal sealed class CharEntityEncoderFallback : EncoderFallback
14
11
{
15
12
private CharEntityEncoderFallbackBuffer ? _fallbackBuffer ;
16
-
17
13
private int [ ] ? _textContentMarks ;
18
14
private int _endMarkPos ;
19
15
private int _curMarkPos ;
20
- private int _startOffset ;
21
16
22
- internal CharEntityEncoderFallback ( )
23
- {
24
- }
17
+ public override int MaxCharCount => 12 ;
18
+ internal int StartOffset { get ; set ; }
25
19
26
20
public override EncoderFallbackBuffer CreateFallbackBuffer ( )
27
21
{
28
- if ( _fallbackBuffer == null )
29
- {
30
- _fallbackBuffer = new CharEntityEncoderFallbackBuffer ( this ) ;
31
- }
32
- return _fallbackBuffer ;
33
- }
34
-
35
- public override int MaxCharCount
36
- {
37
- get
38
- {
39
- return 12 ;
40
- }
41
- }
42
-
43
- internal int StartOffset
44
- {
45
- get
46
- {
47
- return _startOffset ;
48
- }
49
- set
50
- {
51
- _startOffset = value ;
52
- }
22
+ return _fallbackBuffer ??= new CharEntityEncoderFallbackBuffer ( this ) ;
53
23
}
54
24
25
+ [ MemberNotNull ( nameof ( _textContentMarks ) ) ]
55
26
internal void Reset ( int [ ] textContentMarks , int endMarkPos )
56
27
{
57
28
_textContentMarks = textContentMarks ;
58
29
_endMarkPos = endMarkPos ;
59
30
_curMarkPos = 0 ;
60
31
}
61
32
62
- internal bool CanReplaceAt ( int index )
33
+ private bool CanReplaceAt ( int index )
63
34
{
64
35
Debug . Assert ( _textContentMarks != null ) ;
65
36
66
37
int mPos = _curMarkPos ;
67
- int charPos = _startOffset + index ;
38
+ int charPos = StartOffset + index ;
68
39
while ( mPos < _endMarkPos && charPos >= _textContentMarks [ mPos + 1 ] )
69
40
{
70
41
mPos ++ ;
@@ -73,144 +44,121 @@ internal bool CanReplaceAt(int index)
73
44
74
45
return ( mPos & 1 ) != 0 ;
75
46
}
76
- }
77
-
78
- //
79
- // CharEntityFallbackBuffer
80
- //
81
- internal sealed class CharEntityEncoderFallbackBuffer : EncoderFallbackBuffer
82
- {
83
- private readonly CharEntityEncoderFallback _parent ;
84
47
85
- private string _charEntity = string . Empty ;
86
- private int _charEntityIndex = - 1 ;
87
48
88
- internal CharEntityEncoderFallbackBuffer ( CharEntityEncoderFallback parent )
49
+ private sealed class CharEntityEncoderFallbackBuffer : EncoderFallbackBuffer
89
50
{
90
- _parent = parent ;
91
- }
51
+ private readonly CharEntityEncoderFallback _parent ;
92
52
93
- public override bool Fallback ( char charUnknown , int index )
94
- {
95
- // If we are already in fallback, throw, it's probably at the suspect character in charEntity
96
- if ( _charEntityIndex >= 0 )
97
- {
98
- ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) . Fallback ( charUnknown , index ) ;
99
- }
53
+ private string _charEntity = string . Empty ;
54
+ private int _charEntityIndex = - 1 ;
100
55
101
- // find out if we can replace the character with entity
102
- if ( _parent . CanReplaceAt ( index ) )
56
+ internal CharEntityEncoderFallbackBuffer ( CharEntityEncoderFallback parent )
103
57
{
104
- // Create the replacement character entity
105
- _charEntity = string . Create ( null , stackalloc char [ 64 ] , $ "&#x{ ( int ) charUnknown : X} ;") ;
106
- _charEntityIndex = 0 ;
107
- return true ;
58
+ _parent = parent ;
108
59
}
109
- else
60
+
61
+ public override int Remaining => _charEntityIndex == - 1 ? 0 : _charEntity . Length - _charEntityIndex ;
62
+
63
+ public override bool Fallback ( char charUnknown , int index )
110
64
{
65
+ // If we are already in fallback, throw, it's probably at the suspect character in charEntity
66
+ if ( _charEntityIndex >= 0 )
67
+ {
68
+ ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) . Fallback ( charUnknown , index ) ;
69
+ }
70
+
71
+ // find out if we can replace the character with entity
72
+ if ( _parent . CanReplaceAt ( index ) )
73
+ {
74
+ // Create the replacement character entity
75
+ _charEntity = string . Create ( null , stackalloc char [ 64 ] , $ "&#x{ ( int ) charUnknown : X} ;") ;
76
+ _charEntityIndex = 0 ;
77
+ return true ;
78
+ }
79
+
111
80
EncoderFallbackBuffer errorFallbackBuffer = ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) ;
112
81
errorFallbackBuffer . Fallback ( charUnknown , index ) ;
113
82
return false ;
114
83
}
115
- }
116
84
117
- public override bool Fallback ( char charUnknownHigh , char charUnknownLow , int index )
118
- {
119
- // check input surrogate pair
120
- if ( ! char . IsSurrogatePair ( charUnknownHigh , charUnknownLow ) )
85
+ public override bool Fallback ( char charUnknownHigh , char charUnknownLow , int index )
121
86
{
122
- throw XmlConvert . CreateInvalidSurrogatePairException ( charUnknownHigh , charUnknownLow ) ;
123
- }
87
+ // check input surrogate pair
88
+ if ( ! char . IsSurrogatePair ( charUnknownHigh , charUnknownLow ) )
89
+ {
90
+ throw XmlConvert . CreateInvalidSurrogatePairException ( charUnknownHigh , charUnknownLow ) ;
91
+ }
124
92
125
- // If we are already in fallback, throw, it's probably at the suspect character in charEntity
126
- if ( _charEntityIndex >= 0 )
127
- {
128
- ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) . Fallback ( charUnknownHigh , charUnknownLow , index ) ;
129
- }
93
+ // If we are already in fallback, throw, it's probably at the suspect character in charEntity
94
+ if ( _charEntityIndex >= 0 )
95
+ {
96
+ ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) . Fallback ( charUnknownHigh , charUnknownLow , index ) ;
97
+ }
98
+
99
+ if ( _parent . CanReplaceAt ( index ) )
100
+ {
101
+ // Create the replacement character entity
102
+ _charEntity = string . Create ( null , stackalloc char [ 64 ] , $ "&#x{ SurrogateCharToUtf32 ( charUnknownHigh , charUnknownLow ) : X} ;") ;
103
+ _charEntityIndex = 0 ;
104
+ return true ;
105
+ }
130
106
131
- if ( _parent . CanReplaceAt ( index ) )
132
- {
133
- // Create the replacement character entity
134
- _charEntity = string . Create ( null , stackalloc char [ 64 ] , $ "&#x{ SurrogateCharToUtf32 ( charUnknownHigh , charUnknownLow ) : X} ;") ;
135
- _charEntityIndex = 0 ;
136
- return true ;
137
- }
138
- else
139
- {
140
107
EncoderFallbackBuffer errorFallbackBuffer = ( new EncoderExceptionFallback ( ) ) . CreateFallbackBuffer ( ) ;
141
108
errorFallbackBuffer . Fallback ( charUnknownHigh , charUnknownLow , index ) ;
142
109
return false ;
143
110
}
144
- }
145
111
146
- public override char GetNextChar ( )
147
- {
148
- // The protocol using GetNextChar() and MovePrevious() called by Encoder is not well documented.
149
- // Here we have to signal to Encoder that the previous read was last character. Only AFTER we can
150
- // mark ourself as done (-1). Otherwise MovePrevious() can still be called, but -1 is already incorrectly set
151
- // and return false from MovePrevious(). Then Encoder swallowing the rest of the bytes.
152
- if ( _charEntityIndex == _charEntity . Length )
153
- {
154
- _charEntityIndex = - 1 ;
155
- }
156
- if ( _charEntityIndex == - 1 )
157
- {
158
- return ( char ) 0 ;
159
- }
160
- else
112
+ public override char GetNextChar ( )
161
113
{
114
+ // The protocol using GetNextChar() and MovePrevious() called by Encoder is not well documented.
115
+ // Here we have to signal to Encoder that the previous read was last character. Only AFTER we can
116
+ // mark our self as done (-1). Otherwise MovePrevious() can still be called, but -1 is already incorrectly set
117
+ // and return false from MovePrevious(). Then Encoder swallowing the rest of the bytes.
118
+ if ( _charEntityIndex == _charEntity . Length )
119
+ {
120
+ _charEntityIndex = - 1 ;
121
+ }
122
+
123
+ if ( _charEntityIndex == - 1 )
124
+ {
125
+ return ( char ) 0 ;
126
+ }
127
+
162
128
Debug . Assert ( _charEntityIndex < _charEntity . Length ) ;
163
- char ch = _charEntity [ _charEntityIndex ++ ] ;
164
- return ch ;
165
- }
166
- }
167
129
168
- public override bool MovePrevious ( )
169
- {
170
- if ( _charEntityIndex == - 1 )
171
- {
172
- return false ;
130
+ return _charEntity [ _charEntityIndex ++ ] ;
173
131
}
174
- else
132
+
133
+ public override bool MovePrevious ( )
175
134
{
135
+ if ( _charEntityIndex == - 1 )
136
+ {
137
+ return false ;
138
+ }
139
+
176
140
// Could be == length if just read the last character
177
141
Debug . Assert ( _charEntityIndex <= _charEntity . Length ) ;
142
+
178
143
if ( _charEntityIndex > 0 )
179
144
{
180
145
_charEntityIndex -- ;
146
+
181
147
return true ;
182
148
}
183
- else
184
- {
185
- return false ;
186
- }
187
- }
188
- }
189
149
150
+ return false ;
151
+ }
190
152
191
- public override int Remaining
192
- {
193
- get
153
+ public override void Reset ( )
194
154
{
195
- if ( _charEntityIndex == - 1 )
196
- {
197
- return 0 ;
198
- }
199
- else
200
- {
201
- return _charEntity . Length - _charEntityIndex ;
202
- }
155
+ _charEntityIndex = - 1 ;
203
156
}
204
- }
205
157
206
- public override void Reset ( )
207
- {
208
- _charEntityIndex = - 1 ;
209
- }
210
-
211
- private int SurrogateCharToUtf32 ( char highSurrogate , char lowSurrogate )
212
- {
213
- return XmlCharType . CombineSurrogateChar ( lowSurrogate , highSurrogate ) ;
158
+ private static int SurrogateCharToUtf32 ( char highSurrogate , char lowSurrogate )
159
+ {
160
+ return XmlCharType . CombineSurrogateChar ( lowSurrogate , highSurrogate ) ;
161
+ }
214
162
}
215
163
}
216
164
}
0 commit comments