docs/src/features.md

Wed, 28 Jun 2023 19:18:01 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 28 Jun 2023 19:18:01 +0200
changeset 726
44986c0e2b05
parent 725
c9b882bef838
child 727
d92a59f5d261
permissions
-rw-r--r--

add a low-level stdlib-based cx_reallocate()

---
title: UCX Features
---

<div id="modules">

------------------------ -------------------------  -------------------  ---------------------------------
[Allocator](#allocator)  [String](#string)          [Buffer](#buffer)    [Memory&nbsp;Pool](#memory-pool)
[Iterator](#iterator)    [Collection](#collection)  [List](#list)        [Map](#map)
[Utilities](#utilities)
------------------------ -------------------------  -------------------  ---------------------------------

</div>

## Allocator

*Header file:* [allocator.h](api/allocator_8h.html)  

The UCX allocator provides an interface for implementing an own memory allocation mechanism.
Various function in UCX provide an additional alternative signature that takes an allocator as
argument. A default allocator implementation using the stdlib memory management functions is
available via the global symbol `cxDefaultAllocator`.

If you want to define your own allocator, you need to initialize the `CxAllocator` structure
with a pointer to an allocator class (containing function pointers for the memory management
functions) and an optional pointer to an arbitrary memory region that can be used to store
state information for the allocator. An example is shown below:

```c
struct my_allocator_state {
    size_t total;
    size_t avail;
    char[] mem;
};

static cx_allocator_class my_allocator_class = {
        my_malloc_impl,
        my_realloc_impl,   // all these functions are somewhere defined
        my_calloc_impl,
        my_free_impl
};

CxAllocator create_my_allocator(size_t n) {
    CxAllocator alloc;
    alloc.cl = &my_allocator_class;
    alloc.data = calloc(1, sizeof(struct my_allocator_state) + n);
    return alloc;
}

void free_my_allocator(CxAllocator *alloc) {
    free(alloc.data);
    free(alloc);
}
```

## String

*Header file:* [string.h](api/string_8h.html)

UCX strings come in two variants: immutable (`cxstring`) and mutable (`cxmutstr`).
The functions of UCX are designed to work with immutable strings by default but in situations where it is necessary,
the API also provides alternative functions that work directly with mutable strings.
Functions that change a string in-place are, of course, only accepting mutable strings.

When you are using UCX functions, or defining your own functions, you are sometimes facing the "problem",
that the function only accepts arguments of type `cxstring` but you only have a `cxmutstr` at hand.
In this case you _should not_ introduce a wrapper function that accepts the `cxmutstr`,
but instead you should use the `cx_strcast()` function to cast the argument to the correct type.

In general, UCX strings are **not** necessarily zero-terminated. If a function guarantees to return zero-terminated
string, it is explicitly mentioned in the documentation of the respective function.
As a rule of thumb, you _should not_ pass the strings of a UCX string structure to another API without explicitly
ensuring that the string is zero-terminated.

## Buffer

*Header file:* [buffer.h](api/buffer_8h.html)

Instances of this buffer implementation can be used to read from or write to memory like you would do with a stream.
This allows the use of `cx_stream_copy()` (see [Utilities](#utilities)) to copy contents from one buffer to another,
or from a file or network streams to the buffer and vice-versa.

More features for convenient use of the buffer can be enabled, like automatic memory management and automatic
resizing of the buffer space.

Since UCX 3.0, the buffer also supports automatic flushing of contents to another stream (or buffer) as an alternative
to automatically resizing the buffer space.
Please refer to the API doc for the fields prefixed with `flush_` to learn more. 

## Memory Pool

*Header file:* [mempool.h](api/mempool_8h.html)

### Basic Memory Pool

*Header file:* [basic_mempool.h](api/basic__mempool_8h.html)

## Iterator

*Header file:* [iterator.h](api/iterator_8h.html)

## Collection

*Header file:* [collection.h](api/collection_8h.html)

## List

*Header file:* [list.h](api/list_8h.html)

### Linked List

*Header file:* [linked_list.h](api/linked__list_8h.html)

### Array List

*Header file:* [array_list.h](api/array__list_8h.html)

## Map

*Header file:* [map.h](api/map_8h.html)

### Hash Map

*Header file:* [hash_map.h](api/hash__map_8h.html)

## Utilities

*Header file:* [utils.h](api/utils_8h.html)

UCX provides some utilities for routine tasks. Most of them are simple macros, like e.g. the `cx_for_n()` macro,
creating a `for` loop counting from zero to (n-1) which is extremely useful to traverse the indices of
an array.

But the most useful utilities are the *stream copy* functions, which provide a simple way to copy all - or a
bounded amount of - data from one stream to another. Since the read/write functions of a UCX buffer are
fully compatible with stream read/write functions, you can easily transfer data from file or network streams to
a UCX buffer or vice-versa.

The following example shows, how easy it is to read the contents of a file into a buffer:
```c
FILE *inputfile = fopen(infilename, "r");
if (inputfile) {
    CxBuffer fbuf;
    cxBufferInit(&fbuf, NULL, 4096, NULL, CX_BUFFER_AUTO_EXTEND);
    cx_stream_copy(inputfile, &fbuf,
                   (cx_read_func) fread,
                   (cx_write_func) cxBufferWrite);
    fclose(inputfile);
    
    // ... do something meaningful with the contents ...
    
    cxBufferDestroy(&fbuf);
} else {
    perror("Error opening input file");
    if (fout != stdout) {
        fclose(fout);
    }
}
```

### Printf Functions

*Header file:* [printf.h](api/printf_8h.html)

In this utility header you can find `printf()`-like functions that can write the formatted output to an arbitrary
stream (or UCX buffer, resp.), or to memory allocated by an allocator within a single function call.
With the help of these convenience functions, you do not need to `snprintf` your string to a temporary buffer anymore,
plus you do not need to worry about too small buffer sizes, because the functions will automatically allocate enough
memory to contain the entire formatted string.

### Compare Functions

*Header file:* [compare.h](api/compare_8h.html)

This header file contains a collection of compare functions for various data types.
Their signatures are designed to be compatible with the `cx_compare_func` function pointer type.

mercurial