OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [archive/] [zip/] [struct.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// 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 (
15
        "errors"
16
        "os"
17
        "time"
18
)
19
 
20
// Compression methods.
21
const (
22
        Store   uint16 = 0
23
        Deflate uint16 = 8
24
)
25
 
26
const (
27
        fileHeaderSignature      = 0x04034b50
28
        directoryHeaderSignature = 0x02014b50
29
        directoryEndSignature    = 0x06054b50
30
        fileHeaderLen            = 30 // + filename + extra
31
        directoryHeaderLen       = 46 // + filename + extra + comment
32
        directoryEndLen          = 22 // + comment
33
        dataDescriptorLen        = 12
34
 
35
        // Constants for the first byte in CreatorVersion
36
        creatorFAT    = 0
37
        creatorUnix   = 3
38
        creatorNTFS   = 11
39
        creatorVFAT   = 14
40
        creatorMacOSX = 19
41
)
42
 
43
type FileHeader struct {
44
        Name             string
45
        CreatorVersion   uint16
46
        ReaderVersion    uint16
47
        Flags            uint16
48
        Method           uint16
49
        ModifiedTime     uint16 // MS-DOS time
50
        ModifiedDate     uint16 // MS-DOS date
51
        CRC32            uint32
52
        CompressedSize   uint32
53
        UncompressedSize uint32
54
        Extra            []byte
55
        ExternalAttrs    uint32 // Meaning depends on CreatorVersion
56
        Comment          string
57
}
58
 
59
// FileInfo returns an os.FileInfo for the FileHeader.
60
func (h *FileHeader) FileInfo() os.FileInfo {
61
        return headerFileInfo{h}
62
}
63
 
64
// headerFileInfo implements os.FileInfo.
65
type headerFileInfo struct {
66
        fh *FileHeader
67
}
68
 
69
func (fi headerFileInfo) Name() string       { return fi.fh.Name }
70
func (fi headerFileInfo) Size() int64        { return int64(fi.fh.UncompressedSize) }
71
func (fi headerFileInfo) IsDir() bool        { return fi.Mode().IsDir() }
72
func (fi headerFileInfo) ModTime() time.Time { return fi.fh.ModTime() }
73
func (fi headerFileInfo) Mode() os.FileMode  { return fi.fh.Mode() }
74
func (fi headerFileInfo) Sys() interface{}   { return fi.fh }
75
 
76
// FileInfoHeader creates a partially-populated FileHeader from an
77
// os.FileInfo.
78
func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) {
79
        size := fi.Size()
80
        if size > (1<<32 - 1) {
81
                return nil, errors.New("zip: file over 4GB")
82
        }
83
        fh := &FileHeader{
84
                Name:             fi.Name(),
85
                UncompressedSize: uint32(size),
86
        }
87
        fh.SetModTime(fi.ModTime())
88
        fh.SetMode(fi.Mode())
89
        return fh, nil
90
}
91
 
92
type directoryEnd struct {
93
        diskNbr            uint16 // unused
94
        dirDiskNbr         uint16 // unused
95
        dirRecordsThisDisk uint16 // unused
96
        directoryRecords   uint16
97
        directorySize      uint32
98
        directoryOffset    uint32 // relative to file
99
        commentLen         uint16
100
        comment            string
101
}
102
 
103
func recoverError(errp *error) {
104
        if e := recover(); e != nil {
105
                if err, ok := e.(error); ok {
106
                        *errp = err
107
                        return
108
                }
109
                panic(e)
110
        }
111
}
112
 
113
// msDosTimeToTime converts an MS-DOS date and time into a time.Time.
114
// The resolution is 2s.
115
// See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
116
func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
117
        return time.Date(
118
                // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980
119
                int(dosDate>>9+1980),
120
                time.Month(dosDate>>5&0xf),
121
                int(dosDate&0x1f),
122
 
123
                // time bits 0-4: second/2; 5-10: minute; 11-15: hour
124
                int(dosTime>>11),
125
                int(dosTime>>5&0x3f),
126
                int(dosTime&0x1f*2),
127
                0, // nanoseconds
128
 
129
                time.UTC,
130
        )
131
}
132
 
133
// timeToMsDosTime converts a time.Time to an MS-DOS date and time.
134
// The resolution is 2s.
135
// See: http://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx
136
func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
137
        t = t.In(time.UTC)
138
        fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9)
139
        fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11)
140
        return
141
}
142
 
143
// ModTime returns the modification time.
144
// The resolution is 2s.
145
func (h *FileHeader) ModTime() time.Time {
146
        return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
147
}
148
 
