OSDN Git Service

libgo: Update to weekly.2011-11-02.
[pf3gnuchains/gcc-fork.git] / libgo / go / archive / zip / struct.go
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.
4
5 /*
6 Package zip provides support for reading and writing ZIP archives.
7
8 See: http://www.pkware.com/documents/casestudies/APPNOTE.TXT
9
10 This package does not support ZIP64 or disk spanning.
11 */
12 package zip
13
14 import "errors"
15 import "time"
16
17 // Compression methods.
18 const (
19         Store   uint16 = 0
20         Deflate uint16 = 8
21 )
22
23 const (
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
31
32         // Constants for the first byte in CreatorVersion
33         creatorUnix = 3
34 )
35
36 type FileHeader struct {
37         Name             string
38         CreatorVersion   uint16
39         ReaderVersion    uint16
40         Flags            uint16
41         Method           uint16
42         ModifiedTime     uint16 // MS-DOS time
43         ModifiedDate     uint16 // MS-DOS date
44         CRC32            uint32
45         CompressedSize   uint32
46         UncompressedSize uint32
47         Extra            []byte
48         ExternalAttrs    uint32 // Meaning depends on CreatorVersion
49         Comment          string
50 }
51
52 type directoryEnd struct {
53         diskNbr            uint16 // unused
54         dirDiskNbr         uint16 // unused
55         dirRecordsThisDisk uint16 // unused
56         directoryRecords   uint16
57         directorySize      uint32
58         directoryOffset    uint32 // relative to file
59         commentLen         uint16
60         comment            string
61 }
62
63 func recoverError(errp *error) {
64         if e := recover(); e != nil {
65                 if err, ok := e.(error); ok {
66                         *errp = err
67                         return
68                 }
69                 panic(e)
70         }
71 }
72
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 {
77         return 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),
82
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),
87         }
88 }
89
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
95 }
96
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
102         }
103         return 0, errors.New("file mode not available")
104 }
105
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
110 }