STAR - Services, Templates, and Resources

What is it?

STAR is a C++ project cross-platform development framework that is intended to
do most of the grunt-work necessary for creating application programs, namely
a event-driven methedology.  It was originally written under OS-9/68000 (no,
that's not a Macintosh thing, see but most of the
real development occurred under Linux.  It has been ported to Win32 and should
be reasonably easy to extend to other operating systems as well.

Why was it written?

STAR was originally written to be the base layer for a series of continuous-
time, multi-player network games being designed and written by myself (Brian
White) and some of my friends (Andrew Beere, Behan Webster, Takashi Toyooka,
Kevin Rockel, and Todd "Snoopy" Harper).  Unfortunately, Verisim, the little
company we formed to do the work, went out of business before we were able to
actually release one of these gems.  (There is a new company called Verisim
using the domain, but they have nothing to do with us.)  STAR was
the generic support layer.  In fact, there are many modules from that original
project still not found in the STAR source code today simply because they
could be suffering from a fair degree of bit-rot given that STAR has evolved
for use with other projects.  These missing modules include, but are not
limited to, serial port drivers, parallel port drivers, layered database
access, useful Qt objecs, GL object compression and display (with mouse-driver
camera control), object-oriented database with data-dictionary support,
cross-platform data exchange, and TCL access code generator.  It was quite a
large project.

Tell me about the base.

STAR uses an event-driven object-oriented methodology.  You create objects to
handle data and then tell them what object/method to call-back when certain
things happen.  A central customizable event loop deals with checking what
system events have occurred and calling the appropriate modules.  This works
with Unix, with or without X, and also with Win32, though currently only with
direct API calls and not using MFC.  It has support for multi-threaded
applications including locking mechanisims to deal with concurrency issues.
In my opinion, you should never, ever, ever use a multi-threaded technique for
solving a problem if there is another way!  The difficulties it adds are
incalcuable and can be extremely difficult to reproduce/diagnose.  That said,
however, you have no chance of making it work without support at the very base
of whatever system you design.

autolist -- a global-list handler to allow run-time gathering of information
about what components are available.  This system allows the program to learn,
at start-up, about the resources it has access to so that it is not necessary
to recompile base systems every time an external piece of code wants to add
something to it.  The logging system, for example, uses this to learn what
error strings to associate with integer error codes.

dataio -- a base input/output system.  Different than streams, the DataIo
class provides the central I/O management, including call-backs, for STAR.
Derived classes allow ordinary unix paths, sockets, programs, pipes, etc. all
to be accessed and managed in an identical manner.  In additions, there is a
type of DataIo class called a "filter" which can wrap another DataIo object
(including another filter) for transparent conversion of the data stream.  In
fact, with only the creation of a few local variables, it is possible to read
a file from disk, compress it, encrypt it, uuencoded it, and write it back out
to another file with one (1) line of code.  Reversing the process means only
switching two variables.

debug -- support for integrating with local debugger.  The code in this module
just provides some assistance for setting breakpoints when certain events
occur and even dumping core file (without stopping the program) if so desired.

errors -- a hierarchy of exceptions that are used for reporting failures.
Exceptions are a great feature of C++ to ensure that unexpected results do not
go unhandled.  The hierachy here makes it easy for a program to trap errors up
to a certain severity while letting more serious problems continue up tha call
stack.  Exceptions also generate log messages.

events -- central event management.  The events system handles getting events
from the operating system and passing them on to the appropriate modules.
Both Unix and Win32 are fully supported.

logfile -- logging interface.  The logging system reports messages, including
where in the source code they were generated, for tracking and debugging of
problems.  It is configurable as to what level of messages actually get stored
and can store those messages on any DataIo path.

pointer -- smart pointers with reference counting and garbage collection.
Dynamically allocated memory is always a difficulty but exceptions make it a
real problem.  Unless allocated memory is tied to an object with a descructor,
any thrown exception will cause a memory leak as the stack is unwound and the
pointer is destroyed without its associated memory being deallocated.
Smart-pointers take care of all that as well as allowing multiple pointers to
the same memory and only deallocated it when the last "reference" is
destructed.  They are fast, efficient, and offer overloaded operators so they
can be used (i.e. "->") just like ordinary pointers with performance penalty
(assuming a reasonably smart compiler like gcc).

stats -- statistics reporting.  Any module can register itself (an autolist)
as being able to provide statistics information.  It will then be called on a
periodic basis to dump those statistics for later analysis and graphing.  This
doesn't sound much like a "base" service, but since it is called by the event
loop and used by smart-pointers, it is included here.

threads -- multi-threaded application support.  By creating a derived class
from "Thread", a new thread of execution is created for your program.  That
thread can run normally, or can be restarted automatically on a periodic
basis.  Full support for semaphores is included.

timers -- system time information.  These functions provide
platform-independant access to system timers like a realtime second and
microsecond timer, as well as a system independant "timestamp" timer that can
be used between machines.

Tell me about IO.

The I/O system is all derived from the base DataIo class.  Current modules

fileio -- filesystem access.  This provides access to files on disk by their

socketio -- network socket access.  This system provides a high-level view to
a socket (really only useful for TCP sockets) so they can be read/written like
any other file.  Another "Socket" class (as opposed to "SocketIo") is
available for lower-level socket access, including improved TCP listeners and
UDP connections.

Tell me about the utilies.

A great many utility functions, classes, and methods are included.  Some are
just header files while others have support code.

callback -- callback function support.  These classes hold function pointers
or class/method pointers so they can be called at a later time.

charstar -- wrapper for "char*" for STL containers.  This class is a simple
wrapper around the standard "char*" type that allows them to be used within
STL containers and be sorted/accessed by the contents being pointed instead
of the value of the pointer.

crc -- cyclic redundancy checks.  These classes (well, currently only Crc32)
provide a simplistic form of data integrity checking.

endian -- conversion between big-endian and little-endian architectures.  When
passing data between machines with different architectures, it is necessary to
agree upon how bytes within a larger word will be organized when stored in
memory.  This module provides functions to do that conversion.

hmac -- hashed message authentication codes.  This is a wrapper around an
authentication method like MD5 to provide increased security of messages.

md5 -- message digest #5.  This is a standard digest for provide a much more
reliable and secure integrity check than a simple CRC.

rcfile -- configuration file access.  These functions provide parsing and
writing of simple key/value configuration files.

system -- a collection of system and architecture independant definitions.  It
is the types defined in here that allow much of the cross-platform