1#include "mupdf/fitz.h"
2
3#include <string.h>
4#include <stdio.h>
5
6typedef 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
11struct fz_pool_s
12{
13 fz_pool_node *head, *tail;
14 char *pos, *end;
15};
16
17struct fz_pool_node_s
18{
19 fz_pool_node *next;
20 char mem[1];
21};
22
23fz_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
45static 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
57void *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
79char *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
87void 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