Clarify portability and main program.
[python/dscho.git] / Demo / zlib / minigzip.py
blobeefdc393e54feb936fd9b95f43d4879639acc686
1 #!/usr/local/bin/python
2 # 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.
5 FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
7 def 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))
13 def 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
20 import zlib, sys
21 if len(sys.argv)!=2:
22 print 'Usage: minigzip.py <filename>'
23 print ' The file will be compressed or decompressed.'
24 sys.exit(0)
26 filename=sys.argv[1]
27 compressing=1 ; outputname=filename+'.gz'
28 if filename[-3:]=='.gz':
29 compressing=0 ; outputname=filename[:-3]
30 input=open(filename) ; output=open(outputname, 'w')
32 if compressing:
33 output.write('\037\213\010') # Write the header, ...
34 output.write(chr(FNAME)) # ... flag byte ...
36 import os # ... modification time ...
37 statval=os.stat(filename)
38 mtime=statval[8]
39 write32(output, mtime)
40 output.write('\002') # ... slowest compression alg. ...
41 output.write('\377') # ... OS (=unknown) ...
42 output.write(filename+'\000') # ... original filename ...
44 crcval=zlib.crc32("")
45 compobj=zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
46 zlib.DEF_MEM_LEVEL, 0)
47 while (1):
48 data=input.read(1024)
49 if data=="": break
50 crcval=zlib.crc32(data, crcval)
51 output.write(compobj.compress(data))
52 output.write(compobj.flush())
53 write32(output, crcval) # ... the CRC ...
54 write32(output, statval[6]) # and the file size.
56 else:
57 magic=input.read(2)
58 if magic!='\037\213':
59 print 'Not a gzipped file' ; sys.exit(0)
60 if ord(input.read(1))!=8:
61 print 'Unknown compression method' ; sys.exit(0)
62 flag=ord(input.read(1))
63 input.read(4+1+1) # Discard modification time,
64 # extra flags, and OS byte.
65 if flag & FEXTRA:
66 # 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)
70 if flag & FNAME:
71 # Read and discard a null-terminated string containing the filename
72 while (1):
73 s=input.read(1)
74 if s=='\000': break
75 if flag & FCOMMENT:
76 # Read and discard a null-terminated string containing a comment
77 while (1):
78 s=input.read(1)
79 if s=='\000': break
80 if flag & FHCRC:
81 input.read(2) # Read & discard the 16-bit header CRC
82 decompobj=zlib.decompressobj(-zlib.MAX_WBITS)
83 crcval=zlib.crc32("")
84 length=0
85 while (1):
86 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)
92 decompdata=decompobj.flush()
93 output.write(decompdata) ; length=length+len(decompdata)
94 crcval=zlib.crc32(decompdata, crcval)
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'
106 input.close() ; output.close()