...
1 package lz4
2
3 import (
4 "fmt"
5 "reflect"
6 "runtime"
7
8 "github.com/pierrec/lz4/v4/internal/lz4block"
9 "github.com/pierrec/lz4/v4/internal/lz4errors"
10 )
11
12
13
14 type (
15 applier interface {
16 Apply(...Option) error
17 private()
18 }
19
20 Option func(applier) error
21 )
22
23
24 func (o Option) String() string {
25 return o(nil).Error()
26 }
27
28
29 var (
30 DefaultBlockSizeOption = BlockSizeOption(Block4Mb)
31 DefaultChecksumOption = ChecksumOption(true)
32 DefaultConcurrency = ConcurrencyOption(1)
33 defaultOnBlockDone = OnBlockDoneOption(nil)
34 )
35
36 const (
37 Block64Kb BlockSize = 1 << (16 + iota*2)
38 Block256Kb
39 Block1Mb
40 Block4Mb
41 )
42
43
44 type BlockSize uint32
45
46
47 func BlockSizeOption(size BlockSize) Option {
48 return func(a applier) error {
49 switch w := a.(type) {
50 case nil:
51 s := fmt.Sprintf("BlockSizeOption(%s)", size)
52 return lz4errors.Error(s)
53 case *Writer:
54 size := uint32(size)
55 if !lz4block.IsValid(size) {
56 return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidBlockSize, size)
57 }
58 w.frame.Descriptor.Flags.BlockSizeIndexSet(lz4block.Index(size))
59 return nil
60 }
61 return lz4errors.ErrOptionNotApplicable
62 }
63 }
64
65
66 func BlockChecksumOption(flag bool) Option {
67 return func(a applier) error {
68 switch w := a.(type) {
69 case nil:
70 s := fmt.Sprintf("BlockChecksumOption(%v)", flag)
71 return lz4errors.Error(s)
72 case *Writer:
73 w.frame.Descriptor.Flags.BlockChecksumSet(flag)
74 return nil
75 }
76 return lz4errors.ErrOptionNotApplicable
77 }
78 }
79
80
81 func ChecksumOption(flag bool) Option {
82 return func(a applier) error {
83 switch w := a.(type) {
84 case nil:
85 s := fmt.Sprintf("ChecksumOption(%v)", flag)
86 return lz4errors.Error(s)
87 case *Writer:
88 w.frame.Descriptor.Flags.ContentChecksumSet(flag)
89 return nil
90 }
91 return lz4errors.ErrOptionNotApplicable
92 }
93 }
94
95
96
97 func SizeOption(size uint64) Option {
98 return func(a applier) error {
99 switch w := a.(type) {
100 case nil:
101 s := fmt.Sprintf("SizeOption(%d)", size)
102 return lz4errors.Error(s)
103 case *Writer:
104 w.frame.Descriptor.Flags.SizeSet(size > 0)
105 w.frame.Descriptor.ContentSize = size
106 return nil
107 }
108 return lz4errors.ErrOptionNotApplicable
109 }
110 }
111
112
113
114 func ConcurrencyOption(n int) Option {
115 if n <= 0 {
116 n = runtime.GOMAXPROCS(0)
117 }
118 return func(a applier) error {
119 switch rw := a.(type) {
120 case nil:
121 s := fmt.Sprintf("ConcurrencyOption(%d)", n)
122 return lz4errors.Error(s)
123 case *Writer:
124 rw.num = n
125 return nil
126 case *Reader:
127 rw.num = n
128 return nil
129 }
130 return lz4errors.ErrOptionNotApplicable
131 }
132 }
133
134
135 type CompressionLevel uint32
136
137 const (
138 Fast CompressionLevel = 0
139 Level1 CompressionLevel = 1 << (8 + iota)
140 Level2
141 Level3
142 Level4
143 Level5
144 Level6
145 Level7
146 Level8
147 Level9
148 )
149
150
151 func CompressionLevelOption(level CompressionLevel) Option {
152 return func(a applier) error {
153 switch w := a.(type) {
154 case nil:
155 s := fmt.Sprintf("CompressionLevelOption(%s)", level)
156 return lz4errors.Error(s)
157 case *Writer:
158 switch level {
159 case Fast, Level1, Level2, Level3, Level4, Level5, Level6, Level7, Level8, Level9:
160 default:
161 return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidCompressionLevel, level)
162 }
163 w.level = lz4block.CompressionLevel(level)
164 return nil
165 }
166 return lz4errors.ErrOptionNotApplicable
167 }
168 }
169
170 func onBlockDone(int) {}
171
172
173
174 func OnBlockDoneOption(handler func(size int)) Option {
175 if handler == nil {
176 handler = onBlockDone
177 }
178 return func(a applier) error {
179 switch rw := a.(type) {
180 case nil:
181 s := fmt.Sprintf("OnBlockDoneOption(%s)", reflect.TypeOf(handler).String())
182 return lz4errors.Error(s)
183 case *Writer:
184 rw.handler = handler
185 return nil
186 case *Reader:
187 rw.handler = handler
188 return nil
189 }
190 return lz4errors.ErrOptionNotApplicable
191 }
192 }
193
194
195
196
197
198
199
200
201
202 func LegacyOption(legacy bool) Option {
203 return func(a applier) error {
204 switch rw := a.(type) {
205 case nil:
206 s := fmt.Sprintf("LegacyOption(%v)", legacy)
207 return lz4errors.Error(s)
208 case *Writer:
209 rw.legacy = legacy
210 return nil
211 }
212 return lz4errors.ErrOptionNotApplicable
213 }
214 }
215
View as plain text