1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
package zipextra
import (
"math/big"
)
// ExtraFieldUnixN is the Info-ZIP's New Unix (3rd generation) Extra Field
// identifier.
const ExtraFieldUnixN uint16 = 0x7875
const minimumLength = 4
// InfoZIPNewUnix is the New Unix Extra Field structure for holding UID and GID
// file ownership data.
type InfoZIPNewUnix struct {
Version uint8
Uid *big.Int
Gid *big.Int
}
// NewInfoZIPNewUnix returns a new InfoZIPNewUnix extra field structure.
func NewInfoZIPNewUnix(uid *big.Int, gid *big.Int) InfoZIPNewUnix {
return InfoZIPNewUnix{
Version: 1,
Uid: uid,
Gid: gid,
}
}
// Encode encodes the InfoZIPNewUnix extra field.
func (field InfoZIPNewUnix) Encode() []byte {
buf := NewBuffer([]byte{})
defer buf.WriteHeader(ExtraFieldUnixN)()
buid := bigBytesToLittleEndian(field.Uid)
if len(buid) < minimumLength {
buid = append(buid, make([]byte, minimumLength-len(buid))...)
}
bgid := bigBytesToLittleEndian(field.Gid)
if len(bgid) < minimumLength {
bgid = append(bgid, make([]byte, minimumLength-len(bgid))...)
}
buf.WriteByte(field.Version)
buf.Write8(uint8(len(buid)))
buf.WriteBytes(buid)
buf.Write8(uint8(len(bgid)))
buf.WriteBytes(bgid)
return buf.Bytes()
}
// InfoZIPNewUnix returns the decoded InfoZIPNewUnix extra field.
func (ef ExtraField) InfoZIPNewUnix() (field InfoZIPNewUnix, err error) {
buf := NewBuffer(ef)
if buf.Available() < 3 {
return field, ErrInvalidExtraFieldFormat
}
field.Version = buf.Read8()
uidSize := int(buf.Read8())
if buf.Available() < uidSize {
return field, ErrInvalidExtraFieldFormat
}
field.Uid = littleEndianBytesToBig(buf.ReadBytes(uidSize))
gidSize := int(buf.Read8())
if buf.Available() < gidSize {
return field, ErrInvalidExtraFieldFormat
}
field.Gid = littleEndianBytesToBig(buf.ReadBytes(gidSize))
return
}
|