Dan Willemsen | 3bf1a08 | 2016-08-03 00:35:25 -0700 | [diff] [blame^] | 1 | // Copyright 2016 Google Inc. All rights reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package zip |
| 16 | |
| 17 | import ( |
| 18 | "io" |
| 19 | ) |
| 20 | |
| 21 | func (w *Writer) CopyFrom(orig *File, newName string) error { |
| 22 | if w.last != nil && !w.last.closed { |
| 23 | if err := w.last.close(); err != nil { |
| 24 | return err |
| 25 | } |
| 26 | w.last = nil |
| 27 | } |
| 28 | |
| 29 | fileHeader := orig.FileHeader |
| 30 | fileHeader.Name = newName |
| 31 | fh := &fileHeader |
| 32 | fh.Flags |= 0x8 |
| 33 | |
| 34 | h := &header{ |
| 35 | FileHeader: fh, |
| 36 | offset: uint64(w.cw.count), |
| 37 | } |
| 38 | w.dir = append(w.dir, h) |
| 39 | |
| 40 | if err := writeHeader(w.cw, fh); err != nil { |
| 41 | return err |
| 42 | } |
| 43 | |
| 44 | // Copy data |
| 45 | dataOffset, err := orig.DataOffset() |
| 46 | if err != nil { |
| 47 | return err |
| 48 | } |
| 49 | io.Copy(w.cw, io.NewSectionReader(orig.zipr, dataOffset, int64(orig.CompressedSize64))) |
| 50 | |
| 51 | // Write data descriptor. |
| 52 | var buf []byte |
| 53 | if fh.isZip64() { |
| 54 | buf = make([]byte, dataDescriptor64Len) |
| 55 | } else { |
| 56 | buf = make([]byte, dataDescriptorLen) |
| 57 | } |
| 58 | b := writeBuf(buf) |
| 59 | b.uint32(dataDescriptorSignature) |
| 60 | b.uint32(fh.CRC32) |
| 61 | if fh.isZip64() { |
| 62 | b.uint64(fh.CompressedSize64) |
| 63 | b.uint64(fh.UncompressedSize64) |
| 64 | } else { |
| 65 | b.uint32(fh.CompressedSize) |
| 66 | b.uint32(fh.UncompressedSize) |
| 67 | } |
| 68 | _, err = w.cw.Write(buf) |
| 69 | return err |
| 70 | } |