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)85lexbor_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)91lexbor_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)97lexbor_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)103lexbor_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)111lexbor_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