/// <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> /// Gets an estimate of a <see cref="FileDataPart"/>. /// </summary> /// <param name="guid">The <see cref="Guid"/> that should be used in the size estimate.</param> /// <param name="start">The start position that should be used in the size estimate.</param> /// <param name="size">The size of the data that should be used in the size estimate.</param> /// <returns>The estimated size, in bytes, of a serialized <see cref="FileDataPart"/>.</returns> internal static int EstimatePartSize(Guid guid, long start, int size) { var part = new FileDataPart(guid, start, new byte[size]); var bytes = ObjectPacker.Pack(part); return(bytes.Length + PacketHeader.HeaderSize(bytes.Length)); }
/// <summary> /// Receives the <see cref="FileDataPart"/> into the specified file. /// </summary> /// <param name="file">A <see cref="FileInfo"/> object containing the fully qualified name of the file to receiving the data to.</param> /// <param name="part">The <see cref="FileDataPart"/> to be received.</param> internal void ReceivePart(FileInfo file, FileDataPart part) { if (ReceiveCompleted) { throw new InvalidOperationException("Receive operation for this file has already been completed."); } lock (SyncRoot) { using (FileStream fs = new FileStream(file.FullName, FileMode.OpenOrCreate, FileAccess.Write)) { fs.Seek(part.Start, SeekOrigin.Begin); fs.Write(part.Data, 0, part.Data.Length); } LastReceivedSize = part.Data.Length; ReceivedBytes += part.Data.Length; } }
/// <summary> /// Handles the data of an incoming file, but putting it into the temporary file already /// obtained through the other HandleIncomingFile method. /// </summary> /// <param name="part">The <see cref="FileDataPart"/> containing the data that was received.</param> /// <returns>The <see cref="FileData"/> object for the part that was received (for event raising).</returns> /// <remarks>This only runs when legacy support is off.</remarks> private FileData HandleIncomingFile(FileDataPart part) { if (!IncomingFiles.ContainsKey(part.FileGuid)) throw new InvalidOperationException("File part received before file details."); var file = IncomingFiles[part.FileGuid]; file.ReceivePart(file.Info, part); return file; }
/// <summary> /// Receives the <see cref="FileDataPart"/> into the specified file. /// </summary> /// <param name="file">A <see cref="FileInfo"/> object containing the fully qualified name of the file to receiving the data to.</param> /// <param name="part">The <see cref="FileDataPart"/> to be received.</param> internal void ReceivePart(FileInfo file, FileDataPart part) { if (ReceiveCompleted) throw new InvalidOperationException("Receive operation for this file has already been completed."); lock (SyncRoot) { using (FileStream fs = new FileStream(file.FullName, FileMode.OpenOrCreate, FileAccess.Write)) { fs.Seek(part.Start, SeekOrigin.Begin); fs.Write(part.Data, 0, part.Data.Length); } LastReceivedSize = part.Data.Length; ReceivedBytes += part.Data.Length; } }
/// <summary> /// Receives the <see cref="FileDataPart"/> into the specified file. /// </summary> /// <param name="fileName">The fully qualified name of the file, or the relative file name. Do not end the path with the directory separator character.</param> /// <param name="part">The <see cref="FileDataPart"/> to be received.</param> internal void ReceivePart(string fileName, FileDataPart part) { ReceivePart(new FileInfo(fileName), part); }
/// <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> /// Gets an estimate of a <see cref="FileDataPart"/>. /// </summary> /// <param name="guid">The <see cref="Guid"/> that should be used in the size estimate.</param> /// <param name="start">The start position that should be used in the size estimate.</param> /// <param name="size">The size of the data that should be used in the size estimate.</param> /// <returns>The estimated size, in bytes, of a serialized <see cref="FileDataPart"/>.</returns> internal static int EstimatePartSize(Guid guid, long start, int size) { var part = new FileDataPart(guid, start, new byte[size]); var bytes = ObjectPacker.Pack(part); return bytes.Length + PacketHeader.HeaderSize(bytes.Length); }