149
// SetModTime sets the ModifiedTime and ModifiedDate fields to the given time.
150
// The resolution is 2s.
151
func (h *FileHeader) SetModTime(t time.Time) {
152
        h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
153
}
154
 
155
const (
156
        // Unix constants. The specification doesn't mention them,
157
        // but these seem to be the values agreed on by tools.
158
        s_IFMT   = 0xf000
159
        s_IFSOCK = 0xc000
160
        s_IFLNK  = 0xa000
161
        s_IFREG  = 0x8000
162
        s_IFBLK  = 0x6000
163
        s_IFDIR  = 0x4000
164
        s_IFCHR  = 0x2000
165
        s_IFIFO  = 0x1000
166
        s_ISUID  = 0x800
167
        s_ISGID  = 0x400
168
        s_ISVTX  = 0x200
169
 
170
        msdosDir      = 0x10
171
        msdosReadOnly = 0x01
172
)
173
 
174
// Mode returns the permission and mode bits for the FileHeader.
175
func (h *FileHeader) Mode() (mode os.FileMode) {
176
        switch h.CreatorVersion >> 8 {
177
        case creatorUnix, creatorMacOSX:
178
                mode = unixModeToFileMode(h.ExternalAttrs >> 16)
179
        case creatorNTFS, creatorVFAT, creatorFAT:
180
                mode = msdosModeToFileMode(h.ExternalAttrs)
181
        }
182
        if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
183
                mode |= os.ModeDir
184
        }
185
        return mode
186
}
187
 
188
// SetMode changes the permission and mode bits for the FileHeader.
189
func (h *FileHeader) SetMode(mode os.FileMode) {
190
        h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
191
        h.ExternalAttrs = fileModeToUnixMode(mode) << 16
192
 
193
        // set MSDOS attributes too, as the original zip does.
194
        if mode&os.ModeDir != 0 {
195
                h.ExternalAttrs |= msdosDir
196
        }
197
        if mode&0200 == 0 {
198
                h.ExternalAttrs |= msdosReadOnly
199
        }
200
}
201
 
202
func msdosModeToFileMode(m uint32) (mode os.FileMode) {
203
        if m&msdosDir != 0 {
204
                mode = os.ModeDir | 0777
205
        } else {
206
                mode = 0666
207
        }
208
        if m&msdosReadOnly != 0 {
209
                mode &^= 0222
210
        }
211
        return mode
212
}
213
 
214
func fileModeToUnixMode(mode os.FileMode) uint32 {
215
        var m uint32
216
        switch mode & os.ModeType {
217
        default:
218
                m = s_IFREG
219
        case os.ModeDir:
220
                m = s_IFDIR
221
        case os.ModeSymlink:
222
                m = s_IFLNK
223
        case os.ModeNamedPipe:
224
                m = s_IFIFO
225
        case os.ModeSocket:
226
                m = s_IFSOCK
227
        case os.ModeDevice:
228
                if mode&os.ModeCharDevice != 0 {
229
                        m = s_IFCHR
230
                } else {
231
                        m = s_IFBLK
232
                }
233
        }
234
        if mode&os.ModeSetuid != 0 {
235
                m |= s_ISUID
236
        }
237
        if mode&os.ModeSetgid != 0 {
238
                m |= s_ISGID
239
        }
240
        if mode&os.ModeSticky != 0 {
241
                m |= s_ISVTX
242
        }
243
        return m | uint32(mode&0777)
244
}
245
 
246
func unixModeToFileMode(m uint32) os.FileMode {
247
        mode := os.FileMode(m & 0777)
248
        switch m & s_IFMT {
249
        case s_IFBLK:
250
                mode |= os.ModeDevice
251
        case s_IFCHR:
252
                mode |= os.ModeDevice | os.ModeCharDevice
253
        case s_IFDIR:
254
                mode |= os.ModeDir
255
        case s_IFIFO:
256
                mode |= os.ModeNamedPipe
257
        case s_IFLNK:
258
                mode |= os.ModeSymlink
259
        case s_IFREG:
260
                // nothing to do
261
        case s_IFSOCK:
262
                mode |= os.ModeSocket
263
        }
264
        if m&s_ISGID != 0 {
265
                mode |= os.ModeSetgid
266
        }
267
        if m&s_ISUID != 0 {
268
                mode |= os.ModeSetuid
269
        }
270
        if m&s_ISVTX != 0 {
271
                mode |= os.ModeSticky
272
        }
273
        return mode
274
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.