decoder_options.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2019+ Klaus Post. All rights reserved.
  2. // License information can be found in the LICENSE file.
  3. // Based on work by Yann Collet, released under BSD License.
  4. package zstd
  5. import (
  6. "errors"
  7. "runtime"
  8. )
  9. // DOption is an option for creating a decoder.
  10. type DOption func(*decoderOptions) error
  11. // options retains accumulated state of multiple options.
  12. type decoderOptions struct {
  13. lowMem bool
  14. concurrent int
  15. maxDecodedSize uint64
  16. dicts []dict
  17. }
  18. func (o *decoderOptions) setDefault() {
  19. *o = decoderOptions{
  20. // use less ram: true for now, but may change.
  21. lowMem: true,
  22. concurrent: runtime.GOMAXPROCS(0),
  23. }
  24. o.maxDecodedSize = 1 << 63
  25. }
  26. // WithDecoderLowmem will set whether to use a lower amount of memory,
  27. // but possibly have to allocate more while running.
  28. func WithDecoderLowmem(b bool) DOption {
  29. return func(o *decoderOptions) error { o.lowMem = b; return nil }
  30. }
  31. // WithDecoderConcurrency will set the concurrency,
  32. // meaning the maximum number of decoders to run concurrently.
  33. // The value supplied must be at least 1.
  34. // By default this will be set to GOMAXPROCS.
  35. func WithDecoderConcurrency(n int) DOption {
  36. return func(o *decoderOptions) error {
  37. if n <= 0 {
  38. return errors.New("concurrency must be at least 1")
  39. }
  40. o.concurrent = n
  41. return nil
  42. }
  43. }
  44. // WithDecoderMaxMemory allows to set a maximum decoded size for in-memory
  45. // non-streaming operations or maximum window size for streaming operations.
  46. // This can be used to control memory usage of potentially hostile content.
  47. // For streaming operations, the maximum window size is capped at 1<<30 bytes.
  48. // Maximum and default is 1 << 63 bytes.
  49. func WithDecoderMaxMemory(n uint64) DOption {
  50. return func(o *decoderOptions) error {
  51. if n == 0 {
  52. return errors.New("WithDecoderMaxMemory must be at least 1")
  53. }
  54. if n > 1<<63 {
  55. return errors.New("WithDecoderMaxmemory must be less than 1 << 63")
  56. }
  57. o.maxDecodedSize = n
  58. return nil
  59. }
  60. }
  61. // WithDecoderDicts allows to register one or more dictionaries for the decoder.
  62. // If several dictionaries with the same ID is provided the last one will be used.
  63. func WithDecoderDicts(dicts ...[]byte) DOption {
  64. return func(o *decoderOptions) error {
  65. for _, b := range dicts {
  66. d, err := loadDict(b)
  67. if err != nil {
  68. return err
  69. }
  70. o.dicts = append(o.dicts, *d)
  71. }
  72. return nil
  73. }
  74. }