/// <include file='IAdbSocket.xml' path='/IAdbSocket/ReadSyncResponse/*'/> public virtual SyncCommand ReadSyncResponse() { byte[] data = new byte[4]; this.Read(data); return(SyncCommandConverter.GetCommand(data)); }
/// <include file='IAdbSocket.xml' path='/IAdbSocket/SendSyncRequest_SyncCommand_int/*'/> public virtual void SendSyncRequest(SyncCommand command, int length) { // The message structure is: // First four bytes: command // Next four bytes: length of the path // Final bytes: path byte[] commandBytes = SyncCommandConverter.GetBytes(command); byte[] lengthBytes = BitConverter.GetBytes(length); if (!BitConverter.IsLittleEndian) { // Convert from big endian to little endian Array.Reverse(lengthBytes); } this.Write(commandBytes); this.Write(lengthBytes); }
/// <inheritdoc/> public void Push(Stream stream, string remotePath, int permissions, DateTimeOffset timestamp, IProgress <int> progress, CancellationToken cancellationToken) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (remotePath == null) { throw new ArgumentNullException(nameof(remotePath)); } if (remotePath.Length > MaxPathLength) { throw new ArgumentOutOfRangeException(nameof(remotePath), $"The remote path {remotePath} exceeds the maximum path size {MaxPathLength}"); } this.Socket.SendSyncRequest(SyncCommand.SEND, remotePath, permissions); // create the buffer used to read. // we read max SYNC_DATA_MAX. byte[] buffer = new byte[this.MaxBufferSize]; // We need 4 bytes of the buffer to send the 'DATA' command, // and an additional X bytes to inform how much data we are // sending. byte[] dataBytes = SyncCommandConverter.GetBytes(SyncCommand.DATA); byte[] lengthBytes = BitConverter.GetBytes(this.MaxBufferSize); int headerSize = dataBytes.Length + lengthBytes.Length; int reservedHeaderSize = headerSize; int maxDataSize = this.MaxBufferSize - reservedHeaderSize; lengthBytes = BitConverter.GetBytes(maxDataSize); // Try to get the total amount of bytes to transfer. This is not always possible, for example, // for forward-only streams. long totalBytesToProcess = stream.CanSeek ? stream.Length : 0; long totalBytesRead = 0; // look while there is something to read while (true) { // check if we're canceled cancellationToken.ThrowIfCancellationRequested(); // read up to SYNC_DATA_MAX int read = stream.Read(buffer, headerSize, maxDataSize); totalBytesRead += read; if (read == 0) { // we reached the end of the file break; } else if (read != maxDataSize) { // At the end of the line, so we need to recalculate the length of the header lengthBytes = BitConverter.GetBytes(read); headerSize = dataBytes.Length + lengthBytes.Length; } int startPosition = reservedHeaderSize - headerSize; Buffer.BlockCopy(dataBytes, 0, buffer, startPosition, dataBytes.Length); Buffer.BlockCopy(lengthBytes, 0, buffer, startPosition + dataBytes.Length, lengthBytes.Length); // now send the data to the device this.Socket.Send(buffer, startPosition, read + dataBytes.Length + lengthBytes.Length); // Let the caller know about our progress, if requested if (progress != null && totalBytesToProcess != 0) { progress.Report((int)(100.0 * totalBytesRead / totalBytesToProcess)); } } // create the DONE message int time = (int)timestamp.ToUnixTimeSeconds(); this.Socket.SendSyncRequest(SyncCommand.DONE, time); // read the result, in a byte array containing 2 ints // (id, size) var result = this.Socket.ReadSyncResponse(); if (result == SyncCommand.FAIL) { var message = this.Socket.ReadSyncString(); throw new AdbException(message); } else if (result != SyncCommand.OKAY) { throw new AdbException($"The server sent an invali repsonse {result}"); } }