public override DataTransferStatus OnMessage(ICommand command, AtemConnection connection) { if (command is DataTransferUploadContinueCommand continueCommand && continueCommand.TransferId == _id) { var toSend = new DataTransferFileDescriptionCommand() { TransferId = _id, Name = _name, Description = _description, }; connection.QueueCommand(toSend); // also queue data const int maxBodySize = 1350; // TODO - base chunking off of UploedMediaFrameJob int startPos = 0; while (startPos < _dataQueue.Count) { int count = 1; for (; count < _dataQueue.Count - startPos; count++) { int d = _dataQueue.Skip(startPos).Take(count + 1).Sum(v => v.Length); if (d > maxBodySize) { break; } } connection.QueueCommand(new DataTransferDataCommand() { TransferId = _id, Body = _dataQueue.Skip(startPos).Take(count).SelectMany(b => b).ToArray() }); startPos += count; } return(DataTransferStatus.OK); } if (command is DataTransferCompleteCommand completeCommand && completeCommand.TransferId == _id) { _onComplete(true); return(DataTransferStatus.Success); } _onComplete(false); return(DataTransferStatus.Error); }
public virtual IEnumerable <ICommand> HandleCommand(Lazy <ImmutableList <ICommand> > previousCommands, ICommand cmd) { var lockRes = LockCommandHandler(previousCommands, cmd).ToList(); if (lockRes.Any()) { foreach (LockStateChangedCommand lockCmd in lockRes.OfType <LockStateChangedCommand>()) { _locked = lockCmd.Locked; // _output.WriteLine($"Locked {lockCmd.Locked}"); } return(lockRes); } // _output.WriteLine($"Got cmd: {cmd.GetType().FullName}"); var res = new List <ICommand>(); if (cmd is DataTransferUploadRequestCommand startCmd) { Assert.Equal(_bank != 0xffff, _locked); Assert.False(_isComplete); Assert.Equal(_expectedMode, startCmd.Mode); if (_targetBytes > 0) { Assert.Equal((int)_targetBytes, startCmd.Size); } Assert.Equal(_index, startCmd.TransferIndex); Assert.Equal((uint)_bank, startCmd.TransferStoreId); _transferId = startCmd.TransferId; _pendingAck = 0; _targetBytes = (uint)startCmd.Size; res.Add(new DataTransferUploadContinueCommand { TransferId = startCmd.TransferId, ChunkCount = _chunkCount, ChunkSize = _chunkSize }); } else if (cmd is DataTransferFileDescriptionCommand descCmd) { Assert.NotEqual(0u, _transferId); Assert.Null(_description); Assert.False(_isComplete); Assert.Equal(_transferId, descCmd.TransferId); _description = descCmd; if (_usedBytes >= _targetBytes) { _isComplete = true; res.AddRange(Complete()); } else { res.Add(null); } } else if (cmd is DataTransferDataCommand dataCmd) { Assert.NotEqual(0u, _transferId); Assert.False(_isComplete); Assert.Equal(_transferId, dataCmd.TransferId); Assert.True(dataCmd.Body.Length <= _chunkSize); Tuple <int, byte[]> decoded = _decodeRle ? FrameEncodingUtil.DecodeRLESegment(_targetBytes, dataCmd.Body) : Tuple.Create(dataCmd.Body.Length, dataCmd.Body); if (!_knownTargetBytes) { byte[] newBuffer = new byte[Buffer.Length + decoded.Item1]; Array.Copy(Buffer, 0, newBuffer, 0, Buffer.Length); Buffer = newBuffer; } //long copyLength = Math.Min(decoded.Item1, _targetBytes - _usedBytes); Array.Copy(decoded.Item2, 0, Buffer, _usedBytes, decoded.Item1); _usedBytes += (uint)decoded.Item1; _pendingAck++; if (_pendingAck >= _chunkCount) { //res.Add(new DataTransferAckCommand {TransferId = _transferId}); res.Add(new DataTransferUploadContinueCommand { TransferId = _transferId, ChunkCount = _chunkCount, ChunkSize = _chunkSize }); _pendingAck = 0; } // _output.WriteLine($"Now have {_usedBytes} bytes of {_targetBytes}"); if (_usedBytes >= _targetBytes && _description != null) { _isComplete = true; res.AddRange(Complete()); } if (res.Count == 0) { res.Add(null); } } return(res); }