]> Cypherpunks repositories - gostls13.git/commitdiff
archive/zip: use smarter putUintXX functions to hide offsets
authorAndrew Gerrand <adg@golang.org>
Mon, 27 Feb 2012 06:37:59 +0000 (17:37 +1100)
committerAndrew Gerrand <adg@golang.org>
Mon, 27 Feb 2012 06:37:59 +0000 (17:37 +1100)
R=bradfitz, r, dsymonds, kyle
CC=golang-dev
https://golang.org/cl/5701055

src/pkg/archive/zip/reader_test.go
src/pkg/archive/zip/writer.go

index ea9e0020db4a6639961bc7a415dc3b2a552c1c2b..066a61580c56d6ae8ccca5bc87662d34d5130edf 100644 (file)
@@ -165,7 +165,7 @@ func readTestZip(t *testing.T, zt ZipTest) {
                t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
        }
        if len(z.File) != len(zt.File) {
-               t.Errorf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
+               t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
        }
 
        // test read of each file
index 8404e3f09a07ede8af75a03328bac59e033831ef..476407dfd279ec03a06cd5ca982b226db87d5c6b 100644 (file)
@@ -51,24 +51,25 @@ func (w *Writer) Close() error {
        // write central directory
        start := w.cw.count
        for _, h := range w.dir {
-               var b [directoryHeaderLen]byte
-               putUint32(b[:], uint32(directoryHeaderSignature))
-               putUint16(b[4:], h.CreatorVersion)
-               putUint16(b[6:], h.ReaderVersion)
-               putUint16(b[8:], h.Flags)
-               putUint16(b[10:], h.Method)
-               putUint16(b[12:], h.ModifiedTime)
-               putUint16(b[14:], h.ModifiedDate)
-               putUint32(b[16:], h.CRC32)
-               putUint32(b[20:], h.CompressedSize)
-               putUint32(b[24:], h.UncompressedSize)
-               putUint16(b[28:], uint16(len(h.Name)))
-               putUint16(b[30:], uint16(len(h.Extra)))
-               putUint16(b[32:], uint16(len(h.Comment)))
-               // skip two uint16's, disk number start and internal file attributes
-               putUint32(b[38:], h.ExternalAttrs)
-               putUint32(b[42:], h.offset)
-               if _, err := w.cw.Write(b[:]); err != nil {
+               var buf [directoryHeaderLen]byte
+               b := writeBuf(buf[:])
+               b.uint32(uint32(directoryHeaderSignature))
+               b.uint16(h.CreatorVersion)
+               b.uint16(h.ReaderVersion)
+               b.uint16(h.Flags)
+               b.uint16(h.Method)
+               b.uint16(h.ModifiedTime)
+               b.uint16(h.ModifiedDate)
+               b.uint32(h.CRC32)
+               b.uint32(h.CompressedSize)
+               b.uint32(h.UncompressedSize)
+               b.uint16(uint16(len(h.Name)))
+               b.uint16(uint16(len(h.Extra)))
+               b.uint16(uint16(len(h.Comment)))
+               b = b[4:] // skip disk number start and internal file attr (2x uint16)
+               b.uint32(h.ExternalAttrs)
+               b.uint32(h.offset)
+               if _, err := w.cw.Write(buf[:]); err != nil {
                        return err
                }
                if _, err := io.WriteString(w.cw, h.Name); err != nil {
@@ -84,16 +85,16 @@ func (w *Writer) Close() error {
        end := w.cw.count
 
        // write end record
-       var b [directoryEndLen]byte
-       putUint32(b[:], uint32(directoryEndSignature))
-       putUint16(b[4:], uint16(0))           // disk number
-       putUint16(b[6:], uint16(0))           // disk number where directory starts
-       putUint16(b[8:], uint16(len(w.dir)))  // number of entries this disk
-       putUint16(b[10:], uint16(len(w.dir))) // number of entries total
-       putUint32(b[12:], uint32(end-start))  // size of directory
-       putUint32(b[16:], uint32(start))      // start of directory
+       var buf [directoryEndLen]byte
+       b := writeBuf(buf[:])
+       b.uint32(uint32(directoryEndSignature))
+       b = b[4:]                     // skip over disk number and first disk number (2x uint16)
+       b.uint16(uint16(len(w.dir)))  // number of entries this disk
+       b.uint16(uint16(len(w.dir)))  // number of entries total
+       b.uint32(uint32(end - start)) // size of directory
+       b.uint32(uint32(start))       // start of directory
        // skipped size of comment (always zero)
-       if _, err := w.cw.Write(b[:]); err != nil {
+       if _, err := w.cw.Write(buf[:]); err != nil {
                return err
        }
 
@@ -163,19 +164,20 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
 }
 
 func writeHeader(w io.Writer, h *FileHeader) error {
-       var b [fileHeaderLen]byte
-       putUint32(b[:], uint32(fileHeaderSignature))
-       putUint16(b[4:], h.ReaderVersion)
-       putUint16(b[6:], h.Flags)
-       putUint16(b[8:], h.Method)
-       putUint16(b[10:], h.ModifiedTime)
-       putUint16(b[12:], h.ModifiedDate)
-       putUint32(b[14:], h.CRC32)
-       putUint32(b[18:], h.CompressedSize)
-       putUint32(b[22:], h.UncompressedSize)
-       putUint16(b[26:], uint16(len(h.Name)))
-       putUint16(b[28:], uint16(len(h.Extra)))
-       if _, err := w.Write(b[:]); err != nil {
+       var buf [fileHeaderLen]byte
+       b := writeBuf(buf[:])
+       b.uint32(uint32(fileHeaderSignature))
+       b.uint16(h.ReaderVersion)
+       b.uint16(h.Flags)
+       b.uint16(h.Method)
+       b.uint16(h.ModifiedTime)
+       b.uint16(h.ModifiedDate)
+       b.uint32(h.CRC32)
+       b.uint32(h.CompressedSize)
+       b.uint32(h.UncompressedSize)
+       b.uint16(uint16(len(h.Name)))
+       b.uint16(uint16(len(h.Extra)))
+       if _, err := w.Write(buf[:]); err != nil {
                return err
        }
        if _, err := io.WriteString(w, h.Name); err != nil {
@@ -219,11 +221,12 @@ func (w *fileWriter) close() error {
        fh.UncompressedSize = uint32(w.rawCount.count)
 
        // write data descriptor
-       var b [dataDescriptorLen]byte
-       putUint32(b[:], fh.CRC32)
-       putUint32(b[4:], fh.CompressedSize)
-       putUint32(b[8:], fh.UncompressedSize)
-       _, err := w.zipw.Write(b[:])
+       var buf [dataDescriptorLen]byte
+       b := writeBuf(buf[:])
+       b.uint32(fh.CRC32)
+       b.uint32(fh.CompressedSize)
+       b.uint32(fh.UncompressedSize)
+       _, err := w.zipw.Write(buf[:])
        return err
 }
 
@@ -246,17 +249,21 @@ func (w nopCloser) Close() error {
        return nil
 }
 
-// We use these putUintXX functions instead of encoding/binary's Write to avoid
-// reflection. It's easy enough, anyway.
+// We use this helper instead of encoding/binary's Write to avoid reflection.
+// It's easy enough, anyway.
 
-func putUint16(b []byte, v uint16) {
-       b[0] = byte(v)
-       b[1] = byte(v >> 8)
+type writeBuf []byte
+
+func (b *writeBuf) uint16(v uint16) {
+       (*b)[0] = byte(v)
+       (*b)[1] = byte(v >> 8)
+       *b = (*b)[2:]
 }
 
-func putUint32(b []byte, v uint32) {
-       b[0] = byte(v)
-       b[1] = byte(v >> 8)
-       b[2] = byte(v >> 16)
-       b[3] = byte(v >> 24)
+func (b *writeBuf) uint32(v uint32) {
+       (*b)[0] = byte(v)
+       (*b)[1] = byte(v >> 8)
+       (*b)[2] = byte(v >> 16)
+       (*b)[3] = byte(v >> 24)
+       *b = (*b)[4:]
 }