protected override async Task <int> InvokeAsync(InvocationContext context, IStandardStreamWriter console, RolandMidiClient client) { var address = ModuleAddress.FromDisplayValue(HexInt32.Parse(context.ParseResult.ValueForOption <string>("address")).Value); var size = HexInt32.Parse(context.ParseResult.ValueForOption <string>("size")).Value; var timeout = context.ParseResult.ValueForOption <int>("timeout"); // Wait up to 10 seconds to receive all the requested data... int sizeReceived = 0; var delayTask = Task.Delay(TimeSpan.FromSeconds(timeout)); var completeTaskCts = new TaskCompletionSource <int>(); client.DataSetMessageReceived += DumpMessage; client.SendDataRequestMessage(address.DisplayValue, size); await Task.WhenAny(delayTask, completeTaskCts.Task); return(0); void DumpMessage(object sender, DataSetMessage message) { ModuleAddress address = ModuleAddress.FromDisplayValue(message.Address); console.WriteLine($"Address: {address} Length: {message.Length:x4}"); int index = 0; while (index < message.Length) { var builder = new StringBuilder(); var textBuilder = new StringBuilder(); builder.Append(address); builder.Append(" "); for (int i = 0; i < 16 && index < message.Length; i++) { byte b = message.Data[index]; textBuilder.Append(b >= 32 && b < 127 ? (char)b : ' '); builder.Append(b.ToString("x2")); builder.Append(" "); index++; } string text = builder.ToString().PadRight(9 + 16 * 3) + textBuilder; console.WriteLine(text); address = address.PlusLogicalOffset(16); } console.WriteLine(); if (Interlocked.Add(ref sizeReceived, message.Length) >= size) { completeTaskCts.SetResult(0); } } }
protected override async Task <int> InvokeAsync(InvocationContext context, IStandardStreamWriter console, RolandMidiClient client) { using var writer = File.CreateText(context.ParseResult.ValueForOption <string>("file")); int chunkSize = context.ParseResult.ValueForOption <int>("chunkSize"); TimeSpan timeout = TimeSpan.FromMilliseconds(context.ParseResult.ValueForOption <int>("timeout")); var address = ModuleAddress.FromDisplayValue(0); int messagesReceived = 0; client.DataSetMessageReceived += DumpMessage; // TODO: Make this tighter. But we're unlikely to really get here. while (address.DisplayValue < 0x74_00_00_00) { int receivedAtStartOfChunk = messagesReceived; client.SendDataRequestMessage(address.DisplayValue, chunkSize); int receivedAtStartOfDelay; do { receivedAtStartOfDelay = messagesReceived; await Task.Delay(timeout); } while (messagesReceived > receivedAtStartOfDelay); int receivedForChunk = messagesReceived - receivedAtStartOfChunk; console.WriteLine($"Received {receivedForChunk} messages in chunk at {address}"); writer.Flush(); address = address.PlusLogicalOffset(chunkSize); } return(0); void DumpMessage(object sender, DataSetMessage message) { ModuleAddress address = ModuleAddress.FromDisplayValue(message.Address); writer.WriteLine($"Address: {address} Length: {message.Length:x4}"); int index = 0; while (index < message.Length) { var builder = new StringBuilder(); var textBuilder = new StringBuilder(); builder.Append(address); builder.Append(" "); for (int i = 0; i < 16 && index < message.Length; i++) { byte b = message.Data[index]; textBuilder.Append(b >= 32 && b < 127 ? (char)b : ' '); builder.Append(b.ToString("x2")); builder.Append(" "); index++; } string text = builder.ToString().PadRight(9 + 16 * 3) + textBuilder; writer.WriteLine(text); address = address.PlusLogicalOffset(16); } writer.WriteLine(); Interlocked.Increment(ref messagesReceived); } }