public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1) { int sizeT = TextEncoding.GetByteLengthForEncoding(encoding); bool isFixedLength = fixedLength > -1; var remaining = _buffer.Length - _position; int size; if (isFixedLength) { size = fixedLength * sizeT; if (size > remaining) { throw new OutOfMemoryException(); } } else { size = remaining - (remaining & (sizeT - 1)); } var buffer = _buffer.AsSpan(Position, size); int index = buffer.IndexOfTerminator(sizeT); var span = buffer[..(index < 0 ? size : index)];
public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1) { int sizeT = TextEncoding.GetByteLengthForEncoding(encoding); bool isFixedLength = fixedLength > -1; var remaining = Remaining; int size; if (isFixedLength) { size = fixedLength * sizeT; if (size > Remaining) { throw new OutOfMemoryException(); } } else { size = remaining - (remaining & (sizeT - 1)); } int index = _buffer.Slice(Position, size).IndexOfTerminator(sizeT); var span = _buffer.Slice(Position, index < 0 ? size : index); Position += isFixedLength || index < 0 ? size : index + sizeT; return(TextEncoding.GetString(span, encoding, safeString)); }
public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1) { int sizeT = TextEncoding.GetByteLengthForEncoding(encoding); bool isFixedLength = fixedLength > -1; var remaining = Remaining; int size; if (isFixedLength) { size = fixedLength * sizeT; if (size > Remaining) { throw new OutOfMemoryException(); } } else { size = remaining - (remaining & (sizeT - 1)); } ReadOnlySpan <byte> span; int index; if (Position < _first.Length) { var firstLength = Math.Min(_first.Length - Position, size); // Find terminator index = _first.Slice(Position, firstLength).IndexOfTerminator(sizeT); if (index < 0) { remaining = size - firstLength; // We don't have a terminator, but a fixed size to the end of the first span, so stop there if (remaining <= 0) { index = firstLength; } else { index = _second.SliceToLength(remaining).IndexOfTerminator(sizeT); int secondLength = index < 0 ? remaining : index; int length = firstLength + secondLength; // Assume no strings should be too long for the stack Span <byte> bytes = stackalloc byte[length]; _first.Slice(Position).CopyTo(bytes); _second.SliceToLength(secondLength).CopyTo(bytes.Slice(firstLength)); Position += length + (index >= 0 ? sizeT : 0); return(TextEncoding.GetString(bytes, encoding, safeString)); } } span = _first.Slice(Position, index); } else { size = Math.Min(remaining, size); span = _second.Slice(Position - _first.Length, size); index = span.IndexOfTerminator(sizeT); if (index >= 0) { span = span.SliceToLength(index); } else { index = size; } } Position += isFixedLength ? size : index + sizeT; return(TextEncoding.GetString(span, encoding, safeString)); }