comparison mupdf-source/thirdparty/extract/src/alloc.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 #include "extract/alloc.h"
2
3 #include <assert.h>
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8
9 struct extract_alloc_t
10 {
11 extract_realloc_fn_t *realloc_fn;
12 extract_caller_context_t *realloc_state;
13 size_t exp_min_alloc_size;
14 extract_alloc_stats_t stats;
15 };
16
17 int
18 extract_alloc_create( extract_realloc_fn_t *realloc_fn,
19 void *realloc_state,
20 extract_alloc_t **palloc)
21 {
22 assert(realloc_fn);
23 assert(palloc);
24 *palloc = realloc_fn(realloc_state, NULL /*ptr*/, sizeof(**palloc));
25 if (!*palloc) {
26 errno = ENOMEM;
27 return -1;
28 }
29 memset(*palloc, 0, sizeof(**palloc));
30 (*palloc)->realloc_fn = realloc_fn;
31 (*palloc)->realloc_state = realloc_state;
32 (*palloc)->exp_min_alloc_size = 0;
33 return 0;
34 }
35
36 void extract_alloc_destroy(extract_alloc_t **palloc)
37 {
38 if (!*palloc) return;
39 (*palloc)->realloc_fn((*palloc)->realloc_state, *palloc, 0 /*newsize*/);
40 *palloc = NULL;
41 }
42
43 extract_alloc_stats_t *extract_alloc_stats(extract_alloc_t *alloc)
44 {
45 return &alloc->stats;
46 }
47
48 static size_t round_up(extract_alloc_t *alloc, size_t n)
49 {
50 size_t ret;
51
52 if (alloc == NULL || alloc->exp_min_alloc_size || n == 0)
53 return n;
54
55 /* Round up to power of two. */
56 ret = alloc->exp_min_alloc_size;
57 while (ret < n) {
58 size_t ret_old = ret;
59 ret *= 2;
60 if (ret <= ret_old)
61 ret = n;
62 }
63
64 return ret;
65 }
66
67 int (extract_malloc)(extract_alloc_t *alloc, void **pptr, size_t size)
68 {
69 void *p;
70
71 size = round_up(alloc, size);
72 p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, NULL, size) : malloc(size);
73 *pptr = p;
74 if (!p && size)
75 {
76 if (alloc) errno = ENOMEM;
77 return -1;
78 }
79 if (alloc) alloc->stats.num_malloc += 1;
80 return 0;
81 }
82
83 int (extract_realloc)(extract_alloc_t *alloc, void **pptr, size_t newsize)
84 {
85 void *p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, *pptr, newsize) : realloc(*pptr, newsize);
86 if (!p && newsize)
87 {
88 if (alloc) errno = ENOMEM;
89 return -1;
90 }
91 *pptr = p;
92 if (alloc) alloc->stats.num_realloc += 1;
93 return 0;
94 }
95
96 int (extract_realloc2)(extract_alloc_t *alloc, void **pptr, size_t oldsize, size_t newsize)
97 {
98 /* We ignore <oldsize> if <ptr> is NULL - allows callers to not worry
99 about edge cases e.g. with strlen+1. */
100 oldsize = (*pptr) ? round_up(alloc, oldsize) : 0;
101 newsize = round_up(alloc, newsize);
102 if (newsize == oldsize) return 0;
103 return (extract_realloc)(alloc, pptr, newsize);
104 }
105
106 void (extract_free)(extract_alloc_t *alloc, void **pptr)
107 {
108 if (alloc)
109 (void)alloc->realloc_fn(alloc->realloc_state, *pptr, 0);
110 else
111 free(*pptr);
112 *pptr = NULL;
113 if (alloc) alloc->stats.num_free += 1;
114 }
115
116 void extract_alloc_exp_min(extract_alloc_t *alloc, size_t size)
117 {
118 alloc->exp_min_alloc_size = size;
119 }