11cb0ef41Sopenharmony_ci/* Copyright 2016 Google Inc. All Rights Reserved. 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci Distributed under MIT license. 41cb0ef41Sopenharmony_ci See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 51cb0ef41Sopenharmony_ci*/ 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci/* Macros for memory management. */ 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#ifndef BROTLI_ENC_MEMORY_H_ 101cb0ef41Sopenharmony_ci#define BROTLI_ENC_MEMORY_H_ 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include <string.h> /* memcpy */ 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#include "../common/platform.h" 151cb0ef41Sopenharmony_ci#include <brotli/types.h> 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus) 181cb0ef41Sopenharmony_ciextern "C" { 191cb0ef41Sopenharmony_ci#endif 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#if !defined(BROTLI_ENCODER_CLEANUP_ON_OOM) && \ 221cb0ef41Sopenharmony_ci !defined(BROTLI_ENCODER_EXIT_ON_OOM) 231cb0ef41Sopenharmony_ci#define BROTLI_ENCODER_EXIT_ON_OOM 241cb0ef41Sopenharmony_ci#endif 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_citypedef struct MemoryManager { 271cb0ef41Sopenharmony_ci brotli_alloc_func alloc_func; 281cb0ef41Sopenharmony_ci brotli_free_func free_func; 291cb0ef41Sopenharmony_ci void* opaque; 301cb0ef41Sopenharmony_ci#if !defined(BROTLI_ENCODER_EXIT_ON_OOM) 311cb0ef41Sopenharmony_ci BROTLI_BOOL is_oom; 321cb0ef41Sopenharmony_ci size_t perm_allocated; 331cb0ef41Sopenharmony_ci size_t new_allocated; 341cb0ef41Sopenharmony_ci size_t new_freed; 351cb0ef41Sopenharmony_ci void* pointers[256]; 361cb0ef41Sopenharmony_ci#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ 371cb0ef41Sopenharmony_ci} MemoryManager; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciBROTLI_INTERNAL void BrotliInitMemoryManager( 401cb0ef41Sopenharmony_ci MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func, 411cb0ef41Sopenharmony_ci void* opaque); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciBROTLI_INTERNAL void* BrotliAllocate(MemoryManager* m, size_t n); 441cb0ef41Sopenharmony_ci#define BROTLI_ALLOC(M, T, N) \ 451cb0ef41Sopenharmony_ci ((N) > 0 ? ((T*)BrotliAllocate((M), (N) * sizeof(T))) : NULL) 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciBROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p); 481cb0ef41Sopenharmony_ci#define BROTLI_FREE(M, P) { \ 491cb0ef41Sopenharmony_ci BrotliFree((M), (P)); \ 501cb0ef41Sopenharmony_ci P = NULL; \ 511cb0ef41Sopenharmony_ci} 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci#if defined(BROTLI_ENCODER_EXIT_ON_OOM) 541cb0ef41Sopenharmony_ci#define BROTLI_IS_OOM(M) (!!0) 551cb0ef41Sopenharmony_ci#else /* BROTLI_ENCODER_EXIT_ON_OOM */ 561cb0ef41Sopenharmony_ci#define BROTLI_IS_OOM(M) (!!(M)->is_oom) 571cb0ef41Sopenharmony_ci#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci/* 601cb0ef41Sopenharmony_ciBROTLI_IS_NULL is a fake check, BROTLI_IS_OOM does the heavy lifting. 611cb0ef41Sopenharmony_ciThe only purpose of it is to explain static analyzers the state of things. 621cb0ef41Sopenharmony_ciNB: use ONLY together with BROTLI_IS_OOM 631cb0ef41Sopenharmony_ci AND ONLY for allocations in the current scope. 641cb0ef41Sopenharmony_ci */ 651cb0ef41Sopenharmony_ci#if defined(__clang_analyzer__) && !defined(BROTLI_ENCODER_EXIT_ON_OOM) 661cb0ef41Sopenharmony_ci#define BROTLI_IS_NULL(A) ((A) == nullptr) 671cb0ef41Sopenharmony_ci#else /* defined(__clang_analyzer__) */ 681cb0ef41Sopenharmony_ci#define BROTLI_IS_NULL(A) (!!0) 691cb0ef41Sopenharmony_ci#endif /* defined(__clang_analyzer__) */ 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ciBROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci/* 741cb0ef41Sopenharmony_ciDynamically grows array capacity to at least the requested size 751cb0ef41Sopenharmony_ciM: MemoryManager 761cb0ef41Sopenharmony_ciT: data type 771cb0ef41Sopenharmony_ciA: array 781cb0ef41Sopenharmony_ciC: capacity 791cb0ef41Sopenharmony_ciR: requested size 801cb0ef41Sopenharmony_ci*/ 811cb0ef41Sopenharmony_ci#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ 821cb0ef41Sopenharmony_ci if (C < (R)) { \ 831cb0ef41Sopenharmony_ci size_t _new_size = (C == 0) ? (R) : C; \ 841cb0ef41Sopenharmony_ci T* new_array; \ 851cb0ef41Sopenharmony_ci while (_new_size < (R)) _new_size *= 2; \ 861cb0ef41Sopenharmony_ci new_array = BROTLI_ALLOC((M), T, _new_size); \ 871cb0ef41Sopenharmony_ci if (!BROTLI_IS_OOM(M) && !BROTLI_IS_NULL(new_array) && C != 0) \ 881cb0ef41Sopenharmony_ci memcpy(new_array, A, C * sizeof(T)); \ 891cb0ef41Sopenharmony_ci BROTLI_FREE((M), A); \ 901cb0ef41Sopenharmony_ci A = new_array; \ 911cb0ef41Sopenharmony_ci C = _new_size; \ 921cb0ef41Sopenharmony_ci } \ 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci/* 961cb0ef41Sopenharmony_ciAppends value and dynamically grows array capacity when needed 971cb0ef41Sopenharmony_ciM: MemoryManager 981cb0ef41Sopenharmony_ciT: data type 991cb0ef41Sopenharmony_ciA: array 1001cb0ef41Sopenharmony_ciC: array capacity 1011cb0ef41Sopenharmony_ciS: array size 1021cb0ef41Sopenharmony_ciV: value to append 1031cb0ef41Sopenharmony_ci*/ 1041cb0ef41Sopenharmony_ci#define BROTLI_ENSURE_CAPACITY_APPEND(M, T, A, C, S, V) { \ 1051cb0ef41Sopenharmony_ci (S)++; \ 1061cb0ef41Sopenharmony_ci BROTLI_ENSURE_CAPACITY(M, T, A, C, S); \ 1071cb0ef41Sopenharmony_ci A[(S) - 1] = (V); \ 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus) 1111cb0ef41Sopenharmony_ci} /* extern "C" */ 1121cb0ef41Sopenharmony_ci#endif 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci#endif /* BROTLI_ENC_MEMORY_H_ */ 115