Tue, 27 Jun 2023 18:44:37 +0200
add web docs for buffer and stream copy
universe@720 | 1 | --- |
universe@720 | 2 | title: UCX Features |
universe@720 | 3 | --- |
universe@720 | 4 | |
universe@720 | 5 | <div id="modules"> |
universe@720 | 6 | |
universe@720 | 7 | ------------------------ ------------------------- ------------------- --------------------------------- |
universe@720 | 8 | [Allocator](#allocator) [String](#string) [Buffer](#buffer) [Memory Pool](#memory-pool) |
universe@720 | 9 | [Iterator](#iterator) [Collection](#collection) [List](#list) [Map](#map) |
universe@720 | 10 | [Utilities](#utilities) |
universe@720 | 11 | ------------------------ ------------------------- ------------------- --------------------------------- |
universe@720 | 12 | |
universe@720 | 13 | </div> |
universe@720 | 14 | |
universe@720 | 15 | ## Allocator |
universe@720 | 16 | |
universe@720 | 17 | *Header file:* [allocator.h](api/allocator_8h.html) |
universe@720 | 18 | |
universe@722 | 19 | The UCX allocator provides an interface for implementing an own memory allocation mechanism. |
universe@722 | 20 | Various function in UCX provide an additional alternative signature that takes an allocator as |
universe@722 | 21 | argument. A default allocator implementation using the stdlib memory management functions is |
universe@722 | 22 | available via the global symbol `cxDefaultAllocator`. |
universe@722 | 23 | |
universe@722 | 24 | If you want to define your own allocator, you need to initialize the `CxAllocator` structure |
universe@722 | 25 | with a pointer to an allocator class (containing function pointers for the memory management |
universe@722 | 26 | functions) and an optional pointer to an arbitrary memory region that can be used to store |
universe@722 | 27 | state information for the allocator. An example is shown below: |
universe@722 | 28 | |
universe@722 | 29 | ```c |
universe@722 | 30 | struct my_allocator_state { |
universe@722 | 31 | size_t total; |
universe@722 | 32 | size_t avail; |
universe@722 | 33 | char[] mem; |
universe@722 | 34 | }; |
universe@722 | 35 | |
universe@722 | 36 | static cx_allocator_class my_allocator_class = { |
universe@722 | 37 | my_malloc_impl, |
universe@722 | 38 | my_realloc_impl, // all these functions are somewhere defined |
universe@722 | 39 | my_calloc_impl, |
universe@722 | 40 | my_free_impl |
universe@722 | 41 | }; |
universe@722 | 42 | |
universe@722 | 43 | CxAllocator create_my_allocator(size_t n) { |
universe@722 | 44 | CxAllocator alloc; |
universe@722 | 45 | alloc.cl = &my_allocator_class; |
universe@722 | 46 | alloc.data = calloc(1, sizeof(struct my_allocator_state) + n); |
universe@722 | 47 | return alloc; |
universe@722 | 48 | } |
universe@722 | 49 | |
universe@722 | 50 | void free_my_allocator(CxAllocator *alloc) { |
universe@722 | 51 | free(alloc.data); |
universe@722 | 52 | free(alloc); |
universe@722 | 53 | } |
universe@722 | 54 | ``` |
universe@722 | 55 | |
universe@720 | 56 | ## String |
universe@720 | 57 | |
universe@720 | 58 | *Header file:* [string.h](api/string_8h.html) |
universe@720 | 59 | |
universe@723 | 60 | UCX strings come in two variants: immutable (`cxstring`) and mutable (`cxmutstr`). |
universe@723 | 61 | The functions of UCX are designed to work with immutable strings by default but in situations where it is necessary, |
universe@723 | 62 | the API also provides alternative functions that work directly with mutable strings. |
universe@723 | 63 | Functions that change a string in-place are, of course, only accepting mutable strings. |
universe@723 | 64 | |
universe@723 | 65 | When you are using UCX functions, or defining your own functions, you are sometimes facing the "problem", |
universe@723 | 66 | that the function only accepts arguments of type `cxstring` but you only have a `cxmutstr` at hand. |
universe@723 | 67 | In this case you _should not_ introduce a wrapper function that accepts the `cxmutstr`, |
universe@723 | 68 | but instead you should use the `cx_strcast()` function to cast the argument to the correct type. |
universe@723 | 69 | |
universe@723 | 70 | In general, UCX strings are **not** necessarily zero-terminated. If a function guarantees to return zero-terminated |
universe@723 | 71 | string, it is explicitly mentioned in the documentation of the respective function. |
universe@723 | 72 | As a rule of thumb, you _should not_ pass the strings of a UCX string structure to another API without explicitly |
universe@723 | 73 | ensuring that the string is zero-terminated. |
universe@723 | 74 | |
universe@720 | 75 | ## Buffer |
universe@720 | 76 | |
universe@724 | 77 | *Header file:* [buffer.h](api/buffer_8h.html) |
universe@724 | 78 | |
universe@724 | 79 | Instances of this buffer implementation can be used to read from or write to memory like you would do with a stream. |
universe@724 | 80 | This allows the use of `cx_stream_copy()` (see [Utilities](#utilities)) to copy contents from one buffer to another, |
universe@724 | 81 | or from a file or network streams to the buffer and vice-versa. |
universe@724 | 82 | |
universe@724 | 83 | More features for convenient use of the buffer can be enabled, like automatic memory management and automatic |
universe@724 | 84 | resizing of the buffer space. |
universe@724 | 85 | |
universe@724 | 86 | Since UCX 3.0, the buffer also supports automatic flushing of contents to another stream (or buffer) as an alternative |
universe@724 | 87 | to automatically resizing the buffer space. |
universe@724 | 88 | Please refer to the API doc for the fields prefixed with `flush_` to learn more. |
universe@720 | 89 | |
universe@720 | 90 | ## Memory Pool |
universe@720 | 91 | |
universe@720 | 92 | *Header file:* [mempool.h](api/mempool_8h.html) |
universe@720 | 93 | |
universe@720 | 94 | ### Basic Memory Pool |
universe@720 | 95 | |
universe@720 | 96 | *Header file:* [basic_mempool.h](api/basic__mempool_8h.html) |
universe@720 | 97 | |
universe@720 | 98 | ## Iterator |
universe@720 | 99 | |
universe@720 | 100 | *Header file:* [iterator.h](api/iterator_8h.html) |
universe@720 | 101 | |
universe@720 | 102 | ## Collection |
universe@720 | 103 | |
universe@720 | 104 | *Header file:* [collection.h](api/collection_8h.html) |
universe@720 | 105 | |
universe@720 | 106 | ## List |
universe@720 | 107 | |
universe@720 | 108 | *Header file:* [list.h](api/list_8h.html) |
universe@720 | 109 | |
universe@720 | 110 | ### Linked List |
universe@720 | 111 | |
universe@720 | 112 | *Header file:* [linked_list.h](api/linked__list_8h.html) |
universe@720 | 113 | |
universe@720 | 114 | ### Array List |
universe@720 | 115 | |
universe@720 | 116 | *Header file:* [array_list.h](api/array__list_8h.html) |
universe@720 | 117 | |
universe@720 | 118 | ## Map |
universe@720 | 119 | |
universe@720 | 120 | *Header file:* [map.h](api/map_8h.html) |
universe@720 | 121 | |
universe@720 | 122 | ### Hash Map |
universe@720 | 123 | |
universe@720 | 124 | *Header file:* [hash_map.h](api/hash__map_8h.html) |
universe@720 | 125 | |
universe@720 | 126 | ## Utilities |
universe@720 | 127 | |
universe@720 | 128 | *Header file:* [utils.h](api/utils_8h.html) |
universe@720 | 129 | |
universe@724 | 130 | UCX provides some utilities for routine tasks. Most of them are simple macros, like e.g. the `cx_for_n()` macro, |
universe@724 | 131 | creating a `for` loop counting from zero to (n-1) which is extremely useful to traverse the indices of |
universe@724 | 132 | an array. |
universe@724 | 133 | |
universe@724 | 134 | But the most useful utilities are the *stream copy* functions, which provide a simple way to copy all - or a |
universe@724 | 135 | bounded amount of - data from one stream to another. Since the read/write functions of a UCX buffer are |
universe@724 | 136 | fully compatible with stream read/write functions, you can easily transfer data from file or network streams to |
universe@724 | 137 | a UCX buffer or vice-versa. |
universe@724 | 138 | |
universe@724 | 139 | The following example shows, how easy it is to read the contents of a file into a buffer: |
universe@724 | 140 | ```c |
universe@724 | 141 | FILE *inputfile = fopen(infilename, "r"); |
universe@724 | 142 | if (inputfile) { |
universe@724 | 143 | CxBuffer fbuf; |
universe@724 | 144 | cxBufferInit(&fbuf, NULL, 4096, NULL, CX_BUFFER_AUTO_EXTEND); |
universe@724 | 145 | cx_stream_copy(inputfile, &fbuf, |
universe@724 | 146 | (cx_read_func) fread, |
universe@724 | 147 | (cx_write_func) cxBufferWrite); |
universe@724 | 148 | fclose(inputfile); |
universe@724 | 149 | |
universe@724 | 150 | // ... do something meaningful with the contents ... |
universe@724 | 151 | |
universe@724 | 152 | cxBufferDestroy(&fbuf); |
universe@724 | 153 | } else { |
universe@724 | 154 | perror("Error opening input file"); |
universe@724 | 155 | if (fout != stdout) { |
universe@724 | 156 | fclose(fout); |
universe@724 | 157 | } |
universe@724 | 158 | } |
universe@724 | 159 | ``` |
universe@724 | 160 | |
universe@720 | 161 | ### Printf Functions |
universe@720 | 162 | |
universe@720 | 163 | *Header file:* [printf.h](api/printf_8h.html) |
universe@720 | 164 | |
universe@720 | 165 | ### Compare Functions |
universe@720 | 166 | |
universe@720 | 167 | *Header file:* [compare.h](api/compare_8h.html) |