1pub use alloc::Allocator;
2
3#[cfg(feature = "std")]
4use alloc_stdlib::StandardAlloc;
5
6use super::cluster::HistogramPair;
7use super::command::Command;
8use super::entropy_encode::HuffmanTree;
9use super::hash_to_binary_tree::ZopfliNode;
10use super::histogram::{ContextType, HistogramCommand, HistogramDistance, HistogramLiteral};
11use super::interface::StaticCommand;
12use super::util::floatX;
13use super::{s16, v8, PDF};
14pub trait BrotliAlloc:
34 Allocator<u8>
35 + Allocator<u16>
36 + Allocator<i32>
37 + Allocator<u32>
38 + Allocator<u64>
39 + Allocator<Command>
40 + Allocator<super::util::floatX>
41 + Allocator<v8>
42 + Allocator<s16>
43 + Allocator<PDF>
44 + Allocator<StaticCommand>
45 + Allocator<HistogramLiteral>
46 + Allocator<HistogramCommand>
47 + Allocator<HistogramDistance>
48 + Allocator<HistogramPair>
49 + Allocator<ContextType>
50 + Allocator<HuffmanTree>
51 + Allocator<ZopfliNode>
52{
53}
54
55#[cfg(feature = "std")]
56impl BrotliAlloc for StandardAlloc {}
57
58pub struct CombiningAllocator<
59 AllocU8: Allocator<u8>,
60 AllocU16: Allocator<u16>,
61 AllocI32: Allocator<i32>,
62 AllocU32: Allocator<u32>,
63 AllocU64: Allocator<u64>,
64 AllocCommand: Allocator<Command>,
65 AllocFloatX: Allocator<floatX>,
66 AllocV8: Allocator<v8>,
67 AllocS16: Allocator<s16>,
68 AllocPDF: Allocator<PDF>,
69 AllocStaticCommand: Allocator<StaticCommand>,
70 AllocHistogramLiteral: Allocator<HistogramLiteral>,
71 AllocHistogramCommand: Allocator<HistogramCommand>,
72 AllocHistogramDistance: Allocator<HistogramDistance>,
73 AllocHistogramPair: Allocator<HistogramPair>,
74 AllocContextType: Allocator<ContextType>,
75 AllocHuffmanTree: Allocator<HuffmanTree>,
76 AllocZopfliNode: Allocator<ZopfliNode>,
77> {
78 alloc_u8: AllocU8,
79 alloc_u16: AllocU16,
80 alloc_i32: AllocI32,
81 alloc_u32: AllocU32,
82 alloc_u64: AllocU64,
83 alloc_c: AllocCommand,
84 alloc_f: AllocFloatX,
85 alloc_f32x8: AllocV8,
86 alloc_i16x16: AllocS16,
87 alloc_pdf: AllocPDF,
88 alloc_sc: AllocStaticCommand,
89 alloc_hl: AllocHistogramLiteral,
90 alloc_hc: AllocHistogramCommand,
91 alloc_hd: AllocHistogramDistance,
92 alloc_hp: AllocHistogramPair,
93 alloc_ct: AllocContextType,
94 alloc_ht: AllocHuffmanTree,
95 alloc_zn: AllocZopfliNode,
96}
97
98impl<
99 AllocU8: Allocator<u8>,
100 AllocU16: Allocator<u16>,
101 AllocI32: Allocator<i32>,
102 AllocU32: Allocator<u32>,
103 AllocU64: Allocator<u64>,
104 AllocCommand: Allocator<Command>,
105 AllocFloatX: Allocator<floatX>,
106 AllocV8: Allocator<v8>,
107 AllocS16: Allocator<s16>,
108 AllocPDF: Allocator<PDF>,
109 AllocStaticCommand: Allocator<StaticCommand>,
110 AllocHistogramLiteral: Allocator<HistogramLiteral>,
111 AllocHistogramCommand: Allocator<HistogramCommand>,
112 AllocHistogramDistance: Allocator<HistogramDistance>,
113 AllocHistogramPair: Allocator<HistogramPair>,
114 AllocContextType: Allocator<ContextType>,
115 AllocHuffmanTree: Allocator<HuffmanTree>,
116 AllocZopfliNode: Allocator<ZopfliNode>,
117 >
118 CombiningAllocator<
119 AllocU8,
120 AllocU16,
121 AllocI32,
122 AllocU32,
123 AllocU64,
124 AllocCommand,
125 AllocFloatX,
126 AllocV8,
127 AllocS16,
128 AllocPDF,
129 AllocStaticCommand,
130 AllocHistogramLiteral,
131 AllocHistogramCommand,
132 AllocHistogramDistance,
133 AllocHistogramPair,
134 AllocContextType,
135 AllocHuffmanTree,
136 AllocZopfliNode,
137 >
138{
139 pub fn new(
140 alloc_u8: AllocU8,
141 alloc_u16: AllocU16,
142 alloc_i32: AllocI32,
143 alloc_u32: AllocU32,
144 alloc_u64: AllocU64,
145 alloc_c: AllocCommand,
146 alloc_f: AllocFloatX,
147 alloc_f32x8: AllocV8,
148 alloc_i16x16: AllocS16,
149 alloc_pdf: AllocPDF,
150 alloc_sc: AllocStaticCommand,
151 alloc_hl: AllocHistogramLiteral,
152 alloc_hc: AllocHistogramCommand,
153 alloc_hd: AllocHistogramDistance,
154 alloc_hp: AllocHistogramPair,
155 alloc_ct: AllocContextType,
156 alloc_ht: AllocHuffmanTree,
157 alloc_zn: AllocZopfliNode,
158 ) -> Self {
159 CombiningAllocator {
160 alloc_u8,
161 alloc_u16,
162 alloc_i32,
163 alloc_u32,
164 alloc_u64,
165 alloc_c,
166 alloc_f,
167 alloc_f32x8,
168 alloc_i16x16,
169 alloc_pdf,
170 alloc_sc,
171 alloc_hl,
172 alloc_hc,
173 alloc_hd,
174 alloc_hp,
175 alloc_ct,
176 alloc_ht,
177 alloc_zn,
178 }
179 }
180}
181
182impl<
183 AllocU8: Allocator<u8>,
184 AllocU16: Allocator<u16>,
185 AllocI32: Allocator<i32>,
186 AllocU32: Allocator<u32>,
187 AllocU64: Allocator<u64>,
188 AllocCommand: Allocator<Command>,
189 AllocFloatX: Allocator<floatX>,
190 AllocV8: Allocator<v8>,
191 AllocS16: Allocator<s16>,
192 AllocPDF: Allocator<PDF>,
193 AllocStaticCommand: Allocator<StaticCommand>,
194 AllocHistogramLiteral: Allocator<HistogramLiteral>,
195 AllocHistogramCommand: Allocator<HistogramCommand>,
196 AllocHistogramDistance: Allocator<HistogramDistance>,
197 AllocHistogramPair: Allocator<HistogramPair>,
198 AllocContextType: Allocator<ContextType>,
199 AllocHuffmanTree: Allocator<HuffmanTree>,
200 AllocZopfliNode: Allocator<ZopfliNode>,
201 > BrotliAlloc
202 for CombiningAllocator<
203 AllocU8,
204 AllocU16,
205 AllocI32,
206 AllocU32,
207 AllocU64,
208 AllocCommand,
209 AllocFloatX,
210 AllocV8,
211 AllocS16,
212 AllocPDF,
213 AllocStaticCommand,
214 AllocHistogramLiteral,
215 AllocHistogramCommand,
216 AllocHistogramDistance,
217 AllocHistogramPair,
218 AllocContextType,
219 AllocHuffmanTree,
220 AllocZopfliNode,
221 >
222{
223}
224
225impl<
226 AllocU8: Allocator<u8> + Default,
227 AllocU16: Allocator<u16> + Default,
228 AllocI32: Allocator<i32> + Default,
229 AllocU32: Allocator<u32> + Default,
230 AllocU64: Allocator<u64> + Default,
231 AllocCommand: Allocator<Command> + Default,
232 AllocFloatX: Allocator<floatX> + Default,
233 AllocV8: Allocator<v8> + Default,
234 AllocS16: Allocator<s16> + Default,
235 AllocPDF: Allocator<PDF> + Default,
236 AllocStaticCommand: Allocator<StaticCommand> + Default,
237 AllocHistogramLiteral: Allocator<HistogramLiteral> + Default,
238 AllocHistogramCommand: Allocator<HistogramCommand> + Default,
239 AllocHistogramDistance: Allocator<HistogramDistance> + Default,
240 AllocHistogramPair: Allocator<HistogramPair> + Default,
241 AllocContextType: Allocator<ContextType> + Default,
242 AllocHuffmanTree: Allocator<HuffmanTree> + Default,
243 AllocZopfliNode: Allocator<ZopfliNode> + Default,
244 > Default
245 for CombiningAllocator<
246 AllocU8,
247 AllocU16,
248 AllocI32,
249 AllocU32,
250 AllocU64,
251 AllocCommand,
252 AllocFloatX,
253 AllocV8,
254 AllocS16,
255 AllocPDF,
256 AllocStaticCommand,
257 AllocHistogramLiteral,
258 AllocHistogramCommand,
259 AllocHistogramDistance,
260 AllocHistogramPair,
261 AllocContextType,
262 AllocHuffmanTree,
263 AllocZopfliNode,
264 >
265{
266 fn default() -> Self {
267 CombiningAllocator {
268 alloc_u8: AllocU8::default(),
269 alloc_u16: AllocU16::default(),
270 alloc_i32: AllocI32::default(),
271 alloc_u32: AllocU32::default(),
272 alloc_u64: AllocU64::default(),
273 alloc_c: AllocCommand::default(),
274 alloc_f: AllocFloatX::default(),
275 alloc_f32x8: AllocV8::default(),
276 alloc_i16x16: AllocS16::default(),
277 alloc_pdf: AllocPDF::default(),
278 alloc_sc: AllocStaticCommand::default(),
279 alloc_hl: AllocHistogramLiteral::default(),
280 alloc_hc: AllocHistogramCommand::default(),
281 alloc_hd: AllocHistogramDistance::default(),
282 alloc_hp: AllocHistogramPair::default(),
283 alloc_ct: AllocContextType::default(),
284 alloc_ht: AllocHuffmanTree::default(),
285 alloc_zn: AllocZopfliNode::default(),
286 }
287 }
288}
289
290impl<
291 AllocU8: Allocator<u8> + Clone,
292 AllocU16: Allocator<u16> + Clone,
293 AllocI32: Allocator<i32> + Clone,
294 AllocU32: Allocator<u32> + Clone,
295 AllocU64: Allocator<u64> + Clone,
296 AllocCommand: Allocator<Command> + Clone,
297 AllocFloatX: Allocator<floatX> + Clone,
298 AllocV8: Allocator<v8> + Clone,
299 AllocS16: Allocator<s16> + Clone,
300 AllocPDF: Allocator<PDF> + Clone,
301 AllocStaticCommand: Allocator<StaticCommand> + Clone,
302 AllocHistogramLiteral: Allocator<HistogramLiteral> + Clone,
303 AllocHistogramCommand: Allocator<HistogramCommand> + Clone,
304 AllocHistogramDistance: Allocator<HistogramDistance> + Clone,
305 AllocHistogramPair: Allocator<HistogramPair> + Clone,
306 AllocContextType: Allocator<ContextType> + Clone,
307 AllocHuffmanTree: Allocator<HuffmanTree> + Clone,
308 AllocZopfliNode: Allocator<ZopfliNode> + Clone,
309 > Clone
310 for CombiningAllocator<
311 AllocU8,
312 AllocU16,
313 AllocI32,
314 AllocU32,
315 AllocU64,
316 AllocCommand,
317 AllocFloatX,
318 AllocV8,
319 AllocS16,
320 AllocPDF,
321 AllocStaticCommand,
322 AllocHistogramLiteral,
323 AllocHistogramCommand,
324 AllocHistogramDistance,
325 AllocHistogramPair,
326 AllocContextType,
327 AllocHuffmanTree,
328 AllocZopfliNode,
329 >
330{
331 fn clone(&self) -> Self {
332 CombiningAllocator {
333 alloc_u8: self.alloc_u8.clone(),
334 alloc_u16: self.alloc_u16.clone(),
335 alloc_i32: self.alloc_i32.clone(),
336 alloc_u32: self.alloc_u32.clone(),
337 alloc_u64: self.alloc_u64.clone(),
338 alloc_c: self.alloc_c.clone(),
339 alloc_f: self.alloc_f.clone(),
340 alloc_f32x8: self.alloc_f32x8.clone(),
341 alloc_i16x16: self.alloc_i16x16.clone(),
342 alloc_pdf: self.alloc_pdf.clone(),
343 alloc_sc: self.alloc_sc.clone(),
344 alloc_hl: self.alloc_hl.clone(),
345 alloc_hc: self.alloc_hc.clone(),
346 alloc_hd: self.alloc_hd.clone(),
347 alloc_hp: self.alloc_hp.clone(),
348 alloc_ct: self.alloc_ct.clone(),
349 alloc_ht: self.alloc_ht.clone(),
350 alloc_zn: self.alloc_zn.clone(),
351 }
352 }
353}
354
355impl<
356 AllocU8: Allocator<u8> + Copy,
357 AllocU16: Allocator<u16> + Copy,
358 AllocI32: Allocator<i32> + Copy,
359 AllocU32: Allocator<u32> + Copy,
360 AllocU64: Allocator<u64> + Copy,
361 AllocCommand: Allocator<Command> + Copy,
362 AllocFloatX: Allocator<floatX> + Copy,
363 AllocV8: Allocator<v8> + Copy,
364 AllocS16: Allocator<s16> + Copy,
365 AllocPDF: Allocator<PDF> + Copy,
366 AllocStaticCommand: Allocator<StaticCommand> + Copy,
367 AllocHistogramLiteral: Allocator<HistogramLiteral> + Copy,
368 AllocHistogramCommand: Allocator<HistogramCommand> + Copy,
369 AllocHistogramDistance: Allocator<HistogramDistance> + Copy,
370 AllocHistogramPair: Allocator<HistogramPair> + Copy,
371 AllocContextType: Allocator<ContextType> + Copy,
372 AllocHuffmanTree: Allocator<HuffmanTree> + Copy,
373 AllocZopfliNode: Allocator<ZopfliNode> + Copy,
374 > Copy
375 for CombiningAllocator<
376 AllocU8,
377 AllocU16,
378 AllocI32,
379 AllocU32,
380 AllocU64,
381 AllocCommand,
382 AllocFloatX,
383 AllocV8,
384 AllocS16,
385 AllocPDF,
386 AllocStaticCommand,
387 AllocHistogramLiteral,
388 AllocHistogramCommand,
389 AllocHistogramDistance,
390 AllocHistogramPair,
391 AllocContextType,
392 AllocHuffmanTree,
393 AllocZopfliNode,
394 >
395{
396}
397
398macro_rules! implement_allocator {
399 ($bound_name: ty,
400 $type_name: ty,
401 $sub_type_name: ty,
402 $local_name: ident) => {
403 impl<
404 AllocU8: Allocator<u8>,
405 AllocU16: Allocator<u16>,
406 AllocI32: Allocator<i32>,
407 AllocU32: Allocator<u32>,
408 AllocU64: Allocator<u64>,
409 AllocCommand: Allocator<Command>,
410 AllocFloatX: Allocator<floatX>,
411 AllocV8: Allocator<v8>,
412 AllocS16: Allocator<s16>,
413 AllocPDF: Allocator<PDF>,
414 AllocStaticCommand: Allocator<StaticCommand>,
415 AllocHistogramLiteral: Allocator<HistogramLiteral>,
416 AllocHistogramCommand: Allocator<HistogramCommand>,
417 AllocHistogramDistance: Allocator<HistogramDistance>,
418 AllocHistogramPair: Allocator<HistogramPair>,
419 AllocContextType: Allocator<ContextType>,
420 AllocHuffmanTree: Allocator<HuffmanTree>,
421 AllocZopfliNode: Allocator<ZopfliNode>,
422 > Allocator<$type_name>
423 for CombiningAllocator<
424 AllocU8,
425 AllocU16,
426 AllocI32,
427 AllocU32,
428 AllocU64,
429 AllocCommand,
430 AllocFloatX,
431 AllocV8,
432 AllocS16,
433 AllocPDF,
434 AllocStaticCommand,
435 AllocHistogramLiteral,
436 AllocHistogramCommand,
437 AllocHistogramDistance,
438 AllocHistogramPair,
439 AllocContextType,
440 AllocHuffmanTree,
441 AllocZopfliNode,
442 >
443 {
444 type AllocatedMemory = $sub_type_name;
445 fn alloc_cell(
446 &mut self,
447 size: usize,
448 ) -> <Self as Allocator<$type_name>>::AllocatedMemory {
449 self.$local_name.alloc_cell(size)
450 }
451 fn free_cell(&mut self, data: <Self as Allocator<$type_name>>::AllocatedMemory) {
452 self.$local_name.free_cell(data)
453 }
454 }
455 };
456}
457
458implement_allocator!(AllocU8, u8, AllocU8::AllocatedMemory, alloc_u8);
459implement_allocator!(AllocU16, u16, AllocU16::AllocatedMemory, alloc_u16);
460
461implement_allocator!(AllocI32, i32, AllocI32::AllocatedMemory, alloc_i32);
462implement_allocator!(AllocU32, u32, AllocU32::AllocatedMemory, alloc_u32);
463implement_allocator!(AllocU64, u64, AllocU64::AllocatedMemory, alloc_u64);
464implement_allocator!(
465 AllocCommand,
466 Command,
467 AllocCommand::AllocatedMemory,
468 alloc_c
469);
470implement_allocator!(AllocFloatX, floatX, AllocFloatX::AllocatedMemory, alloc_f);
471implement_allocator!(AllocV8, v8, AllocV8::AllocatedMemory, alloc_f32x8);
472implement_allocator!(AllocS16, s16, AllocS16::AllocatedMemory, alloc_i16x16);
473implement_allocator!(AllocPDF, PDF, AllocPDF::AllocatedMemory, alloc_pdf);
474implement_allocator!(
475 AllocStaticCommand,
476 StaticCommand,
477 AllocStaticCommand::AllocatedMemory,
478 alloc_sc
479);
480implement_allocator!(
481 AllocHistogramLiteral,
482 HistogramLiteral,
483 AllocHistogramLiteral::AllocatedMemory,
484 alloc_hl
485);
486implement_allocator!(
487 AllocHistogramCommand,
488 HistogramCommand,
489 AllocHistogramCommand::AllocatedMemory,
490 alloc_hc
491);
492implement_allocator!(
493 AllocHistogramDistance,
494 HistogramDistance,
495 AllocHistogramDistance::AllocatedMemory,
496 alloc_hd
497);
498implement_allocator!(
499 AllocHistogramPair,
500 HistogramPair,
501 AllocHistogramPair::AllocatedMemory,
502 alloc_hp
503);
504implement_allocator!(
505 AllocContextType,
506 ContextType,
507 AllocContextType::AllocatedMemory,
508 alloc_ct
509);
510implement_allocator!(
511 AllocHuffmanTree,
512 HuffmanTree,
513 AllocHuffmanTree::AllocatedMemory,
514 alloc_ht
515);
516implement_allocator!(
517 AllocZopfliNode,
518 ZopfliNode,
519 AllocZopfliNode::AllocatedMemory,
520 alloc_zn
521);
522
523pub(crate) fn allocate<T, A: Allocator<T>>(alloc: &mut A, len: usize) -> A::AllocatedMemory {
525 A::alloc_cell(alloc, len)
526}
527
528pub(crate) fn alloc_default<T, A: Allocator<T>>() -> A::AllocatedMemory {
530 A::AllocatedMemory::default()
531}
532
533pub(crate) fn alloc_if<T, A: Allocator<T>>(
535 condition: bool,
536 alloc: &mut A,
537 len: usize,
538) -> A::AllocatedMemory {
539 if condition {
540 allocate(alloc, len)
541 } else {
542 alloc_default::<T, A>()
543 }
544}
545
546pub(crate) fn alloc_or_default<T, A: Allocator<T>>(
548 alloc: &mut A,
549 len: usize,
550) -> A::AllocatedMemory {
551 alloc_if(len > 0, alloc, len)
552}