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  }