brotli/enc/
combined_alloc.rs

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};
14/*
15struct CombiningAllocator<T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>>(AllocT1, AllocT2);
16
17impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> CombiningAllocator<T1, T2, AllocT1, AllocT2> {
18  pub fn new(a: AllocT1, b: AllocT2) -> Self {
19    CombiningAllocator(a, b)
20  }
21}
22
23impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> Allocator<T1> for CombiningAllocator<T1, T2, AllocT1, AllocT2> {
24
25}
26
27
28impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> Allocator<T2> for CombiningAllocator<T1, T2, AllocT1, AllocT2> {
29
30}
31*/
32
33pub 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
523/// Helper function to allocate memory with the given allocator (may crash if the `len` is 0).
524pub(crate) fn allocate<T, A: Allocator<T>>(alloc: &mut A, len: usize) -> A::AllocatedMemory {
525    A::alloc_cell(alloc, len)
526}
527
528/// Helper function to create an empty allocator object
529pub(crate) fn alloc_default<T, A: Allocator<T>>() -> A::AllocatedMemory {
530    A::AllocatedMemory::default()
531}
532
533/// Helper function to allocate memory or return a default value if the condition is false
534pub(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
546/// Helper function to allocate memory or return a default value when the size is 0.
547pub(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}