1 | #include "mupdf/fitz.h" |
2 | |
3 | #include <string.h> |
4 | #include <stdio.h> |
5 | |
6 | typedef struct fz_pool_node_s fz_pool_node; |
7 | |
8 | #define POOL_SIZE (4<<10) /* default size of pool blocks */ |
9 | #define POOL_SELF (1<<10) /* size where allocs are put into their own blocks */ |
10 | |
11 | struct fz_pool_s |
12 | { |
13 | fz_pool_node *head, *tail; |
14 | char *pos, *end; |
15 | }; |
16 | |
17 | struct fz_pool_node_s |
18 | { |
19 | fz_pool_node *next; |
20 | char mem[1]; |
21 | }; |
22 | |
23 | fz_pool *fz_new_pool(fz_context *ctx) |
24 | { |
25 | fz_pool *pool; |
26 | fz_pool_node *node = NULL; |
27 | |
28 | pool = fz_malloc_struct(ctx, fz_pool); |
29 | fz_try(ctx) |
30 | { |
31 | node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + POOL_SIZE, 1); |
32 | pool->head = pool->tail = node; |
33 | pool->pos = node->mem; |
34 | pool->end = node->mem + POOL_SIZE; |
35 | } |
36 | fz_catch(ctx) |
37 | { |
38 | fz_free(ctx, pool); |
39 | fz_rethrow(ctx); |
40 | } |
41 | |
42 | return pool; |
43 | } |
44 | |
45 | static void *fz_pool_alloc_oversize(fz_context *ctx, fz_pool *pool, size_t size) |
46 | { |
47 | fz_pool_node *node; |
48 | |
49 | /* link in memory at the head of the list */ |
50 | node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + size, 1); |
51 | node->next = pool->head; |
52 | pool->head = node; |
53 | |
54 | return node->mem; |
55 | } |
56 | |
57 | void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size) |
58 | { |
59 | char *ptr; |
60 | |
61 | if (size >= POOL_SELF) |
62 | return fz_pool_alloc_oversize(ctx, pool, size); |
63 | |
64 | /* round size to pointer alignment (we don't expect to use doubles) */ |
65 | size = ((size + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*); |
66 | |
67 | if (pool->pos + size > pool->end) |
68 | { |
69 | fz_pool_node *node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + POOL_SIZE, 1); |
70 | pool->tail = pool->tail->next = node; |
71 | pool->pos = node->mem; |
72 | pool->end = node->mem + POOL_SIZE; |
73 | } |
74 | ptr = pool->pos; |
75 | pool->pos += size; |
76 | return ptr; |
77 | } |
78 | |
79 | char *fz_pool_strdup(fz_context *ctx, fz_pool *pool, const char *s) |
80 | { |
81 | size_t n = strlen(s) + 1; |
82 | char *p = fz_pool_alloc(ctx, pool, n); |
83 | memcpy(p, s, n); |
84 | return p; |
85 | } |
86 | |
87 | void fz_drop_pool(fz_context *ctx, fz_pool *pool) |
88 | { |
89 | fz_pool_node *node; |
90 | |
91 | if (!pool) |
92 | return; |
93 | |
94 | node = pool->head; |
95 | while (node) |
96 | { |
97 | fz_pool_node *next = node->next; |
98 | fz_free(ctx, node); |
99 | node = next; |
100 | } |
101 | fz_free(ctx, pool); |
102 | } |
103 | |