| // Copyright 2010 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| /* | |
| Package zip provides support for reading and writing ZIP archives. | |
| See: http://www.pkware.com/documents/casestudies/APPNOTE.TXT | |
| This package does not support ZIP64 or disk spanning. | |
| */ | |
| package zip | |
| import "os" | |
| import "time" | |
| // Compression methods. | |
| const ( | |
| Store uint16 = 0 | |
| Deflate uint16 = 8 | |
| ) | |
| const ( | |
| fileHeaderSignature = 0x04034b50 | |
| directoryHeaderSignature = 0x02014b50 | |
| directoryEndSignature = 0x06054b50 | |
| dataDescriptorLen = 12 | |
| ) | |
| type FileHeader struct { | |
| Name string | |
| CreatorVersion uint16 | |
| ReaderVersion uint16 | |
| Flags uint16 | |
| Method uint16 | |
| ModifiedTime uint16 // MS-DOS time | |
| ModifiedDate uint16 // MS-DOS date | |
| CRC32 uint32 | |
| CompressedSize uint32 | |
| UncompressedSize uint32 | |
| Extra []byte | |
| Comment string | |
| } | |
| type directoryEnd struct { | |
| diskNbr uint16 // unused | |
| dirDiskNbr uint16 // unused | |
| dirRecordsThisDisk uint16 // unused | |
| directoryRecords uint16 | |
| directorySize uint32 | |
| directoryOffset uint32 // relative to file | |
| commentLen uint16 | |
| comment string | |
| } | |
| func recoverError(err *os.Error) { | |
| if e := recover(); e != nil { | |
| if osErr, ok := e.(os.Error); ok { | |
| *err = osErr | |
| return | |
| } | |
| panic(e) | |
| } | |
| } | |
| // msDosTimeToTime converts an MS-DOS date and time into a time.Time. | |
| // The resolution is 2s. | |
| // See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx | |
| func msDosTimeToTime(dosDate, dosTime uint16) time.Time { | |
| return time.Time{ | |
| // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980 | |
| Year: int64(dosDate>>9 + 1980), | |
| Month: int(dosDate >> 5 & 0xf), | |
| Day: int(dosDate & 0x1f), | |
| // time bits 0-4: second/2; 5-10: minute; 11-15: hour | |
| Hour: int(dosTime >> 11), | |
| Minute: int(dosTime >> 5 & 0x3f), | |
| Second: int(dosTime & 0x1f * 2), | |
| } | |
| } | |
| // Mtime_ns returns the modified time in ns since epoch. | |
| // The resolution is 2s. | |
| func (h *FileHeader) Mtime_ns() int64 { | |
| t := msDosTimeToTime(h.ModifiedDate, h.ModifiedTime) | |
| return t.Seconds() * 1e9 | |
| } |