root/trunk/Updater/ICSharpCode.SharpZipLib/Core/StreamUtils.cs @ 597

Wersja 597, 8.8 KB (wprowadzona przez marek, 17 years temu)

re #165

RevLine 
[597]1// StreamUtils.cs
2//
3// Copyright 2005 John Reilly
4//
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.
9//
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.
14//
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.
18//
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
22// combination.
23//
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.
35
36using System;
37using System.IO;
38
39namespace ICSharpCode.SharpZipLib.Core
40{
41        /// <summary>
42        /// Provides simple <see cref="Stream"/>" utilities.
43        /// </summary>
44        public sealed class StreamUtils
45        {
46                /// <summary>
47                /// Read from a <see cref="Stream"/> ensuring all the required data is read.
48                /// </summary>
49                /// <param name="stream">The stream to read.</param>
50                /// <param name="buffer">The buffer to fill.</param>
51                /// <seealso cref="ReadFully(Stream,byte[],int,int)"/>
52                static public void ReadFully(Stream stream, byte[] buffer)
53                {
54                        ReadFully(stream, buffer, 0, buffer.Length);
55                }
56
57                /// <summary>
58                /// Read from a <see cref="Stream"/>" ensuring all the required data is read.
59                /// </summary>
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                /// <exception cref="ArgumentNullException">Required parameter is null</exception>
65                /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> and or <paramref name="count"/> are invalid.</exception>
66                /// <exception cref="EndOfStreamException">End of stream is encountered before all the data has been read.</exception>
67                static public void ReadFully(Stream stream, byte[] buffer, int offset, int count)
68                {
69                        if ( stream == null ) {
70                                throw new ArgumentNullException("stream");
71                        }
72
73                        if ( buffer == null ) {
74                                throw new ArgumentNullException("buffer");
75                        }
76
77                        // Offset can equal length when buffer and count are 0.
78                        if ( (offset < 0) || (offset > buffer.Length) ) {
79                                throw new ArgumentOutOfRangeException("offset");
80                        }
81
82                        if ( (count < 0) || (offset + count > buffer.Length) ) {
83                                throw new ArgumentOutOfRangeException("count");
84                        }
85
86                        while ( count > 0 ) {
87                                int readCount = stream.Read(buffer, offset, count);
88                                if ( readCount <= 0 ) {
89                                        throw new EndOfStreamException();
90                                }
91                                offset += readCount;
92                                count -= readCount;
93                        }
94                }
95
96                /// <summary>
97                /// Copy the contents of one <see cref="Stream"/> to another.
98                /// </summary>
99                /// <param name="source">The stream to source data from.</param>
100                /// <param name="destination">The stream to write data to.</param>
101                /// <param name="buffer">The buffer to use during copying.</param>
102                static public void Copy(Stream source, Stream destination, byte[] buffer)
103                {
104                        if (source == null) {
105                                throw new ArgumentNullException("source");
106                        }
107
108                        if (destination == null) {
109                                throw new ArgumentNullException("destination");
110                        }
111
112                        if (buffer == null) {
113                                throw new ArgumentNullException("buffer");
114                        }
115
116                        // Ensure a reasonable size of buffer is used without being prohibitive.
117                        if (buffer.Length < 128) {
118                                throw new ArgumentException("Buffer is too small", "buffer");
119                        }
120
121                        bool copying = true;
122
123                        while (copying) {
124                                int bytesRead = source.Read(buffer, 0, buffer.Length);
125                                if (bytesRead > 0) {
126                                        destination.Write(buffer, 0, bytesRead);
127                                }
128                                else {
129                                        destination.Flush();
130                                        copying = false;
131                                }
132                        }
133                }
134
135                /// <summary>
136                /// Copy the contents of one <see cref="Stream"/> to another.
137                /// </summary>
138                /// <param name="source">The stream to source data from.</param>
139                /// <param name="destination">The stream to write data to.</param>
140                /// <param name="buffer">The buffer to use during copying.</param>
141                /// <param name="progressHandler">The <see cref="ProgressHandler">progress handler delegate</see> to use.</param>
142                /// <param name="updateInterval">The minimum <see cref="TimeSpan"/> between progress updates.</param>
143                /// <param name="sender">The source for this event.</param>
144                /// <param name="name">The name to use with the event.</param>
145                /// <remarks>This form is specialised for use within #Zip to support events during archive operations.</remarks>
146                static public void Copy(Stream source, Stream destination,
147                        byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, object sender, string name)
148                {
149                        Copy(source, destination, buffer, progressHandler, updateInterval, sender, name, -1);
150                }
151
152                /// <summary>
153                /// Copy the contents of one <see cref="Stream"/> to another.
154                /// </summary>
155                /// <param name="source">The stream to source data from.</param>
156                /// <param name="destination">The stream to write data to.</param>
157                /// <param name="buffer">The buffer to use during copying.</param>
158                /// <param name="progressHandler">The <see cref="ProgressHandler">progress handler delegate</see> to use.</param>
159                /// <param name="updateInterval">The minimum <see cref="TimeSpan"/> between progress updates.</param>
160                /// <param name="sender">The source for this event.</param>
161                /// <param name="name">The name to use with the event.</param>
162                /// <param name="fixedTarget">A predetermined fixed target value to use with progress updates.
163                /// If the value is negative the target is calculated by looking at the stream.</param>
164                /// <remarks>This form is specialised for use within #Zip to support events during archive operations.</remarks>
165                static public void Copy(Stream source, Stream destination,
166                        byte[] buffer,
167                        ProgressHandler progressHandler, TimeSpan updateInterval,
168                        object sender, string name, long fixedTarget)
169                {
170                        if (source == null) {
171                                throw new ArgumentNullException("source");
172                        }
173
174                        if (destination == null) {
175                                throw new ArgumentNullException("destination");
176                        }
177
178                        if (buffer == null) {
179                                throw new ArgumentNullException("buffer");
180                        }
181
182                        // Ensure a reasonable size of buffer is used without being prohibitive.
183                        if (buffer.Length < 128) {
184                                throw new ArgumentException("Buffer is too small", "buffer");
185                        }
186
187                        if (progressHandler == null) {
188                                throw new ArgumentNullException("progressHandler");
189                        }
190
191                        bool copying = true;
192
193                        DateTime marker = DateTime.Now;
194                        long processed = 0;
195                        long target = 0;
196
197                        if (fixedTarget >= 0) {
198                                target = fixedTarget;
199                        }
200                        else if (source.CanSeek) {
201                                target = source.Length - source.Position;
202                        }
203
204                        // Always fire 0% progress..
205                        ProgressEventArgs args = new ProgressEventArgs(name, processed, target);
206                        progressHandler(sender, args);
207
208                        bool progressFired = true;
209
210                        while (copying) {
211                                int bytesRead = source.Read(buffer, 0, buffer.Length);
212                                if (bytesRead > 0) {
213                                        processed += bytesRead;
214                                        progressFired = false;
215                                        destination.Write(buffer, 0, bytesRead);
216                                }
217                                else {
218                                        destination.Flush();
219                                        copying = false;
220                                }
221
222                                if (DateTime.Now - marker > updateInterval) {
223                                        progressFired = true;
224                                        marker = DateTime.Now;
225                                        args = new ProgressEventArgs(name, processed, target);
226                                        progressHandler(sender, args);
227
228                                        copying = args.ContinueRunning;
229                                }
230                        }
231
232                        if (!progressFired) {
233                                args = new ProgressEventArgs(name, processed, target);
234                                progressHandler(sender, args);
235                        }
236                }
237
238                /// <summary>
239                /// Initialise an instance of <see cref="StreamUtils"></see>
240                /// </summary>
241                private StreamUtils()
242                {
243                        // Do nothing.
244                }
245        }
246}
Notatka: Zobacz TracBrowser aby uzyskać więcej informacji.