xref: /php-src/ext/dom/lexbor/lexbor/core/mem.h (revision bffab33a)
1 /*
2  * Copyright (C) 2018 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #ifndef LEXBOR_MEM_H
8 #define LEXBOR_MEM_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include <string.h>
15 
16 #include "lexbor/core/base.h"
17 
18 
19 typedef struct lexbor_mem_chunk lexbor_mem_chunk_t;
20 typedef struct lexbor_mem lexbor_mem_t;
21 
22 struct lexbor_mem_chunk {
23     uint8_t            *data;
24     size_t             length;
25     size_t             size;
26 
27     lexbor_mem_chunk_t *next;
28     lexbor_mem_chunk_t *prev;
29 };
30 
31 struct lexbor_mem {
32     lexbor_mem_chunk_t *chunk;
33     lexbor_mem_chunk_t *chunk_first;
34 
35     size_t             chunk_min_size;
36     size_t             chunk_length;
37 };
38 
39 
40 LXB_API lexbor_mem_t *
41 lexbor_mem_create(void);
42 
43 LXB_API lxb_status_t
44 lexbor_mem_init(lexbor_mem_t *mem, size_t min_chunk_size);
45 
46 LXB_API void
47 lexbor_mem_clean(lexbor_mem_t *mem);
48 
49 LXB_API lexbor_mem_t *
50 lexbor_mem_destroy(lexbor_mem_t *mem, bool destroy_self);
51 
52 
53 /*
54  * The memory allocated in lexbor_mem_chunk_* functions needs to be freed
55  * by lexbor_mem_chunk_destroy function.
56  *
57  * This memory will not be automatically freed by a function lexbor_mem_destroy.
58  */
59 LXB_API uint8_t *
60 lexbor_mem_chunk_init(lexbor_mem_t *mem,
61                       lexbor_mem_chunk_t *chunk, size_t length);
62 
63 LXB_API lexbor_mem_chunk_t *
64 lexbor_mem_chunk_make(lexbor_mem_t *mem, size_t length);
65 
66 LXB_API lexbor_mem_chunk_t *
67 lexbor_mem_chunk_destroy(lexbor_mem_t *mem,
68                          lexbor_mem_chunk_t *chunk, bool self_destroy);
69 
70 /*
71  * The memory allocated in lexbor_mem_alloc and lexbor_mem_calloc function
72  * will be freeds after calling lexbor_mem_destroy function.
73  */
74 LXB_API void *
75 lexbor_mem_alloc(lexbor_mem_t *mem, size_t length);
76 
77 LXB_API void *
78 lexbor_mem_calloc(lexbor_mem_t *mem, size_t length);
79 
80 
81 /*
82  * Inline functions
83  */
84 lxb_inline size_t
lexbor_mem_current_length(lexbor_mem_t * mem)85 lexbor_mem_current_length(lexbor_mem_t *mem)
86 {
87     return mem->chunk->length;
88 }
89 
90 lxb_inline size_t
lexbor_mem_current_size(lexbor_mem_t * mem)91 lexbor_mem_current_size(lexbor_mem_t *mem)
92 {
93     return mem->chunk->size;
94 }
95 
96 lxb_inline size_t
lexbor_mem_chunk_length(lexbor_mem_t * mem)97 lexbor_mem_chunk_length(lexbor_mem_t *mem)
98 {
99     return mem->chunk_length;
100 }
101 
102 lxb_inline size_t
lexbor_mem_align(size_t size)103 lexbor_mem_align(size_t size)
104 {
105     return ((size % LEXBOR_MEM_ALIGN_STEP) != 0)
106            ? size + (LEXBOR_MEM_ALIGN_STEP - (size % LEXBOR_MEM_ALIGN_STEP))
107            : size;
108 }
109 
110 lxb_inline size_t
lexbor_mem_align_floor(size_t size)111 lexbor_mem_align_floor(size_t size)
112 {
113     return ((size % LEXBOR_MEM_ALIGN_STEP) != 0)
114            ? size - (size % LEXBOR_MEM_ALIGN_STEP)
115            : size;
116 }
117 
118 /*
119  * No inline functions for ABI.
120  */
121 LXB_API size_t
122 lexbor_mem_current_length_noi(lexbor_mem_t *mem);
123 
124 LXB_API size_t
125 lexbor_mem_current_size_noi(lexbor_mem_t *mem);
126 
127 LXB_API size_t
128 lexbor_mem_chunk_length_noi(lexbor_mem_t *mem);
129 
130 LXB_API size_t
131 lexbor_mem_align_noi(size_t size);
132 
133 LXB_API size_t
134 lexbor_mem_align_floor_noi(size_t size);
135 
136 
137 #ifdef __cplusplus
138 } /* extern "C" */
139 #endif
140 
141 #endif /* LEXBOR_MEM_H */
142