libstddjb
libskarnet
skalibs
Software
skarnet.org

# The `genwrite` library interface

The following functions are declared in the `skalibs/genwrite.h` header, and implemented in the `libskarnet.a` or `libskarnet.so` library.

## General information

`genwrite` is syntactic sugar to help write functions that might want to write either to memory or to a file descriptor.

Writing to memory is achieved via appending to a stralloc; writing to a file descriptor is achieved via appending to a buffer or a bufalloc.

## Usage

A `genwrite_t` structure contains a pointer to a function that writes stuff to the target without flushing it (which can be `genwrite_put_stralloc`, `genwrite_put_buffer`, `genwrite_put_bufalloc` or any compatible user-defined function) in `.put`, a pointer to a function that flushes the target (which can be `genwrite_flush_stralloc`, `genwrite_flush_buffer`, `genwrite_flush_bufalloc` or any compatible user-defined function) in `.flush`, and a pointer to the target writing structure in `.target`.

Users should define a `genwrite_t` first, using the provided functions, and give applications a pointer `gp` to this structure. To write len characters at position s to the target, the application should then call `(*gp->put)(gp->target, s, len)`. When it is done writing, the application should call `(*gp->flush)(gp->target)` to flush the output.

`genwrite_stdout` and `genwrite_stderr` are predefined; they write to `buffer_1` and `buffer_2` respectively.

## Macros

`GENWRITE_STRALLOC_INIT(sa)`
Declares a `genwrite_t` writing to the stralloc *sa.

`GENWRITE_BUFFER_INIT(b)`
Declares a `genwrite_t` writing to the buffer *b. Use of such a buffer might interact badly with nonblocking I/O.

`GENWRITE_BUFALLOC_INIT(ba)`
Declares a `genwrite_t` writing to the bufalloc *ba.

## Note

Object-oriented programming in C is inefficient and cumbersome. It is usually possible to avoid it in Unix system programming, because Unix primitives are often generic enough. Unfortunately, it is not the case here: Unix does not provide an abstraction representing either a file or a memory buffer. So an object-oriented approach is unavoidable.