TeamCity.CSharpInteractive/MessagesReader.cs (59 lines of code) (raw):
// ReSharper disable ClassNeverInstantiated.Global
namespace TeamCity.CSharpInteractive;
using System.Buffers;
using JetBrains.TeamCity.ServiceMessages;
using JetBrains.TeamCity.ServiceMessages.Read;
internal class MessagesReader : IMessagesReader
{
private readonly ILog<MessagesReader> _log;
private readonly MemoryPool<byte> _memoryPool;
private readonly IMessageIndicesReader _indicesReader;
private readonly IFileSystem _fileSystem;
private readonly IEncoding _encoding;
private readonly IServiceMessageParser _serviceMessageParser;
public MessagesReader(
ILog<MessagesReader> log,
MemoryPool<byte> memoryPool,
IMessageIndicesReader indicesReader,
IFileSystem fileSystem,
IEncoding encoding,
IServiceMessageParser serviceMessageParser)
{
_log = log;
_memoryPool = memoryPool;
_indicesReader = indicesReader;
_fileSystem = fileSystem;
_encoding = encoding;
_serviceMessageParser = serviceMessageParser;
}
public IEnumerable<IServiceMessage> Read(string indicesFile, string messagesFile)
{
using var reader = _fileSystem.OpenReader(messagesFile);
var position = 0UL;
foreach (var index in _indicesReader.Read(indicesFile))
{
var size = (int)(index - position);
if (size <= 0)
{
_log.Warning($"Corrupted file \"{indicesFile}\", invalid index {index}.");
break;
}
using var owner = _memoryPool.Rent(size);
var buffer = owner.Memory[..size];
if (reader.Read(buffer, (long)position) != size)
{
_log.Warning($"Corrupted file \"{messagesFile}\", invalid size.");
break;
}
position = index;
var line = _encoding.GetString(buffer);
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
foreach (var message in _serviceMessageParser.ParseServiceMessages(line).Where(message => message != default))
{
yield return message;
}
}
}
}