30
30
*/
31
31
32
32
using System ;
33
- using System . Collections . Generic ;
33
+ using System . IO ;
34
34
using static SabreTools . Compression . Blast . Constants ;
35
35
36
36
namespace SabreTools . Compression . Blast
37
37
{
38
- public unsafe static class BlastDecoder
38
+ /// <summary>
39
+ /// blast() decompresses the PKWare Data Compression Library (DCL) compressed
40
+ /// format. It provides the same functionality as the explode() function in
41
+ /// that library. (Note: PKWare overused the "implode" verb, and the format
42
+ /// used by their library implode() function is completely different and
43
+ /// incompatible with the implode compression method supported by PKZIP.)
44
+ ///
45
+ /// The binary mode for stdio functions should be used to assure that the
46
+ /// compressed data is not corrupted when read or written. For example:
47
+ /// fopen(..., "rb") and fopen(..., "wb").
48
+ /// </summary>
49
+ public unsafe class Decompressor
39
50
{
40
51
#region Huffman Encoding
41
52
42
53
/// <summary>
43
54
/// Literal code
44
55
/// </summary>
45
- private static readonly Huffman litcode = new ( MAXBITS + 1 , 256 ) ;
56
+ private readonly Huffman litcode = new ( MAXBITS + 1 , 256 ) ;
46
57
47
58
/// <summary>
48
59
/// Length code
49
60
/// </summary>
50
- private static readonly Huffman lencode = new ( MAXBITS + 1 , 16 ) ;
61
+ private readonly Huffman lencode = new ( MAXBITS + 1 , 16 ) ;
51
62
52
63
/// <summary>
53
64
/// Distance code
54
65
/// </summary>
55
- private static readonly Huffman distcode = new ( MAXBITS + 1 , 64 ) ;
66
+ private readonly Huffman distcode = new ( MAXBITS + 1 , 64 ) ;
56
67
57
68
/// <summary>
58
69
/// Base for length codes
@@ -72,10 +83,12 @@ public unsafe static class BlastDecoder
72
83
73
84
#endregion
74
85
86
+ #region Constructors
87
+
75
88
/// <summary>
76
- /// Static constructor
89
+ /// Create a Blast decompressor
77
90
/// </summary>
78
- static BlastDecoder ( )
91
+ private Decompressor ( )
79
92
{
80
93
// Repeated code lengths of literal codes
81
94
byte [ ] litlen =
@@ -105,20 +118,29 @@ static BlastDecoder()
105
118
}
106
119
107
120
/// <summary>
108
- /// blast() decompresses the PKWare Data Compression Library (DCL) compressed
109
- /// format. It provides the same functionality as the explode() function in
110
- /// that library. (Note: PKWare overused the "implode" verb, and the format
111
- /// used by their library implode() function is completely different and
112
- /// incompatible with the implode compression method supported by PKZIP.)
113
- ///
114
- /// The binary mode for stdio functions should be used to assure that the
115
- /// compressed data is not corrupted when read or written. For example:
116
- /// fopen(..., "rb") and fopen(..., "wb").
121
+ /// Create a Blast decompressor
122
+ /// </summary>
123
+ public static Decompressor Create ( ) => new ( ) ;
124
+
125
+ #endregion
126
+
127
+ /// <summary>
128
+ /// Decompress source data to an output stream
129
+ /// </summary>
130
+ public bool CopyTo ( byte [ ] source , Stream dest )
131
+ => CopyTo ( new MemoryStream ( source ) , dest ) ;
132
+
133
+ /// <summary>
134
+ /// Decompress source data to an output stream
117
135
/// </summary>
118
- public static int Blast ( byte [ ] inhow , List < byte > outhow )
136
+ public bool CopyTo ( Stream source , Stream dest )
119
137
{
138
+ // Ignore unwritable streams
139
+ if ( ! dest . CanWrite )
140
+ return false ;
141
+
120
142
// Input/output state
121
- var state = new State ( inhow , outhow ) ;
143
+ var state = new State ( source , dest ) ;
122
144
123
145
// Attempt to decompress using the above state
124
146
int err ;
@@ -136,7 +158,7 @@ public static int Blast(byte[] inhow, List<byte> outhow)
136
158
if ( err != 1 && state . Next != 0 && ! state . ProcessOutput ( ) && err == 0 )
137
159
err = 1 ;
138
160
139
- return err ;
161
+ return err == 0 ;
140
162
}
141
163
142
164
/// <summary>
@@ -176,7 +198,7 @@ public static int Blast(byte[] inhow, List<byte> outhow)
176
198
/// ignoring whether the length is greater than the distance or not implements
177
199
/// this correctly.
178
200
/// </remarks>
179
- private static int Decomp ( State state )
201
+ private int Decomp ( State state )
180
202
{
181
203
int symbol ; // decoded symbol, extra bits for distance
182
204
int len ; // length for copy
@@ -194,7 +216,7 @@ private static int Decomp(State state)
194
216
return - 2 ;
195
217
196
218
// Decode literals and length/distance pairs
197
- do
219
+ while ( true )
198
220
{
199
221
if ( state . Bits ( 1 ) != 0 )
200
222
{
@@ -256,13 +278,12 @@ private static int Decomp(State state)
256
278
{
257
279
if ( ! state . ProcessOutput ( ) )
258
280
return 1 ;
259
-
281
+
260
282
state . Next = 0 ;
261
283
state . First = false ;
262
284
}
263
285
}
264
286
}
265
- while ( true ) ;
266
287
267
288
return 0 ;
268
289
}
0 commit comments