docs/Writerside/topics/streams.h.md

Tue, 11 Mar 2025 11:10:19 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 11 Mar 2025 11:10:19 +0100
changeset 1242
bbb734f73392
parent 1210
2ad0cf0f314b
permissions
-rw-r--r--

downgrade info regarding stream_copy from warning to note

relates to #451

# Data Streams

Stream copy functions provide a way to copy all - or a  limited amount of - data from one stream to another.

Since the read/write functions of a [UCX buffer](buffer.h.md) are fully compatible with stream read/write functions,
you can, for example, easily transfer data from a file or network stream to a UCX buffer or vice versa.

## Overview
```C
#include <cx/streams.h>

size_t cx_stream_copy(void *src, void *dest,
        cx_read_func rfnc, cx_write_func wfnc);
        
size_t cx_stream_ncopy(void *src, void *dest,
        cx_read_func rfnc, cx_write_func wfnc, size_t n);

size_t cx_stream_bcopy(void *src, void *dest,
        cx_read_func rfnc, cx_write_func wfnc,
        char *buf, size_t bufsize);

size_t cx_stream_bncopy(void *src, void *dest,
        cx_read_func rfnc, cx_write_func wfnc,
        char *buf, size_t bufsize, size_t n);
``` 

## Description

All functions in the stream copy family use the `rfnc` to read data from `src`
and use the `wfnc` to write the data to `dest`.

The `cx_stream_copy()` function always uses internal stack memory as a temporary buffer for the read bytes.
The `cx_stream_bcopy()` function uses either a pre-initialized buffer `buf` of length `bufsize`
or, if `buf` is `NULL`, an internal heap-allocated buffer.

The `cx_stream_ncopy()` function behaves like `cx_stream_copy()` except, that it reads at most `n` bytes
(and the same is true for `cx_stream_bncopy()` and `cx_stream_bcopy()`).


> When you are reading from a stream where you cannot track the position, there is the possibility that
> data gets lost when the destination does not accept all the bytes read from the source.
> While the stream copy functions do report how many bytes were _successfully_ copied
> to the destination, this might - in certain cases - not be the exact number of read items.
> 
> To mitigate the risk, you should make sure that the destination can always accept all read bytes and
> a possible bottleneck is only introduced by the source.
>{style="note"}

> The size of the internal _stack_ buffer in `cx_stream_copy()` and `cx_stream_ncopy()` can be
> set during compilation via the `CX_STREAM_COPY_BUF_SIZE` macro.
> Similarly, the size for the implicitly allocated _heap_ buffer in can be
> configured via the `CX_STREAM_BCOPY_BUF_SIZE` macro.
> Refer to the [build instructions](install.md#compile-time-options) for the details.

## Example

The following example shows, how 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,
                   cxBufferWriteFunc);
    fclose(inputfile);
    
    // ... do something meaningful with the contents ...
    
    cxBufferDestroy(&fbuf);
} else {
    perror("Error opening input file");
}
```


<seealso>
<category ref="apidoc">
<a href="https://ucx.sourceforge.io/api/streams_8h.html">streams.h</a>
</category>
</seealso>

mercurial