3 // Copyright 2005 John Reilly
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 // Linking this library statically or dynamically with other modules is
20 // making a combined work based on this library. Thus, the terms and
21 // conditions of the GNU General Public License cover the whole
24 // As a special exception, the copyright holders of this library give you
25 // permission to link this library with independent modules to produce an
26 // executable, regardless of the license terms of these independent
27 // modules, and to copy and distribute the resulting executable under
28 // terms of your choice, provided that you also meet, for each linked
29 // independent module, the terms and conditions of the license of that
30 // module. An independent module is a module which is not derived from
31 // or based on this library. If you modify this library, you may extend
32 // this exception to your version of the library, but you are not
33 // obligated to do so. If you do not wish to do so, delete this
34 // exception statement from your version.
38 using ICSharpCode.SharpZipLib.Silverlight.Core;
40 namespace ICSharpCode.SharpZipLib.Silverlight.Core
43 /// Provides simple <see cref="Stream"/>" utilities.
45 public static class StreamUtils
48 /// Read from a <see cref="Stream"/> ensuring all the required data is read.
50 /// <param name="stream">The stream to read.</param>
51 /// <param name="buffer">The buffer to fill.</param>
52 static public void ReadFully(Stream stream, byte[] buffer)
54 ReadFully(stream, buffer, 0, buffer.Length);
58 /// Read from a <see cref="Stream"/>" ensuring all the required data is read.
60 /// <param name="stream">The stream to read data from.</param>
61 /// <param name="buffer">The buffer to store data in.</param>
62 /// <param name="offset">The offset at which to begin storing data.</param>
63 /// <param name="count">The number of bytes of data to store.</param>
64 static public void ReadFully(Stream stream, byte[] buffer, int offset, int count)
66 if ( stream == null ) {
67 throw new ArgumentNullException("stream");
70 if ( buffer == null ) {
71 throw new ArgumentNullException("buffer");
74 // Offset can equal length when buffer and count are 0.
75 if ( (offset < 0) || (offset > buffer.Length) ) {
76 throw new ArgumentOutOfRangeException("offset");
79 if ( (count < 0) || (offset + count > buffer.Length) ) {
80 throw new ArgumentOutOfRangeException("count");
84 int readCount = stream.Read(buffer, offset, count);
85 if ( readCount <= 0 ) {
86 throw new EndOfStreamException();
94 /// Copy the contents of one <see cref="Stream"/> to another.
96 /// <param name="source">The stream to source data from.</param>
97 /// <param name="destination">The stream to write data to.</param>
98 /// <param name="buffer">The buffer to use during copying.</param>
99 /// <param name="progressHandler">The <see cref="ProgressHandler">progress handler delegate</see> to use.</param>
100 /// <param name="updateInterval">The minimum <see cref="TimeSpan"/> between progress updates.</param>
101 /// <param name="sender">The source for this event.</param>
102 /// <param name="name">The name to use with the event.</param>
103 static public void Copy(Stream source, Stream destination,
104 byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, object sender, string name)
106 if (source == null) {
107 throw new ArgumentNullException("source");
110 if (destination == null) {
111 throw new ArgumentNullException("destination");
114 if (buffer == null) {
115 throw new ArgumentNullException("buffer");
118 // Ensure a reasonable size of buffer is used without being prohibitive.
119 if (buffer.Length < 128) {
120 throw new ArgumentException("Buffer is too small", "buffer");
123 if (progressHandler == null) {
124 throw new ArgumentNullException("progressHandler");
129 DateTime marker = DateTime.Now;
133 if (source.CanSeek) {
134 target = source.Length - source.Position;
137 // Always fire 0% progress..
138 var args = new ProgressEventArgs(name, processed, target);
139 progressHandler(sender, args);
141 bool completeFired = false;
144 int bytesRead = source.Read(buffer, 0, buffer.Length);
146 processed += bytesRead;
147 destination.Write(buffer, 0, bytesRead);
154 if (DateTime.Now - marker > updateInterval) {
155 completeFired = (processed == target);
156 marker = DateTime.Now;
157 args = new ProgressEventArgs(name, processed, target);
158 progressHandler(sender, args);
160 copying = args.ContinueRunning;
164 if (!completeFired) {
165 args = new ProgressEventArgs(name, processed, target);
166 progressHandler(sender, args);
171 /// Copy the contents of one <see cref="Stream"/> to another.
173 /// <param name="source">The stream to source data from.</param>
174 /// <param name="destination">The stream to write data to.</param>
175 /// <param name="buffer">The buffer to use during copying.</param>
176 static public void Copy(Stream source, Stream destination, byte[] buffer)
178 if ( source == null ) {
179 throw new ArgumentNullException("source");
182 if ( destination == null ) {
183 throw new ArgumentNullException("destination");
186 if ( buffer == null ) {
187 throw new ArgumentNullException("buffer");
190 // Ensure a reasonable size of buffer is used without being prohibitive.
191 if ( buffer.Length < 128 ) {
192 throw new ArgumentException("Buffer is too small", "buffer");
198 int bytesRead = source.Read(buffer, 0, buffer.Length);
199 if ( bytesRead > 0 ) {
200 destination.Write(buffer, 0, bytesRead);