Skip to content

Instantly share code, notes, and snippets.

@stdray
Last active September 18, 2017 16:09
Show Gist options
  • Save stdray/684ee12c20b12ec0bd7dab6c7e064e2d to your computer and use it in GitHub Desktop.
Save stdray/684ee12c20b12ec0bd7dab6c7e064e2d to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Text;
namespace Interfax.SM.Utils.IO
{
/// <inheritdoc />
/// <summary>
/// Представляет коллекцию строк как поток байтов указанной кодировки. По умолчанию UTF8
/// </summary>
public class StringsStream : Stream
{
readonly IReadOnlyList<string> _strings;
readonly Encoding _encoding;
int _streamPosition = 0;
int _currentStringIndex = 0;
byte[] _currentBytes;
int _currentBytesIndex = 0;
public StringsStream(IReadOnlyList<string> strings, Encoding encoding = null)
{
_strings = strings;
_encoding = encoding ?? Encoding.UTF8;
}
public override bool CanRead { get => true; }
public override bool CanSeek { get => false; }
public override bool CanWrite { get => false; }
public override long Length { get => throw new NotSupportedException(); }
public override long Position
{
get => _streamPosition;
set => throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException(nameof(buffer));
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset));
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));
if (buffer.Length - offset < count)
throw new ArgumentException("Failed condition: buffer.Length - offset < count");
Contract.EndContractBlock();
for (; _currentStringIndex < _strings.Count; _currentStringIndex++)
{
if (_currentBytes == null)
_currentBytes = _encoding.GetBytes(_strings[_currentStringIndex]);
var cnt = Math.Min(_currentBytes.Length - _currentBytesIndex, count);
if (cnt < 1)
{
_currentBytes = null;
_currentBytesIndex = 0;
continue;
}
Buffer.BlockCopy(_currentBytes, _currentBytesIndex, buffer, offset, cnt);
_currentBytesIndex += cnt;
_streamPosition += cnt;
return cnt;
}
return 0;
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment