// // FileSink.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Text.RegularExpressions; using NosSmooth.PacketSerializer.Abstractions.Attributes; namespace Anonymizer.Sinks; /// /// A sink that supports reading from a file and writing to a file. /// public class FileSink : IDisposable, IPacketSource, IPacketDestination { private readonly Regex _regex; private readonly FileSinkOptions _options; private readonly StreamReader _reader; private readonly StreamWriter _writer; /// /// Initializes a new instance of the class. /// /// The source file path. /// The destination file path. /// The options. public FileSink(string sourceFile, string destinationFile, FileSinkOptions options) { _regex = new Regex(options.LineRegex); _options = options; _reader = new StreamReader(File.OpenRead(sourceFile)); _writer = new StreamWriter(File.OpenWrite(destinationFile)); } /// public long Cursor { get; private set; } /// public async Task TryGetNextPacketAsync(CancellationToken ct = default) { if (_reader.EndOfStream) { return null; } var line = await _reader.ReadLineAsync(ct); if (string.IsNullOrEmpty(line)) { return null; } Cursor++; var match = _regex.Match(line); if (!match.Success) { Console.Error.WriteLine($"Could not find match on line {line}"); return new PacketInfo(PacketSource.Client, string.Empty); } var type = match.Groups[1].Value; var packetStr = match.Groups[2].Value; var source = type == _options.RecvString ? PacketSource.Server : PacketSource.Client; return new PacketInfo(source, packetStr); } /// public async Task WritePacketAsync(PacketInfo packet, CancellationToken ct = default) { var output = _options.OutputFormat .Replace("%TYPE%", packet.Source == PacketSource.Client ? _options.SendString : _options.RecvString) .Replace("%PACKET%", packet.Packet); await _writer.WriteLineAsync(new ReadOnlyMemory(output.ToCharArray()), ct); await _writer.FlushAsync(); } /// public void Dispose() { _writer.Dispose(); _reader.Dispose(); } }