@@ -194,12 +194,39 @@ public override unsafe void Convert(char* chars, int charCount,
194
194
bytesUsed = _encoding . GetBytes ( chars , charCount , bytes , byteCount , this ) ;
195
195
charsUsed = _charsUsed ;
196
196
197
- // Per MSDN, "The completed output parameter indicates whether all the data in the input
198
- // buffer was converted and stored in the output buffer." That means we've successfully
199
- // consumed all the input _and_ there's no pending state or fallback data remaining to be output.
197
+ // If the 'completed' out parameter is set to false, it means one of two things:
198
+ // a) this call to Convert did not consume the entire source buffer; or
199
+ // b) this call to Convert did consume the entire source buffer, but there's
200
+ // still pending data that needs to be written to the destination buffer.
201
+ //
202
+ // In either case, the caller should slice the input buffer, provide a fresh
203
+ // destination buffer, and call Convert again in a loop until 'completed' is true.
204
+ //
205
+ // The caller *must* specify flush = true on the final iteration(s) of the loop
206
+ // and iterate until 'completed' is set to true. Otherwise data loss may occur.
207
+ //
208
+ // Technically, the expected logic is detailed below.
209
+ //
210
+ // If 'flush' = false, the 'completed' parameter MUST be set to false if not all
211
+ // elements of the source buffer have been consumed. The 'completed' parameter MUST
212
+ // be set to true once the entire source buffer has been consumed and there is no
213
+ // pending data for the destination buffer. (In other words, the 'completed' parameter
214
+ // MUST be set to true if passing a zero-length source buffer and an infinite-length
215
+ // destination buffer will make no forward progress.) The 'completed' parameter value
216
+ // is undefined for the case where all source data has been consumed but there remains
217
+ // pending data for the destination buffer.
218
+ //
219
+ // If 'flush' = true, the 'completed' parameter is set to true IF AND ONLY IF:
220
+ // a) all elements of the source buffer have been transcoded into the destination buffer; AND
221
+ // b) there remains no internal partial read state within this instance; AND
222
+ // c) there remains no pending data for the destination buffer.
223
+ //
224
+ // In other words, if 'flush' = true, then when 'completed' is set to true it should mean
225
+ // that all data has been converted and that this instance is indistinguishable from a
226
+ // freshly-reset instance.
200
227
201
228
completed = ( charsUsed == charCount )
202
- && ! this . HasState
229
+ && ( ! flush || ! this . HasState )
203
230
&& ( _fallbackBuffer is null || _fallbackBuffer . Remaining == 0 ) ;
204
231
205
232
// Our data thingys are now full, we can return
0 commit comments