|         | 
     1 # Data Streams | 
|         | 
     2  | 
|         | 
     3 Stream copy functions provide a way to copy all - or a  limited amount of - data from one stream to another. | 
|         | 
     4  | 
|         | 
     5 Since the read/write functions of a [UCX buffer](buffer.h.md) are fully compatible with stream read/write functions, | 
|         | 
     6 you can, for example, easily transfer data from a file or network stream to a UCX buffer or vice versa. | 
|         | 
     7  | 
|         | 
     8 ## Overview | 
|         | 
     9 ```C | 
|         | 
    10 #include <cx/streams.h> | 
|         | 
    11  | 
|         | 
    12 size_t cx_stream_copy( | 
|         | 
    13     void *src, void *dest, | 
|         | 
    14     cx_read_func rfnc, cx_write_func wfnc | 
|         | 
    15 ); | 
|         | 
    16 size_t cx_stream_ncopy( | 
|         | 
    17     void *src, void *dest, | 
|         | 
    18     cx_read_func rfnc, cx_write_func wfnc, | 
|         | 
    19     size_t n | 
|         | 
    20 ); | 
|         | 
    21  | 
|         | 
    22 size_t cx_stream_bcopy( | 
|         | 
    23     void *src, void *dest, | 
|         | 
    24     cx_read_func rfnc, cx_write_func wfnc, | 
|         | 
    25     char *buf, size_t bufsize | 
|         | 
    26 ); | 
|         | 
    27 size_t cx_stream_bncopy( | 
|         | 
    28     void *src, void *dest, | 
|         | 
    29     cx_read_func rfnc, cx_write_func wfnc, | 
|         | 
    30     char *buf, size_t bufsize, | 
|         | 
    31     size_t n | 
|         | 
    32 ); | 
|         | 
    33 ```  | 
|         | 
    34  | 
|         | 
    35 ## Description | 
|         | 
    36  | 
|         | 
    37 All functions in the stream copy family use the `rfnc` to read data from `src` | 
|         | 
    38 and use the `wfnc` to write the data to `dest`. | 
|         | 
    39  | 
|         | 
    40 The `cx_stream_copy()` function always uses internal stack memory as a temporary buffer for the read bytes. | 
|         | 
    41 The `cx_stream_bcopy()` function uses either a pre-initialized buffer `buf` of length `bufsize` | 
|         | 
    42 or, if `buf` is `NULL`, an internal heap-allocated buffer. | 
|         | 
    43  | 
|         | 
    44 The `cx_stream_ncopy()` function behaves like `cx_stream_copy()` except, that it reads at most `n` bytes | 
|         | 
    45 (and the same is true for `cx_stream_bncopy()` and `cx_stream_bcopy()`). | 
|         | 
    46  | 
|         | 
    47  | 
|         | 
    48 <warning> | 
|         | 
    49 When you are reading from a stream where you cannot track the position, there is the possibility that | 
|         | 
    50 data gets lost when the destination does not accept all the bytes read from the source. | 
|         | 
    51 While the stream copy functions do report how many bytes were <emphasis>successfully</emphasis> copied | 
|         | 
    52 to the destination, this might - in certain cases - not be the exact number of read items. | 
|         | 
    53  | 
|         | 
    54 To mitigate the risk, you should make sure that the destination can always accept all read bytes and | 
|         | 
    55 a possible bottleneck is only introduced by the source. | 
|         | 
    56 </warning> | 
|         | 
    57  | 
|         | 
    58 > The size of the internal _stack_ buffer in `cx_stream_copy()` and `cx_stream_ncopy()` can be | 
|         | 
    59 > set during compilation via the `CX_STREAM_COPY_BUF_SIZE` macro. | 
|         | 
    60 > Similarly, the size for the implicitly allocated _heap_ buffer in can be | 
|         | 
    61 > configured via the `CX_STREAM_BCOPY_BUF_SIZE` macro. | 
|         | 
    62 > Refer to the [build instructions](install.md#compile-time-options) for the details. | 
|         | 
    63  | 
|         | 
    64 ## Example | 
|         | 
    65  | 
|         | 
    66 The following example shows, how to read the contents of a file into a buffer: | 
|         | 
    67 ```c | 
|         | 
    68 FILE *inputfile = fopen(infilename, "r"); | 
|         | 
    69 if (inputfile) { | 
|         | 
    70     CxBuffer fbuf; | 
|         | 
    71     cxBufferInit(&fbuf, NULL, 4096, NULL, CX_BUFFER_AUTO_EXTEND); | 
|         | 
    72     cx_stream_copy(inputfile, &fbuf, | 
|         | 
    73                    (cx_read_func) fread, | 
|         | 
    74                    cxBufferWriteFunc); | 
|         | 
    75     fclose(inputfile); | 
|         | 
    76      | 
|         | 
    77     // ... do something meaningful with the contents ... | 
|         | 
    78      | 
|         | 
    79     cxBufferDestroy(&fbuf); | 
|         | 
    80 } else { | 
|         | 
    81     perror("Error opening input file"); | 
|         | 
    82 } | 
|         | 
    83 ``` | 
|         | 
    84  | 
|         | 
    85  | 
|         | 
    86 <seealso> | 
|         | 
    87 <category ref="apidoc"> | 
|         | 
    88 <a href="https://ucx.sourceforge.io/api/streams_8h.html">streams.h</a> | 
|         | 
    89 </category> | 
|         | 
    90 </seealso> |