xref: /aosp_15_r20/external/brotli/c/enc/memory.h (revision f4ee7fba7774faf2a30f13154332c0a06550dbc4)
1*f4ee7fbaSAndroid Build Coastguard Worker /* Copyright 2016 Google Inc. All Rights Reserved.
2*f4ee7fbaSAndroid Build Coastguard Worker 
3*f4ee7fbaSAndroid Build Coastguard Worker    Distributed under MIT license.
4*f4ee7fbaSAndroid Build Coastguard Worker    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5*f4ee7fbaSAndroid Build Coastguard Worker */
6*f4ee7fbaSAndroid Build Coastguard Worker 
7*f4ee7fbaSAndroid Build Coastguard Worker /* Macros for memory management. */
8*f4ee7fbaSAndroid Build Coastguard Worker 
9*f4ee7fbaSAndroid Build Coastguard Worker #ifndef BROTLI_ENC_MEMORY_H_
10*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENC_MEMORY_H_
11*f4ee7fbaSAndroid Build Coastguard Worker 
12*f4ee7fbaSAndroid Build Coastguard Worker #include <string.h>  /* memcpy */
13*f4ee7fbaSAndroid Build Coastguard Worker 
14*f4ee7fbaSAndroid Build Coastguard Worker #include "../common/platform.h"
15*f4ee7fbaSAndroid Build Coastguard Worker #include <brotli/types.h>
16*f4ee7fbaSAndroid Build Coastguard Worker 
17*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
18*f4ee7fbaSAndroid Build Coastguard Worker extern "C" {
19*f4ee7fbaSAndroid Build Coastguard Worker #endif
20*f4ee7fbaSAndroid Build Coastguard Worker 
21*f4ee7fbaSAndroid Build Coastguard Worker #if !defined(BROTLI_ENCODER_CLEANUP_ON_OOM) && \
22*f4ee7fbaSAndroid Build Coastguard Worker     !defined(BROTLI_ENCODER_EXIT_ON_OOM)
23*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENCODER_EXIT_ON_OOM
24*f4ee7fbaSAndroid Build Coastguard Worker #endif
25*f4ee7fbaSAndroid Build Coastguard Worker 
26*f4ee7fbaSAndroid Build Coastguard Worker typedef struct MemoryManager {
27*f4ee7fbaSAndroid Build Coastguard Worker   brotli_alloc_func alloc_func;
28*f4ee7fbaSAndroid Build Coastguard Worker   brotli_free_func free_func;
29*f4ee7fbaSAndroid Build Coastguard Worker   void* opaque;
30*f4ee7fbaSAndroid Build Coastguard Worker #if !defined(BROTLI_ENCODER_EXIT_ON_OOM)
31*f4ee7fbaSAndroid Build Coastguard Worker   BROTLI_BOOL is_oom;
32*f4ee7fbaSAndroid Build Coastguard Worker   size_t perm_allocated;
33*f4ee7fbaSAndroid Build Coastguard Worker   size_t new_allocated;
34*f4ee7fbaSAndroid Build Coastguard Worker   size_t new_freed;
35*f4ee7fbaSAndroid Build Coastguard Worker   void* pointers[256];
36*f4ee7fbaSAndroid Build Coastguard Worker #endif  /* BROTLI_ENCODER_EXIT_ON_OOM */
37*f4ee7fbaSAndroid Build Coastguard Worker } MemoryManager;
38*f4ee7fbaSAndroid Build Coastguard Worker 
39*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliInitMemoryManager(
40*f4ee7fbaSAndroid Build Coastguard Worker     MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func,
41*f4ee7fbaSAndroid Build Coastguard Worker     void* opaque);
42*f4ee7fbaSAndroid Build Coastguard Worker 
43*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void* BrotliAllocate(MemoryManager* m, size_t n);
44*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ALLOC(M, T, N)                               \
45*f4ee7fbaSAndroid Build Coastguard Worker   ((N) > 0 ? ((T*)BrotliAllocate((M), (N) * sizeof(T))) : NULL)
46*f4ee7fbaSAndroid Build Coastguard Worker 
47*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p);
48*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_FREE(M, P) { \
49*f4ee7fbaSAndroid Build Coastguard Worker   BrotliFree((M), (P));     \
50*f4ee7fbaSAndroid Build Coastguard Worker   P = NULL;                 \
51*f4ee7fbaSAndroid Build Coastguard Worker }
52*f4ee7fbaSAndroid Build Coastguard Worker 
53*f4ee7fbaSAndroid Build Coastguard Worker #if defined(BROTLI_ENCODER_EXIT_ON_OOM)
54*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_IS_OOM(M) (!!0)
55*f4ee7fbaSAndroid Build Coastguard Worker #else  /* BROTLI_ENCODER_EXIT_ON_OOM */
56*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_IS_OOM(M) (!!(M)->is_oom)
57*f4ee7fbaSAndroid Build Coastguard Worker #endif  /* BROTLI_ENCODER_EXIT_ON_OOM */
58*f4ee7fbaSAndroid Build Coastguard Worker 
59*f4ee7fbaSAndroid Build Coastguard Worker /*
60*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_IS_NULL is a fake check, BROTLI_IS_OOM does the heavy lifting.
61*f4ee7fbaSAndroid Build Coastguard Worker The only purpose of it is to explain static analyzers the state of things.
62*f4ee7fbaSAndroid Build Coastguard Worker NB: use ONLY together with BROTLI_IS_OOM
63*f4ee7fbaSAndroid Build Coastguard Worker     AND ONLY for allocations in the current scope.
64*f4ee7fbaSAndroid Build Coastguard Worker  */
65*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__clang_analyzer__) && !defined(BROTLI_ENCODER_EXIT_ON_OOM)
66*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_IS_NULL(A) ((A) == nullptr)
67*f4ee7fbaSAndroid Build Coastguard Worker #else  /* defined(__clang_analyzer__) */
68*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_IS_NULL(A) (!!0)
69*f4ee7fbaSAndroid Build Coastguard Worker #endif  /* defined(__clang_analyzer__) */
70*f4ee7fbaSAndroid Build Coastguard Worker 
71*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m);
72*f4ee7fbaSAndroid Build Coastguard Worker 
73*f4ee7fbaSAndroid Build Coastguard Worker /*
74*f4ee7fbaSAndroid Build Coastguard Worker Dynamically grows array capacity to at least the requested size
75*f4ee7fbaSAndroid Build Coastguard Worker M: MemoryManager
76*f4ee7fbaSAndroid Build Coastguard Worker T: data type
77*f4ee7fbaSAndroid Build Coastguard Worker A: array
78*f4ee7fbaSAndroid Build Coastguard Worker C: capacity
79*f4ee7fbaSAndroid Build Coastguard Worker R: requested size
80*f4ee7fbaSAndroid Build Coastguard Worker */
81*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) {                    \
82*f4ee7fbaSAndroid Build Coastguard Worker   if (C < (R)) {                                                   \
83*f4ee7fbaSAndroid Build Coastguard Worker     size_t _new_size = (C == 0) ? (R) : C;                         \
84*f4ee7fbaSAndroid Build Coastguard Worker     T* new_array;                                                  \
85*f4ee7fbaSAndroid Build Coastguard Worker     while (_new_size < (R)) _new_size *= 2;                        \
86*f4ee7fbaSAndroid Build Coastguard Worker     new_array = BROTLI_ALLOC((M), T, _new_size);                   \
87*f4ee7fbaSAndroid Build Coastguard Worker     if (!BROTLI_IS_OOM(M) && !BROTLI_IS_NULL(new_array) && C != 0) \
88*f4ee7fbaSAndroid Build Coastguard Worker       memcpy(new_array, A, C * sizeof(T));                         \
89*f4ee7fbaSAndroid Build Coastguard Worker     BROTLI_FREE((M), A);                                           \
90*f4ee7fbaSAndroid Build Coastguard Worker     A = new_array;                                                 \
91*f4ee7fbaSAndroid Build Coastguard Worker     C = _new_size;                                                 \
92*f4ee7fbaSAndroid Build Coastguard Worker   }                                                                \
93*f4ee7fbaSAndroid Build Coastguard Worker }
94*f4ee7fbaSAndroid Build Coastguard Worker 
95*f4ee7fbaSAndroid Build Coastguard Worker /*
96*f4ee7fbaSAndroid Build Coastguard Worker Appends value and dynamically grows array capacity when needed
97*f4ee7fbaSAndroid Build Coastguard Worker M: MemoryManager
98*f4ee7fbaSAndroid Build Coastguard Worker T: data type
99*f4ee7fbaSAndroid Build Coastguard Worker A: array
100*f4ee7fbaSAndroid Build Coastguard Worker C: array capacity
101*f4ee7fbaSAndroid Build Coastguard Worker S: array size
102*f4ee7fbaSAndroid Build Coastguard Worker V: value to append
103*f4ee7fbaSAndroid Build Coastguard Worker */
104*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENSURE_CAPACITY_APPEND(M, T, A, C, S, V) { \
105*f4ee7fbaSAndroid Build Coastguard Worker   (S)++;                                                  \
106*f4ee7fbaSAndroid Build Coastguard Worker   BROTLI_ENSURE_CAPACITY(M, T, A, C, S);                  \
107*f4ee7fbaSAndroid Build Coastguard Worker   A[(S) - 1] = (V);                                       \
108*f4ee7fbaSAndroid Build Coastguard Worker }
109*f4ee7fbaSAndroid Build Coastguard Worker 
110*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
111*f4ee7fbaSAndroid Build Coastguard Worker }  /* extern "C" */
112*f4ee7fbaSAndroid Build Coastguard Worker #endif
113*f4ee7fbaSAndroid Build Coastguard Worker 
114*f4ee7fbaSAndroid Build Coastguard Worker #endif  /* BROTLI_ENC_MEMORY_H_ */
115