Concha is a library of C structures and functions that illustrates how to productively apply object oriented techniques like interfaces, abstraction, polymorphism, and inheritance to C applications. Source and Sink are simple byte-oriented abstract interfaces that allow applications to be written which are agnostic as to from where their input comes or to where their output goes. Sources provide a read, a push, and a close method,while Sinks provide a write and a close method. Concha provides a variety of implementations of the Source and Sink interfaces. Here are some examples.
- Source and Sink define the abstract one byte at a time interfaces. (These abstractions also define multi-byte I/O functions, but these are implemented by merely calling the one byte at a time functions multiple times.)
- BufferSource and BufferSink implement the Source and Sink interfaces against fixed-sized memory buffers.
- StreamSource and StreamSink support standard I/O streams.
- DescriptorSource and DescriptorSink support file descriptors, for example sockets.
- FileSource and FileSink extend StreamSource and StreamSource by allowing the caller to just specify a file system path name.
- CompositeSource, ExpanderSink, BoundedSource, UnclosingSource, UnclosingSink, ClosingSource, and ClosingSink alter the behavior of other Sources and Sinks in useful ways.
- Fletcher8Source and Fletcher8Sink automatically handle the generation and verification of Flechter 8-bit checksums on other Sources and Sinks.
- RingBuffer demonstrates how to implement an object the exposes both a Source and a Sink interface.
- SpanningSource and SpanningSink extend the Source and Sink interfaces to offer native multi-byte capability.
- DescriptorSpanningSource and DescriptorSpanningSink implement the SpanningSource and SpanningSink interfaces for file descriptors.
Sources and Sinks can be easily combined to implement very complex behavior while requiring that a minimal amount of application data be buffered at a time in a memory contrained system. The availability of a push method allows algorithms that can be described using LL(1) or LALR(1) grammers (e.g. state machines, simple parsers, and many comdecom, imaging and codec algorithms) to be easily implemented.
I have successfully used the design patterns in Concha in an embedded C-based proprietary commercial product for one of my clients. Concha represents a clean-room reimplementation of those patterns licensed under the Desperado modified LGPL that allows static linking without viral licensing implications. (For those familiar with the prior implementation, this new version differs substantially and is probably completely incompatible; the prior proprietary version was written for a non-POSIX platform.)
Concha can be found on GitHub here.
Here are some articles that my alter-ego Chip Overclock has written about Concha: