go-hep.org/x/hep@v0.38.1/rio/compressor.go (about)

     1  // Copyright ©2015 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rio
     6  
     7  import (
     8  	"compress/flate"
     9  	"compress/gzip"
    10  	"compress/zlib"
    11  	"fmt"
    12  	"io"
    13  )
    14  
    15  // A Compressor takes data written to it and writes the compressed form of that
    16  // data to an underlying writer.
    17  type Compressor interface {
    18  	io.WriteCloser
    19  
    20  	// Reset clears the state of the Writer such that it is equivalent to its
    21  	// initial state, but instead writing to w.
    22  	Reset(w io.Writer) error
    23  
    24  	// Flush flushes the Writer to its underlying io.Writer.
    25  	Flush() error
    26  
    27  	// Kind returns the (de)compressor kind
    28  	//Kind() CompressorKind
    29  }
    30  
    31  // A Decompressor reads data from the underlying io.Reader and decompresses it.
    32  type Decompressor interface {
    33  	io.ReadCloser
    34  
    35  	// Reset clears the state of the Reader such that it is equivalent to its
    36  	// initial state, but instead reading from r.
    37  	Reset(r io.Reader) error
    38  
    39  	// Kind returns the (de)compressor kind
    40  	//Kind() CompressorKind
    41  }
    42  
    43  // Xpressor provides compressor and decompressor functions
    44  type Xpressor interface {
    45  	Inflate(r io.Reader) (Decompressor, error)
    46  	Deflate(w io.Writer, opts Options) (Compressor, error)
    47  }
    48  
    49  // CompressorKind names the various compressors
    50  type CompressorKind uint16
    51  
    52  // builtin compressor types
    53  const (
    54  	CompressDefault CompressorKind = iota
    55  	CompressNone
    56  	CompressFlate
    57  	CompressZlib
    58  	CompressGzip
    59  	CompressLZA
    60  	CompressLZO
    61  	CompressSnappy
    62  
    63  	CompressUser CompressorKind = 0xffff // keep last
    64  )
    65  
    66  func (ck CompressorKind) String() string {
    67  	switch ck {
    68  	case CompressUser:
    69  		return "user"
    70  	case CompressDefault:
    71  		return "default"
    72  	case CompressNone:
    73  		return "none"
    74  	case CompressFlate:
    75  		return "flate"
    76  	case CompressZlib:
    77  		return "zlib"
    78  	case CompressGzip:
    79  		return "gzip"
    80  	case CompressLZA:
    81  		return "lza"
    82  	case CompressLZO:
    83  		return "lzo"
    84  	case CompressSnappy:
    85  		return "snappy"
    86  	}
    87  	return "N/A"
    88  }
    89  
    90  // NewCompressor creates a Compressor writing to w, with compression level according to opts.
    91  func (ck CompressorKind) NewCompressor(w io.Writer, opts Options) (Compressor, error) {
    92  	x, ok := xcomprs[ck]
    93  	if !ok {
    94  		return nil, fmt.Errorf("rio: no compressor registered with %q (%v)", ck.String(), int(ck))
    95  	}
    96  	return x.Deflate(w, opts)
    97  }
    98  
    99  // NewDecompressor creates a Decompressor reading from r.
   100  func (ck CompressorKind) NewDecompressor(r io.Reader) (Decompressor, error) {
   101  	x, ok := xcomprs[ck]
   102  	if !ok {
   103  		return nil, fmt.Errorf("rio: no decompressor registered with %q (%v)", ck.String(), int(ck))
   104  	}
   105  	return x.Inflate(r)
   106  }
   107  
   108  type xpressor struct {
   109  	inflater func(r io.Reader) (Decompressor, error)
   110  	deflater func(w io.Writer, opts Options) (Compressor, error)
   111  }
   112  
   113  func (x xpressor) Inflate(r io.Reader) (Decompressor, error) {
   114  	return x.inflater(r)
   115  }
   116  
   117  func (x xpressor) Deflate(w io.Writer, o Options) (Compressor, error) {
   118  	return x.deflater(w, o)
   119  }
   120  
   121  type noneCompressor struct{}
   122  
   123  func (noneCompressor) Inflate(r io.Reader) (Decompressor, error) {
   124  	return &nopReadCloser{r}, nil
   125  }
   126  
   127  func (noneCompressor) Deflate(w io.Writer, o Options) (Compressor, error) {
   128  	return &nopWriteCloser{w}, nil
   129  }
   130  
   131  type nopWriteCloser struct {
   132  	io.Writer
   133  }
   134  
   135  func (nw *nopWriteCloser) Close() error {
   136  	return nil
   137  }
   138  
   139  func (nw *nopWriteCloser) Flush() error {
   140  	return nil
   141  }
   142  
   143  func (nw *nopWriteCloser) Reset(w io.Writer) error {
   144  	nw.Writer = w
   145  	return nil
   146  }
   147  
   148  type nopReadCloser struct {
   149  	io.Reader
   150  }
   151  
   152  func (nr *nopReadCloser) Close() error {
   153  	return nil
   154  }
   155  
   156  func (nr *nopReadCloser) Reset(r io.Reader) error {
   157  	nr.Reader = r
   158  	return nil
   159  }
   160  
   161  // flate ---
   162  
   163  type flateCompressor struct {
   164  	*flate.Writer
   165  }
   166  
   167  func newFlateCompressor(w io.Writer, o Options) (Compressor, error) {
   168  	cw, err := flate.NewWriter(w, o.CompressorLevel())
   169  	return &flateCompressor{cw}, err
   170  }
   171  
   172  func (cw *flateCompressor) Reset(w io.Writer) error {
   173  	cw.Writer.Reset(w)
   174  	return nil
   175  }
   176  
   177  type flateDecompressor struct {
   178  	io.ReadCloser
   179  }
   180  
   181  func newFlateDecompressor(r io.Reader) (Decompressor, error) {
   182  	xr := flate.NewReader(r)
   183  	return &flateDecompressor{xr}, nil
   184  }
   185  
   186  func (xr *flateDecompressor) Reset(r io.Reader) error {
   187  	return xr.ReadCloser.(flate.Resetter).Reset(r, nil)
   188  }
   189  
   190  // zlib ---
   191  
   192  type zlibCompressor struct {
   193  	*zlib.Writer
   194  }
   195  
   196  func newZlibCompressor(w io.Writer, o Options) (Compressor, error) {
   197  	cw, err := zlib.NewWriterLevel(w, o.CompressorLevel())
   198  	return &zlibCompressor{cw}, err
   199  }
   200  
   201  func (cw *zlibCompressor) Reset(w io.Writer) error {
   202  	cw.Writer.Reset(w)
   203  	return nil
   204  }
   205  
   206  type zlibDecompressor struct {
   207  	io.ReadCloser
   208  }
   209  
   210  func newZlibDecompressor(r io.Reader) (Decompressor, error) {
   211  	xr, err := zlib.NewReader(r)
   212  	return &zlibDecompressor{xr}, err
   213  }
   214  
   215  func (xr *zlibDecompressor) Reset(r io.Reader) error {
   216  	return xr.ReadCloser.(zlib.Resetter).Reset(r, nil)
   217  }
   218  
   219  // gzip ---
   220  
   221  type gzipCompressor struct {
   222  	*gzip.Writer
   223  }
   224  
   225  func newGzipCompressor(w io.Writer, o Options) (Compressor, error) {
   226  	cw, err := gzip.NewWriterLevel(w, o.CompressorLevel())
   227  	return &gzipCompressor{cw}, err
   228  }
   229  
   230  func (cw *gzipCompressor) Reset(w io.Writer) error {
   231  	cw.Writer.Reset(w)
   232  	return nil
   233  }
   234  
   235  type gzipDecompressor struct {
   236  	*gzip.Reader
   237  }
   238  
   239  func newGzipDecompressor(r io.Reader) (Decompressor, error) {
   240  	xr, err := gzip.NewReader(r)
   241  	return &gzipDecompressor{xr}, err
   242  }
   243  
   244  // RegisterCompressor registers a compressor/decompressor.
   245  // It silently replaces the compressor/decompressor if one was already registered.
   246  func RegisterCompressor(kind CompressorKind, x Xpressor) {
   247  	xcomprs[kind] = x
   248  }
   249  
   250  var xcomprs map[CompressorKind]Xpressor
   251  
   252  func init() {
   253  
   254  	xcomprs = map[CompressorKind]Xpressor{
   255  
   256  		CompressNone: noneCompressor{},
   257  
   258  		CompressFlate: xpressor{
   259  			inflater: newFlateDecompressor,
   260  			deflater: newFlateCompressor,
   261  		},
   262  
   263  		CompressZlib: xpressor{
   264  			inflater: newZlibDecompressor,
   265  			deflater: newZlibCompressor,
   266  		},
   267  
   268  		CompressGzip: xpressor{
   269  			inflater: newGzipDecompressor,
   270  			deflater: newGzipCompressor,
   271  		},
   272  	}
   273  
   274  	xcomprs[CompressDefault] = xcomprs[CompressZlib]
   275  }