33using ICSharpCode . SharpZipLib . Zip . Compression . Streams ;
44using System ;
55using System . IO ;
6+ using System . Text ;
67
78namespace ICSharpCode . SharpZipLib . GZip
89{
@@ -54,6 +55,8 @@ public class GZipInputStream : InflaterInputStream
5455 /// </summary>
5556 private bool completedLastBlock ;
5657
58+ private string fileName ;
59+
5760 #endregion Instance Fields
5861
5962 #region Constructors
@@ -149,6 +152,15 @@ public override int Read(byte[] buffer, int offset, int count)
149152 }
150153 }
151154
155+ /// <summary>
156+ /// Retrieves the filename header field for the block last read
157+ /// </summary>
158+ /// <returns></returns>
159+ public string GetFilename ( )
160+ {
161+ return fileName ;
162+ }
163+
152164 #endregion Stream overrides
153165
154166 #region Support routines
@@ -170,149 +182,108 @@ private bool ReadHeader()
170182 }
171183 }
172184
173- // 1. Check the two magic bytes
174185 var headCRC = new Crc32 ( ) ;
175- int magic = inputBuffer . ReadLeByte ( ) ;
176186
177- if ( magic < 0 )
178- {
179- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
180- }
187+ // 1. Check the two magic bytes
181188
189+ var magic = inputBuffer . ReadLeByte ( ) ;
182190 headCRC . Update ( magic ) ;
183- if ( magic != ( GZipConstants . GZIP_MAGIC >> 8 ) )
191+ if ( magic != GZipConstants . ID1 )
184192 {
185193 throw new GZipException ( "Error GZIP header, first magic byte doesn't match" ) ;
186194 }
187195
188- //magic = baseInputStream.ReadByte();
189196 magic = inputBuffer . ReadLeByte ( ) ;
190-
191- if ( magic < 0 )
192- {
193- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
194- }
195-
196- if ( magic != ( GZipConstants . GZIP_MAGIC & 0xFF ) )
197+ if ( magic != GZipConstants . ID2 )
197198 {
198199 throw new GZipException ( "Error GZIP header, second magic byte doesn't match" ) ;
199200 }
200-
201201 headCRC . Update ( magic ) ;
202202
203203 // 2. Check the compression type (must be 8)
204- int compressionType = inputBuffer . ReadLeByte ( ) ;
205-
206- if ( compressionType < 0 )
207- {
208- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
209- }
204+ var compressionType = inputBuffer . ReadLeByte ( ) ;
210205
211- if ( compressionType != 8 )
206+ if ( compressionType != GZipConstants . CompressionMethodDeflate )
212207 {
213208 throw new GZipException ( "Error GZIP header, data not in deflate format" ) ;
214209 }
215210 headCRC . Update ( compressionType ) ;
216211
217212 // 3. Check the flags
218- int flags = inputBuffer . ReadLeByte ( ) ;
219- if ( flags < 0 )
220- {
221- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
222- }
223- headCRC . Update ( flags ) ;
224-
225- /* This flag byte is divided into individual bits as follows:
213+ var flagsByte = inputBuffer . ReadLeByte ( ) ;
226214
227- bit 0 FTEXT
228- bit 1 FHCRC
229- bit 2 FEXTRA
230- bit 3 FNAME
231- bit 4 FCOMMENT
232- bit 5 reserved
233- bit 6 reserved
234- bit 7 reserved
235- */
215+ headCRC . Update ( flagsByte ) ;
236216
237217 // 3.1 Check the reserved bits are zero
238218
239- if ( ( flags & 0xE0 ) != 0 )
219+ if ( ( flagsByte & 0xE0 ) != 0 )
240220 {
241221 throw new GZipException ( "Reserved flag bits in GZIP header != 0" ) ;
242222 }
243223
224+ var flags = ( GZipFlags ) flagsByte ;
225+
244226 // 4.-6. Skip the modification time, extra flags, and OS type
245227 for ( int i = 0 ; i < 6 ; i ++ )
246228 {
247- int readByte = inputBuffer . ReadLeByte ( ) ;
248- if ( readByte < 0 )
249- {
250- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
251- }
252- headCRC . Update ( readByte ) ;
229+ headCRC . Update ( inputBuffer . ReadLeByte ( ) ) ;
253230 }
254231
255232 // 7. Read extra field
256- if ( ( flags & GZipConstants . FEXTRA ) != 0 )
233+ if ( flags . HasFlag ( GZipFlags . FEXTRA ) )
257234 {
258235 // XLEN is total length of extra subfields, we will skip them all
259- int len1 , len2 ;
260- len1 = inputBuffer . ReadLeByte ( ) ;
261- len2 = inputBuffer . ReadLeByte ( ) ;
262- if ( ( len1 < 0 ) || ( len2 < 0 ) )
263- {
264- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
265- }
236+ var len1 = inputBuffer . ReadLeByte ( ) ;
237+ var len2 = inputBuffer . ReadLeByte ( ) ;
238+
266239 headCRC . Update ( len1 ) ;
267240 headCRC . Update ( len2 ) ;
268241
269242 int extraLen = ( len2 << 8 ) | len1 ; // gzip is LSB first
270243 for ( int i = 0 ; i < extraLen ; i ++ )
271244 {
272- int readByte = inputBuffer . ReadLeByte ( ) ;
273- if ( readByte < 0 )
274- {
275- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
276- }
277- headCRC . Update ( readByte ) ;
245+ headCRC . Update ( inputBuffer . ReadLeByte ( ) ) ;
278246 }
279247 }
280248
281249 // 8. Read file name
282- if ( ( flags & GZipConstants . FNAME ) != 0 )
250+ if ( flags . HasFlag ( GZipFlags . FNAME ) )
283251 {
252+ var fname = new byte [ 1024 ] ;
253+ var fnamePos = 0 ;
284254 int readByte ;
285255 while ( ( readByte = inputBuffer . ReadLeByte ( ) ) > 0 )
286256 {
257+ if ( fnamePos < 1024 )
258+ {
259+ fname [ fnamePos ++ ] = ( byte ) readByte ;
260+ }
287261 headCRC . Update ( readByte ) ;
288262 }
289263
290- if ( readByte < 0 )
291- {
292- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
293- }
294264 headCRC . Update ( readByte ) ;
265+
266+ fileName = GZipConstants . Encoding . GetString ( fname , 0 , fnamePos ) ;
267+ }
268+ else
269+ {
270+ fileName = null ;
295271 }
296272
297273 // 9. Read comment
298- if ( ( flags & GZipConstants . FCOMMENT ) != 0 )
274+ if ( flags . HasFlag ( GZipFlags . FCOMMENT ) )
299275 {
300276 int readByte ;
301277 while ( ( readByte = inputBuffer . ReadLeByte ( ) ) > 0 )
302278 {
303279 headCRC . Update ( readByte ) ;
304280 }
305281
306- if ( readByte < 0 )
307- {
308- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
309- }
310-
311282 headCRC . Update ( readByte ) ;
312283 }
313284
314285 // 10. Read header CRC
315- if ( ( flags & GZipConstants . FHCRC ) != 0 )
286+ if ( flags . HasFlag ( GZipFlags . FHCRC ) )
316287 {
317288 int tempByte ;
318289 int crcval = inputBuffer . ReadLeByte ( ) ;
0 commit comments