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