diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-10-26 23:57:58 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-10-26 23:57:58 +0000 |
commit | d8f412571f8768df2d3239e72392dfeabbad1559 (patch) | |
tree | 19d182df05ead7ff8ba7ee00a7d57555e1383fdf /libgo/go/archive | |
parent | e0c39d66d4f0607177b1cf8995dda56a667e07b3 (diff) | |
download | gcc-d8f412571f8768df2d3239e72392dfeabbad1559.zip gcc-d8f412571f8768df2d3239e72392dfeabbad1559.tar.gz gcc-d8f412571f8768df2d3239e72392dfeabbad1559.tar.bz2 |
Update Go library to last weekly.
From-SVN: r180552
Diffstat (limited to 'libgo/go/archive')
-rw-r--r-- | libgo/go/archive/tar/common.go | 51 | ||||
-rw-r--r-- | libgo/go/archive/tar/reader.go | 2 | ||||
-rw-r--r-- | libgo/go/archive/tar/testdata/writer.tar | bin | 3072 -> 3584 bytes | |||
-rw-r--r-- | libgo/go/archive/tar/writer.go | 2 | ||||
-rw-r--r-- | libgo/go/archive/tar/writer_test.go | 19 | ||||
-rw-r--r-- | libgo/go/archive/zip/reader.go | 2 | ||||
-rw-r--r-- | libgo/go/archive/zip/reader_test.go | 18 | ||||
-rw-r--r-- | libgo/go/archive/zip/struct.go | 19 | ||||
-rw-r--r-- | libgo/go/archive/zip/writer.go | 4 | ||||
-rw-r--r-- | libgo/go/archive/zip/writer_test.go | 58 |
10 files changed, 133 insertions, 42 deletions
diff --git a/libgo/go/archive/tar/common.go b/libgo/go/archive/tar/common.go index 5288587..6735508 100644 --- a/libgo/go/archive/tar/common.go +++ b/libgo/go/archive/tar/common.go @@ -15,36 +15,37 @@ const ( blockSize = 512 // Types - TypeReg = '0' - TypeRegA = '\x00' - TypeLink = '1' - TypeSymlink = '2' - TypeChar = '3' - TypeBlock = '4' - TypeDir = '5' - TypeFifo = '6' - TypeCont = '7' - TypeXHeader = 'x' - TypeXGlobalHeader = 'g' + TypeReg = '0' // regular file. + TypeRegA = '\x00' // regular file. + TypeLink = '1' // hard link. + TypeSymlink = '2' // symbolic link. + TypeChar = '3' // character device node. + TypeBlock = '4' // block device node. + TypeDir = '5' // directory. + TypeFifo = '6' // fifo node. + TypeCont = '7' // reserved. + TypeXHeader = 'x' // extended header. + TypeXGlobalHeader = 'g' // global extended header. ) // A Header represents a single header in a tar archive. // Some fields may not be populated. type Header struct { - Name string - Mode int64 - Uid int - Gid int - Size int64 - Mtime int64 - Typeflag byte - Linkname string - Uname string - Gname string - Devmajor int64 - Devminor int64 - Atime int64 - Ctime int64 + Name string // name of header file entry. + Mode int64 // permission and mode bits. + Uid int // user id of owner. + Gid int // group id of owner. + Size int64 // length in bytes. + Mtime int64 // modified time; seconds since epoch. + Typeflag byte // type of header entry. + Linkname string // target name of link. + Uname string // user name of owner. + Gname string // group name of owner. + Devmajor int64 // major number of character or block device. + Devminor int64 // minor number of character or block device. + Atime int64 // access time; seconds since epoch. + Ctime int64 // status change time; seconds since epoch. + } var zeroBlock = make([]byte, blockSize) diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go index 45d95c3..12de2ad 100644 --- a/libgo/go/archive/tar/reader.go +++ b/libgo/go/archive/tar/reader.go @@ -94,7 +94,7 @@ func (tr *Reader) skipUnread() { return } } - _, tr.err = io.Copyn(ioutil.Discard, tr.r, nr) + _, tr.err = io.CopyN(ioutil.Discard, tr.r, nr) } func (tr *Reader) verifyChecksum(header []byte) bool { diff --git a/libgo/go/archive/tar/testdata/writer.tar b/libgo/go/archive/tar/testdata/writer.tar Binary files differindex 0358f91..e6d816a 100644 --- a/libgo/go/archive/tar/testdata/writer.tar +++ b/libgo/go/archive/tar/testdata/writer.tar diff --git a/libgo/go/archive/tar/writer.go b/libgo/go/archive/tar/writer.go index 8673bad..c6ce224 100644 --- a/libgo/go/archive/tar/writer.go +++ b/libgo/go/archive/tar/writer.go @@ -134,7 +134,7 @@ func (tw *Writer) WriteHeader(hdr *Header) os.Error { tw.numeric(s.next(12), hdr.Mtime) // 136:148 s.next(8) // chksum (148:156) s.next(1)[0] = hdr.Typeflag // 156:157 - s.next(100) // linkname (157:257) + tw.cString(s.next(100), hdr.Linkname) // linkname (157:257) copy(s.next(8), []byte("ustar\x0000")) // 257:265 tw.cString(s.next(32), hdr.Uname) // 265:297 tw.cString(s.next(32), hdr.Gname) // 297:329 diff --git a/libgo/go/archive/tar/writer_test.go b/libgo/go/archive/tar/writer_test.go index 838cb7e..6cc9386 100644 --- a/libgo/go/archive/tar/writer_test.go +++ b/libgo/go/archive/tar/writer_test.go @@ -24,6 +24,10 @@ type writerTest struct { } var writerTests = []*writerTest{ + // The writer test file was produced with this command: + // tar (GNU tar) 1.26 + // ln -s small.txt link.txt + // tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt &writerTest{ file: "testdata/writer.tar", entries: []*writerTestEntry{ @@ -55,6 +59,21 @@ var writerTests = []*writerTest{ }, contents: "Google.com\n", }, + &writerTestEntry{ + header: &Header{ + Name: "link.txt", + Mode: 0777, + Uid: 1000, + Gid: 1000, + Size: 0, + Mtime: 1314603082, + Typeflag: '2', + Linkname: "small.txt", + Uname: "strings", + Gname: "strings", + }, + // no contents + }, }, }, // The truncated test file was produced using these commands: diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go index f92f929..b0a5599 100644 --- a/libgo/go/archive/zip/reader.go +++ b/libgo/go/archive/zip/reader.go @@ -238,7 +238,7 @@ func readDirectoryHeader(f *File, r io.Reader) os.Error { commentLen := int(c.Uint16(b[32:34])) // startDiskNumber := c.Uint16(b[34:36]) // Unused // internalAttributes := c.Uint16(b[36:38]) // Unused - // externalAttributes := c.Uint32(b[38:42]) // Unused + f.ExternalAttrs = c.Uint32(b[38:42]) f.headerOffset = int64(c.Uint32(b[42:46])) d := make([]byte, filenameLen+extraLen+commentLen) if _, err := io.ReadFull(r, d); err != nil { diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go index fd5fed2..3b7b0dc 100644 --- a/libgo/go/archive/zip/reader_test.go +++ b/libgo/go/archive/zip/reader_test.go @@ -26,6 +26,7 @@ type ZipTestFile struct { Content []byte // if blank, will attempt to compare against File File string // name of file to compare to (relative to testdata/) Mtime string // modified time in format "mm-dd-yy hh:mm:ss" + Mode uint32 } // Caution: The Mtime values found for the test files should correspond to @@ -47,11 +48,13 @@ var tests = []ZipTest{ Name: "test.txt", Content: []byte("This is a test text file.\n"), Mtime: "09-05-10 12:12:02", + Mode: 0x81a4, }, { Name: "gophercolor16x16.png", File: "gophercolor16x16.png", Mtime: "09-05-10 15:52:58", + Mode: 0x81a4, }, }, }, @@ -162,6 +165,8 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) { t.Errorf("%s: mtime=%s (%d); want %s (%d)", f.Name, time.SecondsToUTC(got), got, mtime, want) } + testFileMode(t, f, ft.Mode) + size0 := f.UncompressedSize var b bytes.Buffer @@ -203,6 +208,19 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) { } } +func testFileMode(t *testing.T, f *File, want uint32) { + mode, err := f.Mode() + if want == 0 { + if err == nil { + t.Errorf("%s mode: got %v, want none", f.Name, mode) + } + } else if err != nil { + t.Errorf("%s mode: %s", f.Name, err) + } else if mode != want { + t.Errorf("%s mode: want 0x%x, got 0x%x", f.Name, want, mode) + } +} + func TestInvalidFiles(t *testing.T) { const size = 1024 * 70 // 70kb b := make([]byte, size) diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go index 1d6e70f..a32de5a 100644 --- a/libgo/go/archive/zip/struct.go +++ b/libgo/go/archive/zip/struct.go @@ -28,6 +28,9 @@ const ( directoryHeaderLen = 46 // + filename + extra + comment directoryEndLen = 22 // + comment dataDescriptorLen = 12 + + // Constants for the first byte in CreatorVersion + creatorUnix = 3 ) type FileHeader struct { @@ -42,6 +45,7 @@ type FileHeader struct { CompressedSize uint32 UncompressedSize uint32 Extra []byte + ExternalAttrs uint32 // Meaning depends on CreatorVersion Comment string } @@ -89,3 +93,18 @@ func (h *FileHeader) Mtime_ns() int64 { t := msDosTimeToTime(h.ModifiedDate, h.ModifiedTime) return t.Seconds() * 1e9 } + +// Mode returns the permission and mode bits for the FileHeader. +// An error is returned in case the information is not available. +func (h *FileHeader) Mode() (mode uint32, err os.Error) { + if h.CreatorVersion>>8 == creatorUnix { + return h.ExternalAttrs >> 16, nil + } + return 0, os.NewError("file mode not available") +} + +// SetMode changes the permission and mode bits for the FileHeader. +func (h *FileHeader) SetMode(mode uint32) { + h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8 + h.ExternalAttrs = mode << 16 +} diff --git a/libgo/go/archive/zip/writer.go b/libgo/go/archive/zip/writer.go index 2065b06..3a6dc38 100644 --- a/libgo/go/archive/zip/writer.go +++ b/libgo/go/archive/zip/writer.go @@ -69,7 +69,7 @@ func (w *Writer) Close() (err os.Error) { write(w, uint16(len(h.Comment))) write(w, uint16(0)) // disk number start write(w, uint16(0)) // internal file attributes - write(w, uint32(0)) // external file attributes + write(w, h.ExternalAttrs) write(w, h.offset) writeBytes(w, []byte(h.Name)) writeBytes(w, h.Extra) @@ -115,7 +115,7 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, os.Error) { } fh.Flags |= 0x8 // we will write a data descriptor - fh.CreatorVersion = 0x14 + fh.CreatorVersion = fh.CreatorVersion&0xff00 | 0x14 fh.ReaderVersion = 0x14 fw := &fileWriter{ diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go index eb2a80c..b562f84 100644 --- a/libgo/go/archive/zip/writer_test.go +++ b/libgo/go/archive/zip/writer_test.go @@ -13,19 +13,45 @@ import ( // TODO(adg): a more sophisticated test suite -const testString = "Rabbits, guinea pigs, gophers, marsupial rats, and quolls." +type WriteTest struct { + Name string + Data []byte + Method uint16 + Mode uint32 +} + +var writeTests = []WriteTest{ + WriteTest{ + Name: "foo", + Data: []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."), + Method: Store, + }, + WriteTest{ + Name: "bar", + Data: nil, // large data set in the test + Method: Deflate, + Mode: 0x81ed, + }, +} func TestWriter(t *testing.T) { largeData := make([]byte, 1<<17) for i := range largeData { largeData[i] = byte(rand.Int()) } + writeTests[1].Data = largeData + defer func() { + writeTests[1].Data = nil + }() // write a zip file buf := new(bytes.Buffer) w := NewWriter(buf) - testCreate(t, w, "foo", []byte(testString), Store) - testCreate(t, w, "bar", largeData, Deflate) + + for _, wt := range writeTests { + testCreate(t, w, &wt) + } + if err := w.Close(); err != nil { t.Fatal(err) } @@ -35,26 +61,34 @@ func TestWriter(t *testing.T) { if err != nil { t.Fatal(err) } - testReadFile(t, r.File[0], []byte(testString)) - testReadFile(t, r.File[1], largeData) + for i, wt := range writeTests { + testReadFile(t, r.File[i], &wt) + } } -func testCreate(t *testing.T, w *Writer, name string, data []byte, method uint16) { +func testCreate(t *testing.T, w *Writer, wt *WriteTest) { header := &FileHeader{ - Name: name, - Method: method, + Name: wt.Name, + Method: wt.Method, + } + if wt.Mode != 0 { + header.SetMode(wt.Mode) } f, err := w.CreateHeader(header) if err != nil { t.Fatal(err) } - _, err = f.Write(data) + _, err = f.Write(wt.Data) if err != nil { t.Fatal(err) } } -func testReadFile(t *testing.T, f *File, data []byte) { +func testReadFile(t *testing.T, f *File, wt *WriteTest) { + if f.Name != wt.Name { + t.Fatalf("File name: got %q, want %q", f.Name, wt.Name) + } + testFileMode(t, f, wt.Mode) rc, err := f.Open() if err != nil { t.Fatal("opening:", err) @@ -67,7 +101,7 @@ func testReadFile(t *testing.T, f *File, data []byte) { if err != nil { t.Fatal("closing:", err) } - if !bytes.Equal(b, data) { - t.Errorf("File contents %q, want %q", b, data) + if !bytes.Equal(b, wt.Data) { + t.Errorf("File contents %q, want %q", b, wt.Data) } } |