summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Montag <pmontag@iseeme.com>2018-11-07 08:03:04 -0600
committerPaul Montag <pmontag@iseeme.com>2018-11-07 08:03:04 -0600
commita90e8ab8a5ab8b8bb484c51df7c29e721f31e184 (patch)
tree14b6b586ed620b367638ccc405e1284f8f26dd65
parent6993fe6ea4223dca30d0cae9fa0bd9a3cdfdb12d (diff)
Changed the byte encoding so we are no longer saving redundant data from pointers
-rw-r--r--template_impl.go119
1 files changed, 83 insertions, 36 deletions
diff --git a/template_impl.go b/template_impl.go
index b1b2382..174e893 100644
--- a/template_impl.go
+++ b/template_impl.go
@@ -3,7 +3,7 @@ package gofpdf
import (
"bytes"
"encoding/gob"
- "reflect"
+ "fmt"
)
/*
@@ -86,25 +86,60 @@ func (t *FpdfTpl) Templates() []Template {
return t.templates
}
+// returns the next layer of children images, it doesn't dig into
+// children of children. Applies template namespace to keys to ensure
+// no collisions. See UseTemplateScaled
+func (t *FpdfTpl) childrenImages() map[string]*ImageInfoType {
+ childrenImgs := make(map[string]*ImageInfoType)
+
+ for x := 0; x < len(t.templates); x++ {
+ imgs := t.templates[x].Images()
+ for key, val := range imgs {
+ name := sprintf("t%d-%s", t.templates[x].ID(), key)
+ childrenImgs[name] = val
+ }
+ }
+
+ return childrenImgs
+}
+
func (t *FpdfTpl) GobEncode() ([]byte, error) {
w := new(bytes.Buffer)
encoder := gob.NewEncoder(w)
- err := encoder.Encode(t.id)
+ err := encoder.Encode(t.templates)
+ childrenImgs := t.childrenImages()
+
if err == nil {
- err = encoder.Encode(t.corner)
+ encoder.Encode(len(t.images))
+ }
+
+ for key, img := range t.images {
+ // if the image has already been saved as a child, then
+ // save nil so we don't duplicate data
+ err = encoder.Encode(key)
+
+ if err != nil {
+ break
+ }
+
+ if _, ok := childrenImgs[key]; ok {
+ err = encoder.Encode(nil)
+ } else {
+ err = encoder.Encode(img)
+ }
}
if err == nil {
- err = encoder.Encode(t.size)
+ err = encoder.Encode(t.id)
}
if err == nil {
- err = encoder.Encode(t.bytes)
+ err = encoder.Encode(t.corner)
}
if err == nil {
- err = encoder.Encode(t.images)
+ err = encoder.Encode(t.size)
}
if err == nil {
- err = encoder.Encode(t.templates)
+ err = encoder.Encode(t.bytes)
}
return w.Bytes(), err
@@ -114,49 +149,61 @@ func (t *FpdfTpl) GobDecode(buf []byte) error {
r := bytes.NewBuffer(buf)
decoder := gob.NewDecoder(r)
- err := decoder.Decode(&t.id)
+ templates := make([]*FpdfTpl, 0)
+ err := decoder.Decode(&templates)
+ t.templates = make([]Template, len(templates))
+
+ for x := 0; x < len(templates); x++ {
+ t.templates[x] = templates[x]
+ }
+
+ var numImgs int
if err == nil {
- err = decoder.Decode(&t.corner)
+ err = decoder.Decode(&numImgs)
+ }
+ t.images = make(map[string]*ImageInfoType)
+ childrenImgs := t.childrenImages()
+
+ for x := 0; x < numImgs; x++ {
+ var key string
+ var img *ImageInfoType
+
+ if err == nil {
+ err = decoder.Decode(&key)
+ }
+
+ if err == nil {
+ err = decoder.Decode(&img)
+ }
+
+ if err == nil {
+ if img != nil {
+ t.images[key] = img
+ } else {
+ if _, ok := childrenImgs[key]; !ok {
+ err = fmt.Errorf("Encoded template is corrupt, could not find image %s", key)
+ } else {
+ t.images[key] = childrenImgs[key]
+ }
+ }
+ }
}
if err == nil {
- err = decoder.Decode(&t.size)
+ err = decoder.Decode(&t.id)
}
if err == nil {
- err = decoder.Decode(&t.bytes)
+ err = decoder.Decode(&t.corner)
}
if err == nil {
- err = decoder.Decode(&t.images)
+ err = decoder.Decode(&t.size)
}
if err == nil {
- templates := make([]*FpdfTpl, 0)
- err = decoder.Decode(&templates)
- t.templates = make([]Template, len(templates))
-
- for x := 0; x < len(templates); x++ {
- t.templates[x] = templates[x]
- }
+ err = decoder.Decode(&t.bytes)
}
- t.relinkPointers(t.images)
-
return err
}
-func (t *FpdfTpl) relinkPointers(images map[string]*ImageInfoType) {
- for gKey, _ := range images {
- for key, _ := range t.images {
- if reflect.DeepEqual(t.images[key], images[gKey]) {
- t.images[key] = images[gKey]
- }
- }
- }
-
- for x := 0; x < len(t.templates); x++ {
- innerT := t.templates[x].(*FpdfTpl)
- innerT.relinkPointers(t.images)
- }
-}
-
// Tpl is an Fpdf used for writing a template. It has most of the facilities of
// an Fpdf, but cannot add more pages. Tpl is used directly only during the
// limited time a template is writable.