OLD | NEW |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package zip | 5 package zip |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "compress/flate" | |
10 "encoding/binary" | 9 "encoding/binary" |
11 "errors" | 10 "errors" |
12 "hash" | 11 "hash" |
13 "hash/crc32" | 12 "hash/crc32" |
14 "io" | 13 "io" |
15 "io/ioutil" | |
16 "os" | 14 "os" |
17 ) | 15 ) |
18 | 16 |
19 var ( | 17 var ( |
20 ErrFormat = errors.New("zip: not a valid zip file") | 18 ErrFormat = errors.New("zip: not a valid zip file") |
21 ErrAlgorithm = errors.New("zip: unsupported compression algorithm") | 19 ErrAlgorithm = errors.New("zip: unsupported compression algorithm") |
22 ErrChecksum = errors.New("zip: checksum error") | 20 ErrChecksum = errors.New("zip: checksum error") |
23 ) | 21 ) |
24 | 22 |
25 type Reader struct { | 23 type Reader struct { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 116 |
119 // Open returns a ReadCloser that provides access to the File's contents. | 117 // Open returns a ReadCloser that provides access to the File's contents. |
120 // Multiple files may be read concurrently. | 118 // Multiple files may be read concurrently. |
121 func (f *File) Open() (rc io.ReadCloser, err error) { | 119 func (f *File) Open() (rc io.ReadCloser, err error) { |
122 bodyOffset, err := f.findBodyOffset() | 120 bodyOffset, err := f.findBodyOffset() |
123 if err != nil { | 121 if err != nil { |
124 return | 122 return |
125 } | 123 } |
126 size := int64(f.CompressedSize64) | 124 size := int64(f.CompressedSize64) |
127 r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size) | 125 r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size) |
128 » switch f.Method { | 126 » dcomp := decompressor(f.Method) |
129 » case Store: // (no compression) | 127 » if dcomp == nil { |
130 » » rc = ioutil.NopCloser(r) | |
131 » case Deflate: | |
132 » » rc = flate.NewReader(r) | |
133 » default: | |
134 err = ErrAlgorithm | 128 err = ErrAlgorithm |
135 return | 129 return |
136 } | 130 } |
| 131 rc = dcomp(r) |
137 var desr io.Reader | 132 var desr io.Reader |
138 if f.hasDataDescriptor() { | 133 if f.hasDataDescriptor() { |
139 desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+siz
e, dataDescriptorLen) | 134 desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+siz
e, dataDescriptorLen) |
140 } | 135 } |
141 rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil} | 136 rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil} |
142 return | 137 return |
143 } | 138 } |
144 | 139 |
145 type checksumReader struct { | 140 type checksumReader struct { |
146 rc io.ReadCloser | 141 rc io.ReadCloser |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 v := binary.LittleEndian.Uint32(*b) | 427 v := binary.LittleEndian.Uint32(*b) |
433 *b = (*b)[4:] | 428 *b = (*b)[4:] |
434 return v | 429 return v |
435 } | 430 } |
436 | 431 |
437 func (b *readBuf) uint64() uint64 { | 432 func (b *readBuf) uint64() uint64 { |
438 v := binary.LittleEndian.Uint64(*b) | 433 v := binary.LittleEndian.Uint64(*b) |
439 *b = (*b)[8:] | 434 *b = (*b)[8:] |
440 return v | 435 return v |
441 } | 436 } |
OLD | NEW |