Skip to content

Commit c770491

Browse files
authored
Merge pull request #16 from qmuntal/newwriter-reader
Add NewWriterFromReader
2 parents f472a81 + 8e9f030 commit c770491

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

example_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,34 @@ func ExampleReader() {
5959
fmt.Println()
6060
}
6161
}
62+
63+
func ExampleNewWriterFromReader() {
64+
r, err := opc.OpenReader("testdata/component.3mf")
65+
if err != nil {
66+
log.Fatal(err)
67+
}
68+
defer r.Close()
69+
70+
buf := new(bytes.Buffer)
71+
w, err := opc.NewWriterFromReader(buf, r.Reader)
72+
if err != nil {
73+
log.Fatal(err)
74+
}
75+
name := opc.NormalizePartName("docs\\readme.txt")
76+
part, err := w.Create(name, "text/plain")
77+
if err != nil {
78+
log.Fatal(err)
79+
}
80+
81+
// Write content to the part.
82+
_, err = part.Write([]byte("This archive contains some text files."))
83+
if err != nil {
84+
log.Fatal(err)
85+
}
86+
87+
// Make sure to check the error on Close.
88+
if err := w.Close(); err != nil {
89+
log.Fatal(err)
90+
}
91+
}
92+

writer.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Writer struct {
3535
last *Part
3636
}
3737

38-
// NewWriter returns a new Writer writing an OPC file to w.
38+
// NewWriter returns a new Writer writing an OPC package to w.
3939
func NewWriter(w io.Writer) *Writer {
4040
return &Writer{p: &pkg{
4141
parts: make(map[string]*Part, 0),
@@ -49,6 +49,35 @@ func NewWriter(w io.Writer) *Writer {
4949
}, w: zip.NewWriter(w)}
5050
}
5151

52+
// NewWriterFromReader returns a new Writer writing an OPC package to w
53+
// and with its content initialized with r.
54+
// Parts comming from r cannot be modified but new parts can be appended
55+
// and package core properties and relationships can be updated.
56+
func NewWriterFromReader(w io.Writer, r *Reader) (*Writer, error) {
57+
ow := NewWriter(w)
58+
for _, p := range r.Files {
59+
pw, err := ow.CreatePart(p.Part, CompressionNormal)
60+
if err != nil {
61+
return nil, err
62+
}
63+
rc, err := p.Open()
64+
if err != nil {
65+
return nil, err
66+
}
67+
_, err = io.Copy(pw, rc)
68+
rc.Close()
69+
if err != nil {
70+
return nil, err
71+
}
72+
}
73+
ow.Properties = r.Properties
74+
ow.Relationships = make([]*Relationship, len(r.Relationships))
75+
for i, rel := range r.Relationships {
76+
ow.Relationships[i] = &(*rel)
77+
}
78+
return ow, nil
79+
}
80+
5281
// Flush flushes any buffered data to the underlying writer.
5382
// Part metadata, relationships, content types and other OPC related files won't be flushed.
5483
// Calling Flush is not normally necessary; calling Close is sufficient.

writer_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,24 @@ func TestWriter_createLastPartRelationships(t *testing.T) {
194194
})
195195
}
196196
}
197+
198+
func TestNewWriterFromReader(t *testing.T) {
199+
r, err := OpenReader("testdata/office.docx")
200+
if err != nil {
201+
t.Fatalf("failed to open test file: %v", err)
202+
}
203+
var buf bytes.Buffer
204+
w, err := NewWriterFromReader(&buf, r.Reader)
205+
if err != nil {
206+
t.Fatalf("NewWriterFromReader() error: %v", err)
207+
}
208+
if w.Properties != r.Properties {
209+
t.Error("NewWriterFromReader() haven't copied core properties")
210+
}
211+
if len(w.Relationships) != len(r.Relationships) {
212+
t.Error("NewWriterFromReader() haven't copied package relationships")
213+
}
214+
if err = w.Close(); err != nil {
215+
t.Errorf("NewWriterFromReader() created package that cannot be closed: %v", err)
216+
}
217+
}

0 commit comments

Comments
 (0)