codeberg.org/go-pdf/fpdf@v0.11.1/xcompr.go (about) 1 // Copyright ©2021 The go-pdf Authors. All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package fpdf 6 7 import ( 8 "bytes" 9 "compress/zlib" 10 "fmt" 11 "sync" 12 ) 13 14 var xmem = xmempool{ 15 Pool: sync.Pool{ 16 New: func() interface{} { 17 var m membuffer 18 return &m 19 }, 20 }, 21 } 22 23 type xmempool struct{ sync.Pool } 24 25 func (pool *xmempool) compress(data []byte) *membuffer { 26 mem := pool.Get().(*membuffer) 27 buf := &mem.buf 28 buf.Grow(len(data)) 29 30 zw, err := zlib.NewWriterLevel(buf, zlib.BestSpeed) 31 if err != nil { 32 panic(fmt.Errorf("could not create zlib writer: %w", err)) 33 } 34 _, err = zw.Write(data) 35 if err != nil { 36 panic(fmt.Errorf("could not zlib-compress slice: %w", err)) 37 } 38 39 err = zw.Close() 40 if err != nil { 41 panic(fmt.Errorf("could not close zlib writer: %w", err)) 42 } 43 return mem 44 } 45 46 func (pool *xmempool) uncompress(data []byte) (*membuffer, error) { 47 zr, err := zlib.NewReader(bytes.NewReader(data)) 48 if err != nil { 49 return nil, err 50 } 51 52 mem := pool.Get().(*membuffer) 53 mem.buf.Reset() 54 55 _, err = mem.buf.ReadFrom(zr) 56 if err != nil { 57 mem.release() 58 return nil, err 59 } 60 61 return mem, nil 62 } 63 64 type membuffer struct { 65 buf bytes.Buffer 66 } 67 68 func (mem *membuffer) bytes() []byte { return mem.buf.Bytes() } 69 func (mem *membuffer) release() { 70 mem.buf.Reset() 71 xmem.Put(mem) 72 } 73 74 func (mem *membuffer) copy() []byte { 75 src := mem.bytes() 76 dst := make([]byte, len(src)) 77 copy(dst, src) 78 return dst 79 }