StreamModules provide a facility for building a program out of small components that are connected by bidirectional streams of data. There are many programs that fit this model, or have large pieces that fit this model. One example is the tokenizer -> preprocessor -> compiler -> optimizer -> assembler chain for traditional compilation of a C program. Another is the wire <-> ethernet <-> IP <-> TCP <-> socket <-> apache chain for an http connnection to a webserver.
Though the entire StreamModule system is designed such that many of its individual pieces can be used independently, the StreamModule subsystem is its heart. The other pieces are mainly designed to provide a supporting framework for this piece.
StreamModule's are connected by StreamModule::Plug objects. These objects are created by a StreamModule, and are owned by that module. They can be plugged into other plugs from other modules. Each plug is created on a 'side' of the StreamModule.
A side is always identified by an integer. Usually only a small range of integer values are valued, and a StreamModule class will usually have an enum inside it detailing all the valid values side may take.
A side represents a protocol role. Now, that's kind of an airy description, and here's what it really means.
A StreamModule can be thought of as a processor of data with multiple inputs and outputs and its own internal state. A side represets a distinct IO stream for this data processor. Some processors have the job of taking in one copy of the data on one side, and making many copies on the other side. The side on which many copies are made is just one side because the copies are indistinguishable, but there are still multiple plugs on that side because there are multiple outputs, even if any given output is indistinguishable from another.
Since a StreamModule bears a strong resemblance to a component in a Unix pipeline, here are a few examples from the Unix world:
grep
grep
has three sides. One side takes a file,
and the other spits out the matching lines, and the last
spits out error messages.sh
sh
, when used to run a shellscript, has four
sides. The first side is stdin
, the second,
stdout
, the third stderr
, and the
last is the file containing the shellscript.tee
tee
has three sides. The first is the input
side, the second, the output side (which has multiple
'plugs' because tee writes its output to multiple places)
and the error side on which tee write error messages.StreamModule::Plugs move StrChunks around using eachothers i_Read and i_Write methods to pull data from, and push data into another StreamModule. These methods are protected. StreamModule::Plugs use their internal 'readable' and 'writeable' state to determine when these methods are called.