#region Disclaimer / License // Copyright (C) 2011, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.Text; namespace Duplicati.Library.SharpRSync { public static class Utility { /// /// Size of buffers for copying stream /// public static long DEFAULT_BUFFER_SIZE = 64 * 1024; /// /// Some streams can return a number that is less than the requested number of bytes. /// This is usually due to fragmentation, and is solved by issuing a new read. /// This function wraps that functionality. /// /// The stream to read /// The buffer to read into /// The actual number of bytes read public static int ForceStreamRead(System.IO.Stream stream, byte[] buf) { return ForceStreamRead(stream, buf, 0, buf.Length); } /// /// Some streams can return a number that is less than the requested number of bytes. /// This is usually due to fragmentation, and is solved by issuing a new read. /// This function wraps that functionality. /// /// The stream to read /// The buffer to read into /// The amout of bytes to read /// The actual number of bytes read public static int ForceStreamRead(System.IO.Stream stream, byte[] buf, int count) { return ForceStreamRead(stream, buf, 0, count); } /// /// Some streams can return a number that is less than the requested number of bytes. /// This is usually due to fragmentation, and is solved by issuing a new read. /// This function wraps that functionality. /// /// The stream to read /// The buffer to read into /// The index into which the writing starts /// The amout of bytes to read /// The actual number of bytes read public static int ForceStreamRead(System.IO.Stream stream, byte[] buf, int index, int count) { //Non fragmenting streams skip here if (stream is System.IO.FileStream || stream is System.IO.MemoryStream) return stream.Read(buf, index, count); int a; int read = 0; do { a = stream.Read(buf, index, count); index += a; read += a; count -= a; } while (a != 0 && count > 0); return read; } /// /// Copies a number of bytes from one stream into another. /// /// The stream to read from /// The stream to write to /// The number of bytes to copy public static void StreamCopy(System.IO.Stream input, System.IO.Stream output, long count) { byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; while (count > 0) { int a = input.Read(buf, 0, (int)Math.Min(count, buf.Length)); if (a <= 0) throw new Exception(Strings.Utility.UnexpectedEndOfStreamError); output.Write(buf, 0, a); count -= a; } } } }