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