1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 Package zip provides support for reading and writing ZIP archives.
8 See: http://www.pkware.com/documents/casestudies/APPNOTE.TXT
10 This package does not support ZIP64 or disk spanning.
17 // Compression methods.
24 fileHeaderSignature = 0x04034b50
25 directoryHeaderSignature = 0x02014b50
26 directoryEndSignature = 0x06054b50
27 fileHeaderLen = 30 // + filename + extra
28 directoryHeaderLen = 46 // + filename + extra + comment
29 directoryEndLen = 22 // + comment
30 dataDescriptorLen = 12
32 // Constants for the first byte in CreatorVersion
36 type FileHeader struct {
42 ModifiedTime uint16 // MS-DOS time
43 ModifiedDate uint16 // MS-DOS date
46 UncompressedSize uint32
48 ExternalAttrs uint32 // Meaning depends on CreatorVersion
52 type directoryEnd struct {
53 diskNbr uint16 // unused
54 dirDiskNbr uint16 // unused
55 dirRecordsThisDisk uint16 // unused
56 directoryRecords uint16
58 directoryOffset uint32 // relative to file
63 func recoverError(errp *error) {
64 if e := recover(); e != nil {
65 if err, ok := e.(error); ok {
73 // msDosTimeToTime converts an MS-DOS date and time into a time.Time.
74 // The resolution is 2s.
75 // See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
76 func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
78 // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980
79 Year: int64(dosDate>>9 + 1980),
80 Month: int(dosDate >> 5 & 0xf),
81 Day: int(dosDate & 0x1f),
83 // time bits 0-4: second/2; 5-10: minute; 11-15: hour
84 Hour: int(dosTime >> 11),
85 Minute: int(dosTime >> 5 & 0x3f),
86 Second: int(dosTime & 0x1f * 2),
90 // Mtime_ns returns the modified time in ns since epoch.
91 // The resolution is 2s.
92 func (h *FileHeader) Mtime_ns() int64 {
93 t := msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
94 return t.Seconds() * 1e9
97 // Mode returns the permission and mode bits for the FileHeader.
98 // An error is returned in case the information is not available.
99 func (h *FileHeader) Mode() (mode uint32, err error) {
100 if h.CreatorVersion>>8 == creatorUnix {
101 return h.ExternalAttrs >> 16, nil
103 return 0, errors.New("file mode not available")
106 // SetMode changes the permission and mode bits for the FileHeader.
107 func (h *FileHeader) SetMode(mode uint32) {
108 h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
109 h.ExternalAttrs = mode << 16