-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfiles.go
102 lines (92 loc) · 2.64 KB
/
files.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package model
import (
"crypto/md5"
"encoding/hex"
"time"
)
// FileSpec is a File Specification Dictionary.
// In PDF, it may be found as a simple File Specification String
// which should be stored in the `UF` field.
type FileSpec struct {
UF string // optional
EF *EmbeddedFileStream
Desc string // optional
}
// returns the dictionnay, with a nil content `pdf` is used
// to create the EmbeddedFileStream object.
func (f *FileSpec) pdfContent(pdf pdfWriter, ref Reference) (StreamHeader, string, []byte) {
b := newBuffer()
b.fmt("<</Type/Filespec")
if f.UF != "" {
b.fmt("/UF %s /F %s", pdf.EncodeString(f.UF, TextString, ref),
pdf.EncodeString(f.UF, ByteString, ref))
}
if f.EF != nil {
s, _, by := f.EF.pdfContent(pdf, ref)
ref := pdf.addStream(s, by)
b.fmt("/EF <</F %s>>", ref)
}
if f.Desc != "" {
b.fmt("/Desc %s", pdf.EncodeString(f.Desc, TextString, ref))
}
b.fmt(">>")
return StreamHeader{}, b.String(), nil
}
func (f *FileSpec) clone(cache cloneCache) Referenceable {
if f == nil {
return f
}
out := *f
out.EF = cache.checkOrClone(f.EF).(*EmbeddedFileStream)
return &out
}
type EmbeddedFileParams struct {
CreationDate time.Time // optional
ModDate time.Time // optional
Size int // optional
CheckSum string // optional, must be hex16 encoded
}
// SetChecksumAndSize compute the size and the checksum of the `content`,
// which must be the original (not encoded) data.
func (f *EmbeddedFileParams) SetChecksumAndSize(content []byte) {
f.Size = len(content)
tmp := md5.Sum(content)
f.CheckSum = hex.EncodeToString(tmp[:])
}
func (params EmbeddedFileParams) pdfString(pdf pdfWriter, ref Reference) string {
b := newBuffer()
b.WriteString("<<")
if params.Size != 0 {
b.fmt("/Size %d", params.Size)
}
if !params.CreationDate.IsZero() {
b.fmt("/CreationDate %s", pdf.dateString(params.CreationDate, ref))
}
if !params.ModDate.IsZero() {
b.fmt("/ModDate %s", pdf.dateString(params.ModDate, ref))
}
if params.CheckSum != "" {
b.fmt("/CheckSum <%s>", params.CheckSum)
}
b.fmt(">>")
return b.String()
}
type EmbeddedFileStream struct {
Stream
Params EmbeddedFileParams // optional
}
func (emb *EmbeddedFileStream) pdfContent(pdf pdfWriter, ref Reference) (StreamHeader, string, []byte) {
args := emb.PDFCommonFields(true)
args.Fields["Type"] = "/EmbeddedFile"
args.Fields["Params"] = emb.Params.pdfString(pdf, ref)
return args, "", emb.Content
}
// clone returns a deep copy, with concrete type `*EmbeddedFileStream`
func (emb *EmbeddedFileStream) clone(cloneCache) Referenceable {
if emb == nil {
return emb
}
out := *emb // shallow copy
out.Stream = emb.Stream.Clone()
return &out
}