private int InternalReadChars(char[] buffer, int index, int count) { Debug.Assert(buffer != null); Debug.Assert(index >= 0 && count >= 0); Debug.Assert(_stream != null); int numBytes = 0; int charsRemaining = count; if (_charBytes == null) { _charBytes = new byte[MaxCharBytesSize]; } while (charsRemaining > 0) { int charsRead = 0; // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. numBytes = charsRemaining; if (_2BytesPerChar) { numBytes <<= 1; } if (numBytes > MaxCharBytesSize) { numBytes = MaxCharBytesSize; } int position = 0; byte[] byteBuffer = null; if (_isMemoryStream) { MemoryStream mStream = _stream as MemoryStream; Debug.Assert(mStream != null, "_stream as MemoryStream != null"); position = mStream.InternalGetPosition(); numBytes = mStream.InternalEmulateRead(numBytes); byteBuffer = mStream.InternalGetBuffer(); } else { numBytes = _stream.Read(_charBytes, 0, numBytes); byteBuffer = _charBytes; } if (numBytes == 0) { return(count - charsRemaining); } Debug.Assert(byteBuffer != null, "expected byteBuffer to be non-null"); charsRead = _decoder.GetChars(byteBuffer, position, numBytes, buffer, index, flush: false); charsRemaining -= charsRead; index += charsRead; } // this should never fail Debug.Assert(charsRemaining >= 0, "We read too many characters."); // we may have read fewer than the number of characters requested if end of stream reached // or if the encoding makes the char count too big for the buffer (e.g. fallback sequence) return(count - charsRemaining); }
private int InternalReadChars(Span <char> buffer) { Debug.Assert(!_disposed); int totalCharsRead = 0; while (!buffer.IsEmpty) { int numBytes = buffer.Length; // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. if (_2BytesPerChar) { numBytes <<= 1; } // We do not want to read even a single byte more than necessary. // // Subtract pending bytes that the decoder may be holding onto. This assumes that each // decoded char corresponds to one or more bytes. Note that custom encodings or encodings with // a custom replacement sequence may violate this assumption. if (numBytes > 1) { DecoderNLS?decoder = _decoder as DecoderNLS; // For internal decoders, we can check whether the decoder has any pending state. // For custom decoders, assume that the decoder has pending state. if (decoder == null || decoder.HasState) { numBytes--; // The worst case is charsRemaining = 2 and UTF32Decoder holding onto 3 pending bytes. We need to read just // one byte in this case. if (_2BytesPerChar && numBytes > 2) { numBytes -= 2; } } } ReadOnlySpan <byte> byteBuffer; if (_isMemoryStream) { Debug.Assert(_stream is MemoryStream); MemoryStream mStream = (MemoryStream)_stream; int position = mStream.InternalGetPosition(); numBytes = mStream.InternalEmulateRead(numBytes); byteBuffer = new ReadOnlySpan <byte>(mStream.InternalGetBuffer(), position, numBytes); } else { _charBytes ??= new byte[MaxCharBytesSize]; if (numBytes > MaxCharBytesSize) { numBytes = MaxCharBytesSize; } numBytes = _stream.Read(_charBytes, 0, numBytes); byteBuffer = new ReadOnlySpan <byte>(_charBytes, 0, numBytes); } if (byteBuffer.IsEmpty) { break; } int charsRead = _decoder.GetChars(byteBuffer, buffer, flush: false); buffer = buffer.Slice(charsRead); totalCharsRead += charsRead; } // we may have read fewer than the number of characters requested if end of stream reached // or if the encoding makes the char count too big for the buffer (e.g. fallback sequence) return(totalCharsRead); }
private int InternalReadChars(char[] buffer, int index, int count) { Contract.Requires(buffer != null); Contract.Requires(index >= 0 && count >= 0); Contract.Assert(m_stream != null); int numBytes = 0; int charsRemaining = count; if (m_charBytes == null) { m_charBytes = new byte[MaxCharBytesSize]; } while (charsRemaining > 0) { int charsRead = 0; // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. numBytes = charsRemaining; // special case for DecoderNLS subclasses when there is a hanging byte from the previous loop DecoderNLS decoder = m_decoder as DecoderNLS; if (decoder != null && decoder.HasState && numBytes > 1) { numBytes -= 1; } if (m_2BytesPerChar) { numBytes <<= 1; } if (numBytes > MaxCharBytesSize) { numBytes = MaxCharBytesSize; } int position = 0; byte[] byteBuffer = null; if (m_isMemoryStream) { MemoryStream mStream = m_stream as MemoryStream; Contract.Assert(mStream != null, "m_stream as MemoryStream != null"); position = mStream.InternalGetPosition(); numBytes = mStream.InternalEmulateRead(numBytes); byteBuffer = mStream.InternalGetBuffer(); } else { numBytes = m_stream.Read(m_charBytes, 0, numBytes); byteBuffer = m_charBytes; } if (numBytes == 0) { return(count - charsRemaining); } Contract.Assert(byteBuffer != null, "expected byteBuffer to be non-null"); unsafe { fixed(byte *pBytes = byteBuffer) fixed(char *pChars = buffer) { charsRead = m_decoder.GetChars(pBytes + position, numBytes, pChars + index, charsRemaining, false); } } charsRemaining -= charsRead; index += charsRead; } // this should never fail Contract.Assert(charsRemaining >= 0, "We read too many characters."); // we may have read fewer than the number of characters requested if end of stream reached // or if the encoding makes the char count too big for the buffer (e.g. fallback sequence) return(count - charsRemaining); }
private int InternalReadChars(Span <char> buffer) { Debug.Assert(_stream != null); int numBytes = 0; int index = 0; int charsRemaining = buffer.Length; if (_charBytes == null) { _charBytes = new byte[MaxCharBytesSize]; } while (charsRemaining > 0) { int charsRead = 0; // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. numBytes = charsRemaining; if (_2BytesPerChar) { numBytes <<= 1; } if (numBytes > MaxCharBytesSize) { numBytes = MaxCharBytesSize; } int position = 0; byte[] byteBuffer = null; if (_isMemoryStream) { MemoryStream mStream = _stream as MemoryStream; Debug.Assert(mStream != null, "_stream as MemoryStream != null"); position = mStream.InternalGetPosition(); numBytes = mStream.InternalEmulateRead(numBytes); byteBuffer = mStream.InternalGetBuffer(); } else { numBytes = _stream.Read(_charBytes, 0, numBytes); byteBuffer = _charBytes; } if (numBytes == 0) { return(buffer.Length - charsRemaining); } Debug.Assert(byteBuffer != null, "expected byteBuffer to be non-null"); checked { if (position < 0 || numBytes < 0 || position > byteBuffer.Length - numBytes) { throw new ArgumentOutOfRangeException(nameof(numBytes)); } if (index < 0 || charsRemaining < 0 || index > buffer.Length - charsRemaining) { throw new ArgumentOutOfRangeException(nameof(charsRemaining)); } unsafe { fixed(byte *pBytes = byteBuffer) fixed(char *pChars = &MemoryMarshal.GetReference(buffer)) { charsRead = _decoder.GetChars(pBytes + position, numBytes, pChars + index, charsRemaining, flush: false); } } } charsRemaining -= charsRead; index += charsRead; } // this should never fail Debug.Assert(charsRemaining >= 0, "We read too many characters."); // we may have read fewer than the number of characters requested if end of stream reached // or if the encoding makes the char count too big for the buffer (e.g. fallback sequence) return(buffer.Length - charsRemaining); }
private unsafe int InternalReadChars(char[] buffer, int index, int count) { int i = count; if (this.m_charBytes == null) { this.m_charBytes = new byte[128]; } while (i > 0) { int num = i; DecoderNLS decoderNLS = this.m_decoder as DecoderNLS; if (decoderNLS != null && decoderNLS.HasState && num > 1) { num--; } if (this.m_2BytesPerChar) { num <<= 1; } if (num > 128) { num = 128; } int num2 = 0; byte[] array; if (this.m_isMemoryStream) { MemoryStream memoryStream = this.m_stream as MemoryStream; num2 = memoryStream.InternalGetPosition(); num = memoryStream.InternalEmulateRead(num); array = memoryStream.InternalGetBuffer(); } else { num = this.m_stream.Read(this.m_charBytes, 0, num); array = this.m_charBytes; } if (num == 0) { return(count - i); } int chars; checked { if (num2 < 0 || num < 0 || num2 + num > array.Length) { throw new ArgumentOutOfRangeException("byteCount"); } if (index < 0 || i < 0 || index + i > buffer.Length) { throw new ArgumentOutOfRangeException("charsRemaining"); } fixed(byte *ptr = array) { fixed(char *ptr2 = buffer) { chars = this.m_decoder.GetChars(ptr + num2, num, ptr2 + index, i, false); } } } i -= chars; index += chars; } return(count - i); }
private int InternalReadChars(Span <char> buffer) { Debug.Assert(!_disposed); int numBytes = 0; int index = 0; int charsRemaining = buffer.Length; if (_charBytes == null) { _charBytes = new byte[MaxCharBytesSize]; } while (charsRemaining > 0) { int charsRead = 0; // We really want to know what the minimum number of bytes per char // is for our encoding. Otherwise for UnicodeEncoding we'd have to // do ~1+log(n) reads to read n characters. numBytes = charsRemaining; if (_2BytesPerChar) { numBytes <<= 1; } // We do not want to read even a single byte more than necessary. // // Subtract pending bytes that the decoder may be holding onto. This assumes that each // decoded char corresponds to one or more bytes. Note that custom encodings or encodings with // a custom replacement sequence may violate this assumption. if (numBytes > 1) { DecoderNLS?decoder = _decoder as DecoderNLS; // For internal decoders, we can check whether the decoder has any pending state. // For custom decoders, assume that the decoder has pending state. if (decoder == null || decoder.HasState) { numBytes -= 1; // The worst case is charsRemaining = 2 and UTF32Decoder holding onto 3 pending bytes. We need to read just // one byte in this case. if (_2BytesPerChar && numBytes > 2) { numBytes -= 2; } } } if (numBytes > MaxCharBytesSize) { numBytes = MaxCharBytesSize; } int position = 0; byte[]? byteBuffer = null; if (_isMemoryStream) { Debug.Assert(_stream is MemoryStream); MemoryStream mStream = (MemoryStream)_stream; position = mStream.InternalGetPosition(); numBytes = mStream.InternalEmulateRead(numBytes); byteBuffer = mStream.InternalGetBuffer(); } else { numBytes = _stream.Read(_charBytes, 0, numBytes); byteBuffer = _charBytes; } if (numBytes == 0) { return(buffer.Length - charsRemaining); } Debug.Assert(byteBuffer != null, "expected byteBuffer to be non-null"); checked { if (position < 0 || numBytes < 0 || position > byteBuffer.Length - numBytes) { throw new ArgumentOutOfRangeException(nameof(numBytes)); } if (index < 0 || charsRemaining < 0 || index > buffer.Length - charsRemaining) { throw new ArgumentOutOfRangeException(nameof(charsRemaining)); } unsafe { fixed(byte *pBytes = byteBuffer) fixed(char *pChars = &MemoryMarshal.GetReference(buffer)) { charsRead = _decoder.GetChars(pBytes + position, numBytes, pChars + index, charsRemaining, flush: false); } } } charsRemaining -= charsRead; index += charsRead; } // this should never fail Debug.Assert(charsRemaining >= 0, "We read too many characters."); // we may have read fewer than the number of characters requested if end of stream reached // or if the encoding makes the char count too big for the buffer (e.g. fallback sequence) return(buffer.Length - charsRemaining); }