/// <summary> /// Gets the next <see cref="FileDataPart"/> that will be sent over the network. /// </summary> /// <param name="bufferSize">The size of the buffer and amount of data to return.</param> /// <returns>The bufferSize is adjusted by an estimate of how large the metadata would be, so that the size of the serialized <see cref="FileDataPart"/> should be the same as the bufferSize.</returns> internal FileDataPart GetNextPart(int bufferSize) { if (SendCompleted) { return(null); } if (Info == null) { throw new NullReferenceException("File information not found."); } if (!Info.Exists) { throw new FileNotFoundException(Info.FullName); } bufferSize -= MetaSize; byte[] buffer = new byte[bufferSize]; lock (SyncRoot) { using (FileStream fs = new FileStream(Info.FullName, FileMode.Open, FileAccess.Read)) { fs.Seek(SentBytes, SeekOrigin.Begin); int readSize = fs.Read(buffer, 0, bufferSize); byte[] sizedBuffer = ArrayMethods.Shrink(ref buffer, readSize); var part = new FileDataPart(Guid, SentBytes, sizedBuffer); SentBytes += readSize; return(part); } } }
/// <summary> /// Processes the incoming <see cref="byte"/> array to see if a <see cref="PacketHeader"/> is within it. /// </summary> /// <param name="data">The data to check for a <see cref="PacketHeader"/> - may be incomplete and the rest stored in the buffer.</param> /// <param name="buffer">A <see cref="ByteBufferCollection"/> that potentially has stored part of a <see cref="PacketHeader"/>.</param> /// <returns>true, if the method encountered no error; otherwise false.</returns> /// <remarks>Just because the method returns true, does not mean it found the <see cref="PacketHeader"/> - just that there were no errors.</remarks> public bool ProcessHeader(ref byte[] data, ref ByteBufferCollection buffer) { if (!HasDelimiter) { Delimiter = ArrayMethods.Shrink(ref data, 1)[0]; if (data == null || data.Length == 0) { return(true); } } int delimiterIndex = Array.IndexOf(data, Delimiter); if (delimiterIndex == -1) { buffer.Add(data); return(true); } byte[] headerData = buffer.Combine(ArrayMethods.Shrink(ref data, delimiterIndex + 1)); Array.Resize(ref headerData, headerData.Length - 1); buffer.Clear(); string size = Encoding.ASCII.GetString(headerData); if (!int.TryParse(size, out _size)) { Reset(); return(false); } if (Size == 0) { Reset(); } return(true); }