blob: dc99d9bc88eba1622ebe2b1ffad8e6ebc3bdbb4e [file] [log] [blame]
Guido van Rossum9a4da081999-03-12 19:07:59 +00001#!/usr/bin/env python
Guido van Rossum5416a0d1997-05-28 16:13:21 +00002# Demo program for zlib; it compresses or decompresses files, but *doesn't*
3# delete the original. This doesn't support all of gzip's options.
4
5FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
6
7def write32(output, value):
8 output.write(chr(value & 255)) ; value=value / 256
9 output.write(chr(value & 255)) ; value=value / 256
10 output.write(chr(value & 255)) ; value=value / 256
11 output.write(chr(value & 255))
12
13def read32(input):
14 v=ord(input.read(1))
15 v=v+ (ord(input.read(1))<<8 )
16 v=v+ (ord(input.read(1))<<16)
17 v=v+ (ord(input.read(1))<<24)
18 return v
19
20import zlib, sys
21if len(sys.argv)!=2:
22 print 'Usage: minigzip.py <filename>'
23 print ' The file will be compressed or decompressed.'
24 sys.exit(0)
25
26filename=sys.argv[1]
27compressing=1 ; outputname=filename+'.gz'
28if filename[-3:]=='.gz':
29 compressing=0 ; outputname=filename[:-3]
30input=open(filename) ; output=open(outputname, 'w')
31
32if compressing:
33 output.write('\037\213\010') # Write the header, ...
Guido van Rossum4117e541998-09-14 16:44:15 +000034 output.write(chr(FNAME)) # ... flag byte ...
Guido van Rossum5416a0d1997-05-28 16:13:21 +000035
Guido van Rossum4117e541998-09-14 16:44:15 +000036 import os # ... modification time ...
Guido van Rossum5416a0d1997-05-28 16:13:21 +000037 statval=os.stat(filename)
38 mtime=statval[8]
39 write32(output, mtime)
Guido van Rossum4117e541998-09-14 16:44:15 +000040 output.write('\002') # ... slowest compression alg. ...
41 output.write('\377') # ... OS (=unknown) ...
42 output.write(filename+'\000') # ... original filename ...
Guido van Rossum5416a0d1997-05-28 16:13:21 +000043
44 crcval=zlib.crc32("")
45 compobj=zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
Guido van Rossum4117e541998-09-14 16:44:15 +000046 zlib.DEF_MEM_LEVEL, 0)
Guido van Rossum5416a0d1997-05-28 16:13:21 +000047 while (1):
Guido van Rossum4117e541998-09-14 16:44:15 +000048 data=input.read(1024)
49 if data=="": break
50 crcval=zlib.crc32(data, crcval)
51 output.write(compobj.compress(data))
Guido van Rossum5416a0d1997-05-28 16:13:21 +000052 output.write(compobj.flush())
Guido van Rossum4117e541998-09-14 16:44:15 +000053 write32(output, crcval) # ... the CRC ...
54 write32(output, statval[6]) # and the file size.
Guido van Rossum5416a0d1997-05-28 16:13:21 +000055
56else:
57 magic=input.read(2)
58 if magic!='\037\213':
Guido van Rossum4117e541998-09-14 16:44:15 +000059 print 'Not a gzipped file' ; sys.exit(0)
Guido van Rossum5416a0d1997-05-28 16:13:21 +000060 if ord(input.read(1))!=8:
Guido van Rossum4117e541998-09-14 16:44:15 +000061 print 'Unknown compression method' ; sys.exit(0)
Guido van Rossum5416a0d1997-05-28 16:13:21 +000062 flag=ord(input.read(1))
Guido van Rossum4117e541998-09-14 16:44:15 +000063 input.read(4+1+1) # Discard modification time,
64 # extra flags, and OS byte.
Guido van Rossum5416a0d1997-05-28 16:13:21 +000065 if flag & FEXTRA:
Guido van Rossum4117e541998-09-14 16:44:15 +000066 # Read & discard the extra field, if present
67 xlen=ord(input.read(1))
68 xlen=xlen+256*ord(input.read(1))
69 input.read(xlen)
Guido van Rossum5416a0d1997-05-28 16:13:21 +000070 if flag & FNAME:
Guido van Rossum4117e541998-09-14 16:44:15 +000071 # Read and discard a null-terminated string containing the filename
72 while (1):
73 s=input.read(1)
74 if s=='\000': break
Guido van Rossum5416a0d1997-05-28 16:13:21 +000075 if flag & FCOMMENT:
Guido van Rossum4117e541998-09-14 16:44:15 +000076 # Read and discard a null-terminated string containing a comment
77 while (1):
78 s=input.read(1)
79 if s=='\000': break
Guido van Rossum5416a0d1997-05-28 16:13:21 +000080 if flag & FHCRC:
Guido van Rossum4117e541998-09-14 16:44:15 +000081 input.read(2) # Read & discard the 16-bit header CRC
Guido van Rossum5416a0d1997-05-28 16:13:21 +000082 decompobj=zlib.decompressobj(-zlib.MAX_WBITS)
83 crcval=zlib.crc32("")
84 length=0
85 while (1):
Guido van Rossum4117e541998-09-14 16:44:15 +000086 data=input.read(1024)
87 if data=="": break
88 decompdata=decompobj.decompress(data)
89 print len(decompdata)
90 output.write(decompdata) ; length=length+len(decompdata)
91 crcval=zlib.crc32(decompdata, crcval)
Guido van Rossum5416a0d1997-05-28 16:13:21 +000092 decompdata=decompobj.flush()
93 output.write(decompdata) ; length=length+len(decompdata)
94 crcval=zlib.crc32(decompdata, crcval)
95
96 # We've read to the end of the file, so we have to rewind in order
97 # to reread the 8 bytes containing the CRC and the file size. The
98 # decompressor is smart and knows when to stop, so feeding it
99 # extra data is harmless.
100 input.seek(-8, 2)
101 crc32=read32(input)
102 isize=read32(input)
103 if crc32!=crcval: print 'CRC check failed.'
104 if isize!=length: print 'Incorrect length of data produced'
105
106input.close() ; output.close()
107