1
0
mirror of https://github.com/golang/go synced 2024-11-19 02:54:42 -07:00

archive/zip: add NewWriterWithOptions

When appending zip data to existing data such as a binary file the
zip headers must use the correct offset. NewWriterWithOptions
allows creating a Writer that uses the provided offset in the zip
headers.

Fixes #8669

Change-Id: I6ec64f1e816cc57b6fc8bb9e8a0918e586fc56b0
Reviewed-on: https://go-review.googlesource.com/2978
Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
Geert-Johan Riemer 2015-01-19 14:39:33 +01:00 committed by Andrew Gerrand
parent 0d6a0d6c3f
commit de573f8748
2 changed files with 55 additions and 1 deletions

View File

@ -29,9 +29,29 @@ type header struct {
offset uint64
}
// WriterOptions contains configuration options for a zip.Writer.
type WriterOptions struct {
// Offset modifies the initial zip offset.
// This is useful when the zip is appended to other data such as a binary executable.
Offset int64
}
// NewWriter returns a new Writer writing a zip file to w.
func NewWriter(w io.Writer) *Writer {
return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
return NewWriterWithOptions(w, nil)
}
// NewWriterWithOptions returns a new Writer writing a zip file to w and uses the given options.
func NewWriterWithOptions(w io.Writer, options *WriterOptions) *Writer {
writer := &Writer{
cw: &countWriter{
w: bufio.NewWriter(w),
},
}
if options != nil {
writer.cw.count = options.Offset
}
return writer
}
// Flush flushes any buffered data to the underlying writer.

View File

@ -87,6 +87,40 @@ func TestWriter(t *testing.T) {
}
}
func TestWriterOffsetOption(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)
existingData := []byte{1, 2, 3, 1, 2, 3, 1, 2, 3}
n, _ := buf.Write(existingData)
w := NewWriterWithOptions(buf, &WriterOptions{Offset: int64(n)})
for _, wt := range writeTests {
testCreate(t, w, &wt)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
// read it back
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
t.Fatal(err)
}
for i, wt := range writeTests {
testReadFile(t, r.File[i], &wt)
}
}
func TestWriterFlush(t *testing.T) {
var buf bytes.Buffer
w := NewWriter(struct{ io.Writer }{&buf})