DeflateStream.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. // DeflateStream.cs
  2. // ------------------------------------------------------------------
  3. //
  4. // Copyright (c) 2009-2010 Dino Chiesa.
  5. // All rights reserved.
  6. //
  7. // This code module is part of DotNetZip, a zipfile class library.
  8. //
  9. // ------------------------------------------------------------------
  10. //
  11. // This code is licensed under the Microsoft Public License.
  12. // See the file License.txt for the license details.
  13. // More info on: http://dotnetzip.codeplex.com
  14. //
  15. // ------------------------------------------------------------------
  16. //
  17. // last saved (in emacs):
  18. // Time-stamp: <2011-July-31 14:48:11>
  19. //
  20. // ------------------------------------------------------------------
  21. //
  22. // This module defines the DeflateStream class, which can be used as a replacement for
  23. // the System.IO.Compression.DeflateStream class in the .NET BCL.
  24. //
  25. // ------------------------------------------------------------------
  26. using System;
  27. namespace Ionic.Zlib
  28. {
  29. /// <summary>
  30. /// A class for compressing and decompressing streams using the Deflate algorithm.
  31. /// </summary>
  32. ///
  33. /// <remarks>
  34. ///
  35. /// <para>
  36. /// The DeflateStream is a <see
  37. /// href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see
  38. /// cref="System.IO.Stream"/>. It adds DEFLATE compression or decompression to any
  39. /// stream.
  40. /// </para>
  41. ///
  42. /// <para>
  43. /// Using this stream, applications can compress or decompress data via stream
  44. /// <c>Read</c> and <c>Write</c> operations. Either compresssion or decompression
  45. /// can occur through either reading or writing. The compression format used is
  46. /// DEFLATE, which is documented in <see
  47. /// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE
  48. /// Compressed Data Format Specification version 1.3.".
  49. /// </para>
  50. ///
  51. /// <para>
  52. /// This class is similar to <see cref="ZlibStream"/>, except that
  53. /// <c>ZlibStream</c> adds the <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
  54. /// 1950 - ZLIB</see> framing bytes to a compressed stream when compressing, or
  55. /// expects the RFC1950 framing bytes when decompressing. The <c>DeflateStream</c>
  56. /// does not.
  57. /// </para>
  58. ///
  59. /// </remarks>
  60. ///
  61. /// <seealso cref="ZlibStream" />
  62. /// <seealso cref="GZipStream" />
  63. public class DeflateStream : System.IO.Stream
  64. {
  65. internal ZlibBaseStream _baseStream;
  66. internal System.IO.Stream _innerStream;
  67. bool _disposed;
  68. /// <summary>
  69. /// Create a DeflateStream using the specified CompressionMode.
  70. /// </summary>
  71. ///
  72. /// <remarks>
  73. /// When mode is <c>CompressionMode.Compress</c>, the DeflateStream will use
  74. /// the default compression level. The "captive" stream will be closed when
  75. /// the DeflateStream is closed.
  76. /// </remarks>
  77. ///
  78. /// <example>
  79. /// This example uses a DeflateStream to compress data from a file, and writes
  80. /// the compressed data to another file.
  81. /// <code>
  82. /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
  83. /// {
  84. /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
  85. /// {
  86. /// using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress))
  87. /// {
  88. /// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
  89. /// int n;
  90. /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
  91. /// {
  92. /// compressor.Write(buffer, 0, n);
  93. /// }
  94. /// }
  95. /// }
  96. /// }
  97. /// </code>
  98. ///
  99. /// <code lang="VB">
  100. /// Using input As Stream = File.OpenRead(fileToCompress)
  101. /// Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
  102. /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress)
  103. /// Dim buffer As Byte() = New Byte(4096) {}
  104. /// Dim n As Integer = -1
  105. /// Do While (n &lt;&gt; 0)
  106. /// If (n &gt; 0) Then
  107. /// compressor.Write(buffer, 0, n)
  108. /// End If
  109. /// n = input.Read(buffer, 0, buffer.Length)
  110. /// Loop
  111. /// End Using
  112. /// End Using
  113. /// End Using
  114. /// </code>
  115. /// </example>
  116. /// <param name="stream">The stream which will be read or written.</param>
  117. /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
  118. public DeflateStream(System.IO.Stream stream, CompressionMode mode)
  119. : this(stream, mode, CompressionLevel.Default, false)
  120. {
  121. }
  122. /// <summary>
  123. /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel.
  124. /// </summary>
  125. ///
  126. /// <remarks>
  127. ///
  128. /// <para>
  129. /// When mode is <c>CompressionMode.Decompress</c>, the level parameter is
  130. /// ignored. The "captive" stream will be closed when the DeflateStream is
  131. /// closed.
  132. /// </para>
  133. ///
  134. /// </remarks>
  135. ///
  136. /// <example>
  137. ///
  138. /// This example uses a DeflateStream to compress data from a file, and writes
  139. /// the compressed data to another file.
  140. ///
  141. /// <code>
  142. /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
  143. /// {
  144. /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
  145. /// {
  146. /// using (Stream compressor = new DeflateStream(raw,
  147. /// CompressionMode.Compress,
  148. /// CompressionLevel.BestCompression))
  149. /// {
  150. /// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
  151. /// int n= -1;
  152. /// while (n != 0)
  153. /// {
  154. /// if (n &gt; 0)
  155. /// compressor.Write(buffer, 0, n);
  156. /// n= input.Read(buffer, 0, buffer.Length);
  157. /// }
  158. /// }
  159. /// }
  160. /// }
  161. /// </code>
  162. ///
  163. /// <code lang="VB">
  164. /// Using input As Stream = File.OpenRead(fileToCompress)
  165. /// Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
  166. /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
  167. /// Dim buffer As Byte() = New Byte(4096) {}
  168. /// Dim n As Integer = -1
  169. /// Do While (n &lt;&gt; 0)
  170. /// If (n &gt; 0) Then
  171. /// compressor.Write(buffer, 0, n)
  172. /// End If
  173. /// n = input.Read(buffer, 0, buffer.Length)
  174. /// Loop
  175. /// End Using
  176. /// End Using
  177. /// End Using
  178. /// </code>
  179. /// </example>
  180. /// <param name="stream">The stream to be read or written while deflating or inflating.</param>
  181. /// <param name="mode">Indicates whether the <c>DeflateStream</c> will compress or decompress.</param>
  182. /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
  183. public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)
  184. : this(stream, mode, level, false)
  185. {
  186. }
  187. /// <summary>
  188. /// Create a <c>DeflateStream</c> using the specified
  189. /// <c>CompressionMode</c>, and explicitly specify whether the
  190. /// stream should be left open after Deflation or Inflation.
  191. /// </summary>
  192. ///
  193. /// <remarks>
  194. ///
  195. /// <para>
  196. /// This constructor allows the application to request that the captive stream
  197. /// remain open after the deflation or inflation occurs. By default, after
  198. /// <c>Close()</c> is called on the stream, the captive stream is also
  199. /// closed. In some cases this is not desired, for example if the stream is a
  200. /// memory stream that will be re-read after compression. Specify true for
  201. /// the <paramref name="leaveOpen"/> parameter to leave the stream open.
  202. /// </para>
  203. ///
  204. /// <para>
  205. /// The <c>DeflateStream</c> will use the default compression level.
  206. /// </para>
  207. ///
  208. /// <para>
  209. /// See the other overloads of this constructor for example code.
  210. /// </para>
  211. /// </remarks>
  212. ///
  213. /// <param name="stream">
  214. /// The stream which will be read or written. This is called the
  215. /// "captive" stream in other places in this documentation.
  216. /// </param>
  217. ///
  218. /// <param name="mode">
  219. /// Indicates whether the <c>DeflateStream</c> will compress or decompress.
  220. /// </param>
  221. ///
  222. /// <param name="leaveOpen">true if the application would like the stream to
  223. /// remain open after inflation/deflation.</param>
  224. public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)
  225. : this(stream, mode, CompressionLevel.Default, leaveOpen)
  226. {
  227. }
  228. /// <summary>
  229. /// Create a <c>DeflateStream</c> using the specified <c>CompressionMode</c>
  230. /// and the specified <c>CompressionLevel</c>, and explicitly specify whether
  231. /// the stream should be left open after Deflation or Inflation.
  232. /// </summary>
  233. ///
  234. /// <remarks>
  235. ///
  236. /// <para>
  237. /// When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.
  238. /// </para>
  239. ///
  240. /// <para>
  241. /// This constructor allows the application to request that the captive stream
  242. /// remain open after the deflation or inflation occurs. By default, after
  243. /// <c>Close()</c> is called on the stream, the captive stream is also
  244. /// closed. In some cases this is not desired, for example if the stream is a
  245. /// <see cref="System.IO.MemoryStream"/> that will be re-read after
  246. /// compression. Specify true for the <paramref name="leaveOpen"/> parameter
  247. /// to leave the stream open.
  248. /// </para>
  249. ///
  250. /// </remarks>
  251. ///
  252. /// <example>
  253. ///
  254. /// This example shows how to use a <c>DeflateStream</c> to compress data from
  255. /// a file, and store the compressed data into another file.
  256. ///
  257. /// <code>
  258. /// using (var output = System.IO.File.Create(fileToCompress + ".deflated"))
  259. /// {
  260. /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
  261. /// {
  262. /// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
  263. /// {
  264. /// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
  265. /// int n= -1;
  266. /// while (n != 0)
  267. /// {
  268. /// if (n &gt; 0)
  269. /// compressor.Write(buffer, 0, n);
  270. /// n= input.Read(buffer, 0, buffer.Length);
  271. /// }
  272. /// }
  273. /// }
  274. /// // can write additional data to the output stream here
  275. /// }
  276. /// </code>
  277. ///
  278. /// <code lang="VB">
  279. /// Using output As FileStream = File.Create(fileToCompress &amp; ".deflated")
  280. /// Using input As Stream = File.OpenRead(fileToCompress)
  281. /// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
  282. /// Dim buffer As Byte() = New Byte(4096) {}
  283. /// Dim n As Integer = -1
  284. /// Do While (n &lt;&gt; 0)
  285. /// If (n &gt; 0) Then
  286. /// compressor.Write(buffer, 0, n)
  287. /// End If
  288. /// n = input.Read(buffer, 0, buffer.Length)
  289. /// Loop
  290. /// End Using
  291. /// End Using
  292. /// ' can write additional data to the output stream here.
  293. /// End Using
  294. /// </code>
  295. /// </example>
  296. /// <param name="stream">The stream which will be read or written.</param>
  297. /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
  298. /// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param>
  299. /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
  300. public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
  301. {
  302. _innerStream = stream;
  303. _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen);
  304. }
  305. #region Zlib properties
  306. /// <summary>
  307. /// This property sets the flush behavior on the stream.
  308. /// </summary>
  309. /// <remarks> See the ZLIB documentation for the meaning of the flush behavior.
  310. /// </remarks>
  311. virtual public FlushType FlushMode
  312. {
  313. get { return (this._baseStream._flushMode); }
  314. set
  315. {
  316. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  317. this._baseStream._flushMode = value;
  318. }
  319. }
  320. /// <summary>
  321. /// The size of the working buffer for the compression codec.
  322. /// </summary>
  323. ///
  324. /// <remarks>
  325. /// <para>
  326. /// The working buffer is used for all stream operations. The default size is
  327. /// 1024 bytes. The minimum size is 128 bytes. You may get better performance
  328. /// with a larger buffer. Then again, you might not. You would have to test
  329. /// it.
  330. /// </para>
  331. ///
  332. /// <para>
  333. /// Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
  334. /// stream. If you try to set it afterwards, it will throw.
  335. /// </para>
  336. /// </remarks>
  337. public int BufferSize
  338. {
  339. get
  340. {
  341. return this._baseStream._bufferSize;
  342. }
  343. set
  344. {
  345. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  346. if (this._baseStream._workingBuffer != null)
  347. throw new ZlibException("The working buffer is already set.");
  348. if (value < ZlibConstants.WorkingBufferSizeMin)
  349. throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
  350. this._baseStream._bufferSize = value;
  351. }
  352. }
  353. /// <summary>
  354. /// The ZLIB strategy to be used during compression.
  355. /// </summary>
  356. ///
  357. /// <remarks>
  358. /// By tweaking this parameter, you may be able to optimize the compression for
  359. /// data with particular characteristics.
  360. /// </remarks>
  361. public CompressionStrategy Strategy
  362. {
  363. get
  364. {
  365. return this._baseStream.Strategy;
  366. }
  367. set
  368. {
  369. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  370. this._baseStream.Strategy = value;
  371. }
  372. }
  373. /// <summary> Returns the total number of bytes input so far.</summary>
  374. virtual public long TotalIn
  375. {
  376. get
  377. {
  378. return this._baseStream._z.TotalBytesIn;
  379. }
  380. }
  381. /// <summary> Returns the total number of bytes output so far.</summary>
  382. virtual public long TotalOut
  383. {
  384. get
  385. {
  386. return this._baseStream._z.TotalBytesOut;
  387. }
  388. }
  389. #endregion
  390. #region System.IO.Stream methods
  391. /// <summary>
  392. /// Dispose the stream.
  393. /// </summary>
  394. /// <remarks>
  395. /// <para>
  396. /// This may or may not result in a <c>Close()</c> call on the captive
  397. /// stream. See the constructors that have a <c>leaveOpen</c> parameter
  398. /// for more information.
  399. /// </para>
  400. /// <para>
  401. /// Application code won't call this code directly. This method may be
  402. /// invoked in two distinct scenarios. If disposing == true, the method
  403. /// has been called directly or indirectly by a user's code, for example
  404. /// via the public Dispose() method. In this case, both managed and
  405. /// unmanaged resources can be referenced and disposed. If disposing ==
  406. /// false, the method has been called by the runtime from inside the
  407. /// object finalizer and this method should not reference other objects;
  408. /// in that case only unmanaged resources must be referenced or
  409. /// disposed.
  410. /// </para>
  411. /// </remarks>
  412. /// <param name="disposing">
  413. /// true if the Dispose method was invoked by user code.
  414. /// </param>
  415. protected override void Dispose(bool disposing)
  416. {
  417. try
  418. {
  419. if (!_disposed)
  420. {
  421. if (disposing && (this._baseStream != null))
  422. this._baseStream.Dispose();
  423. _disposed = true;
  424. }
  425. }
  426. finally
  427. {
  428. base.Dispose(disposing);
  429. }
  430. }
  431. /// <summary>
  432. /// Indicates whether the stream can be read.
  433. /// </summary>
  434. /// <remarks>
  435. /// The return value depends on whether the captive stream supports reading.
  436. /// </remarks>
  437. public override bool CanRead
  438. {
  439. get
  440. {
  441. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  442. return _baseStream._stream.CanRead;
  443. }
  444. }
  445. /// <summary>
  446. /// Indicates whether the stream supports Seek operations.
  447. /// </summary>
  448. /// <remarks>
  449. /// Always returns false.
  450. /// </remarks>
  451. public override bool CanSeek
  452. {
  453. get { return false; }
  454. }
  455. /// <summary>
  456. /// Indicates whether the stream can be written.
  457. /// </summary>
  458. /// <remarks>
  459. /// The return value depends on whether the captive stream supports writing.
  460. /// </remarks>
  461. public override bool CanWrite
  462. {
  463. get
  464. {
  465. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  466. return _baseStream._stream.CanWrite;
  467. }
  468. }
  469. /// <summary>
  470. /// Flush the stream.
  471. /// </summary>
  472. public override void Flush()
  473. {
  474. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  475. _baseStream.Flush();
  476. }
  477. /// <summary>
  478. /// Reading this property always throws a <see cref="NotImplementedException"/>.
  479. /// </summary>
  480. public override long Length
  481. {
  482. get { throw new NotImplementedException(); }
  483. }
  484. /// <summary>
  485. /// The position of the stream pointer.
  486. /// </summary>
  487. ///
  488. /// <remarks>
  489. /// Setting this property always throws a <see
  490. /// cref="NotImplementedException"/>. Reading will return the total bytes
  491. /// written out, if used in writing, or the total bytes read in, if used in
  492. /// reading. The count may refer to compressed bytes or uncompressed bytes,
  493. /// depending on how you've used the stream.
  494. /// </remarks>
  495. public override long Position
  496. {
  497. get
  498. {
  499. if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
  500. return this._baseStream._z.TotalBytesOut;
  501. if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
  502. return this._baseStream._z.TotalBytesIn;
  503. return 0;
  504. }
  505. set { throw new NotImplementedException(); }
  506. }
  507. /// <summary>
  508. /// Read data from the stream.
  509. /// </summary>
  510. /// <remarks>
  511. ///
  512. /// <para>
  513. /// If you wish to use the <c>DeflateStream</c> to compress data while
  514. /// reading, you can create a <c>DeflateStream</c> with
  515. /// <c>CompressionMode.Compress</c>, providing an uncompressed data stream.
  516. /// Then call Read() on that <c>DeflateStream</c>, and the data read will be
  517. /// compressed as you read. If you wish to use the <c>DeflateStream</c> to
  518. /// decompress data while reading, you can create a <c>DeflateStream</c> with
  519. /// <c>CompressionMode.Decompress</c>, providing a readable compressed data
  520. /// stream. Then call Read() on that <c>DeflateStream</c>, and the data read
  521. /// will be decompressed as you read.
  522. /// </para>
  523. ///
  524. /// <para>
  525. /// A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
  526. /// </para>
  527. ///
  528. /// </remarks>
  529. /// <param name="buffer">The buffer into which the read data should be placed.</param>
  530. /// <param name="offset">the offset within that data array to put the first byte read.</param>
  531. /// <param name="count">the number of bytes to read.</param>
  532. /// <returns>the number of bytes actually read</returns>
  533. public override int Read(byte[] buffer, int offset, int count)
  534. {
  535. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  536. return _baseStream.Read(buffer, offset, count);
  537. }
  538. /// <summary>
  539. /// Calling this method always throws a <see cref="NotImplementedException"/>.
  540. /// </summary>
  541. /// <param name="offset">this is irrelevant, since it will always throw!</param>
  542. /// <param name="origin">this is irrelevant, since it will always throw!</param>
  543. /// <returns>irrelevant!</returns>
  544. public override long Seek(long offset, System.IO.SeekOrigin origin)
  545. {
  546. throw new NotImplementedException();
  547. }
  548. /// <summary>
  549. /// Calling this method always throws a <see cref="NotImplementedException"/>.
  550. /// </summary>
  551. /// <param name="value">this is irrelevant, since it will always throw!</param>
  552. public override void SetLength(long value)
  553. {
  554. throw new NotImplementedException();
  555. }
  556. /// <summary>
  557. /// Write data to the stream.
  558. /// </summary>
  559. /// <remarks>
  560. ///
  561. /// <para>
  562. /// If you wish to use the <c>DeflateStream</c> to compress data while
  563. /// writing, you can create a <c>DeflateStream</c> with
  564. /// <c>CompressionMode.Compress</c>, and a writable output stream. Then call
  565. /// <c>Write()</c> on that <c>DeflateStream</c>, providing uncompressed data
  566. /// as input. The data sent to the output stream will be the compressed form
  567. /// of the data written. If you wish to use the <c>DeflateStream</c> to
  568. /// decompress data while writing, you can create a <c>DeflateStream</c> with
  569. /// <c>CompressionMode.Decompress</c>, and a writable output stream. Then
  570. /// call <c>Write()</c> on that stream, providing previously compressed
  571. /// data. The data sent to the output stream will be the decompressed form of
  572. /// the data written.
  573. /// </para>
  574. ///
  575. /// <para>
  576. /// A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>,
  577. /// but not both.
  578. /// </para>
  579. ///
  580. /// </remarks>
  581. ///
  582. /// <param name="buffer">The buffer holding data to write to the stream.</param>
  583. /// <param name="offset">the offset within that data array to find the first byte to write.</param>
  584. /// <param name="count">the number of bytes to write.</param>
  585. public override void Write(byte[] buffer, int offset, int count)
  586. {
  587. if (_disposed) throw new ObjectDisposedException("DeflateStream");
  588. _baseStream.Write(buffer, offset, count);
  589. }
  590. #endregion
  591. /// <summary>
  592. /// Compress a string into a byte array using DEFLATE (RFC 1951).
  593. /// </summary>
  594. ///
  595. /// <remarks>
  596. /// Uncompress it with <see cref="DeflateStream.UncompressString(byte[])"/>.
  597. /// </remarks>
  598. ///
  599. /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
  600. /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
  601. /// <seealso cref="GZipStream.CompressString(string)">GZipStream.CompressString(string)</seealso>
  602. /// <seealso cref="ZlibStream.CompressString(string)">ZlibStream.CompressString(string)</seealso>
  603. ///
  604. /// <param name="s">
  605. /// A string to compress. The string will first be encoded
  606. /// using UTF8, then compressed.
  607. /// </param>
  608. ///
  609. /// <returns>The string in compressed form</returns>
  610. public static byte[] CompressString(String s)
  611. {
  612. using (var ms = new System.IO.MemoryStream())
  613. {
  614. System.IO.Stream compressor =
  615. new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
  616. ZlibBaseStream.CompressString(s, compressor);
  617. return ms.ToArray();
  618. }
  619. }
  620. /// <summary>
  621. /// Compress a byte array into a new byte array using DEFLATE.
  622. /// </summary>
  623. ///
  624. /// <remarks>
  625. /// Uncompress it with <see cref="DeflateStream.UncompressBuffer(byte[])"/>.
  626. /// </remarks>
  627. ///
  628. /// <seealso cref="DeflateStream.CompressString(string)">DeflateStream.CompressString(string)</seealso>
  629. /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
  630. /// <seealso cref="GZipStream.CompressBuffer(byte[])">GZipStream.CompressBuffer(byte[])</seealso>
  631. /// <seealso cref="ZlibStream.CompressBuffer(byte[])">ZlibStream.CompressBuffer(byte[])</seealso>
  632. ///
  633. /// <param name="b">
  634. /// A buffer to compress.
  635. /// </param>
  636. ///
  637. /// <returns>The data in compressed form</returns>
  638. public static byte[] CompressBuffer(byte[] b)
  639. {
  640. using (var ms = new System.IO.MemoryStream())
  641. {
  642. System.IO.Stream compressor =
  643. new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
  644. ZlibBaseStream.CompressBuffer(b, compressor);
  645. return ms.ToArray();
  646. }
  647. }
  648. /// <summary>
  649. /// Uncompress a DEFLATE'd byte array into a single string.
  650. /// </summary>
  651. ///
  652. /// <seealso cref="DeflateStream.CompressString(String)">DeflateStream.CompressString(String)</seealso>
  653. /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
  654. /// <seealso cref="GZipStream.UncompressString(byte[])">GZipStream.UncompressString(byte[])</seealso>
  655. /// <seealso cref="ZlibStream.UncompressString(byte[])">ZlibStream.UncompressString(byte[])</seealso>
  656. ///
  657. /// <param name="compressed">
  658. /// A buffer containing DEFLATE-compressed data.
  659. /// </param>
  660. ///
  661. /// <returns>The uncompressed string</returns>
  662. public static String UncompressString(byte[] compressed)
  663. {
  664. using (var input = new System.IO.MemoryStream(compressed))
  665. {
  666. System.IO.Stream decompressor =
  667. new DeflateStream(input, CompressionMode.Decompress);
  668. return ZlibBaseStream.UncompressString(compressed, decompressor);
  669. }
  670. }
  671. /// <summary>
  672. /// Uncompress a DEFLATE'd byte array into a byte array.
  673. /// </summary>
  674. ///
  675. /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
  676. /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
  677. /// <seealso cref="GZipStream.UncompressBuffer(byte[])">GZipStream.UncompressBuffer(byte[])</seealso>
  678. /// <seealso cref="ZlibStream.UncompressBuffer(byte[])">ZlibStream.UncompressBuffer(byte[])</seealso>
  679. ///
  680. /// <param name="compressed">
  681. /// A buffer containing data that has been compressed with DEFLATE.
  682. /// </param>
  683. ///
  684. /// <returns>The data in uncompressed form</returns>
  685. public static byte[] UncompressBuffer(byte[] compressed)
  686. {
  687. using (var input = new System.IO.MemoryStream(compressed))
  688. {
  689. System.IO.Stream decompressor =
  690. new DeflateStream( input, CompressionMode.Decompress );
  691. return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
  692. }
  693. }
  694. }
  695. }