ColorBox2 — Overview

Directories and files overview

The subdirectories of the source tree contain following parts of the project:

The build and installation process

The compilation process works as by many other projects by running the following two commands in the root directory of the source tree:

./configure
make

The configure script will check for the presence of C++ compiler, Apache web server, MySQL client library and other compulsory components. It will also create the makefiles and configure headers from the gathered information. Some very important values are stored in src/config.h — the macro CB2_DESC constains the string description of the project (including version number read from VERSION file) and the macro CB2_FLAGS contains the compile flags for compiling end programmer's web applications (these flags are stored to the Just-In-Time compiler binary and supplied during the on-the-fly compilation).

The build process continues then by running make with the following steps:

You would need root user privileges to install ColorBox2 to the system by running:

make install

Let's assume that the default installation prefix is /usr/local. The installation will do the following steps:

  1. If not already present, create a new system user "cb2" with no shell and a home directory /var/cb2.
  2. Copy the Just-In-Time compiler to /usr/local/bin/cb2jit. The binary file is setuid for the user "cb2", thus the on-the-fly compilation later on will always be done with the priviledges of this user.
  3. Copy the public header files to /usr/local/include/cb2.
  4. Copy the shared ColorBox2 library to /usr/local/lib. A symlink libcb2.so is created, too.
  5. Run ldconfig to recreate the shared libraries cache.
  6. Use the apxs tool to install the web server module (mod_cb2.so) to the propper location acknowledged by the Apache web server.
  7. Create directories /var/cb2/bin and /var/cb2/src.

In case of the first installation you have to add some additional directives to the Apache configuration file. Locate your main Apache configuration file and add directives described in this file. The directives for loading the ColorBox2 server module

LoadModule cb2_module		/usr/lib/apache/mod_cb2.so
AddModule mod_cb2.c

should be already present (there are filled in by the apxs tool). But to allow the ColorBox2 applications to be processed you have to add at least these four directives:

AddType		application/x-cb2		.cb2
CB2SourcePath /var/cb2/src
CB2BinaryPath /var/cb2/bin
CB2JIT /usr/local/bin/cb2jit

The first directive will instruct Apache to handle the files with the extension .cb2 as ColorBox2 description files. The other directives will set the path for the sources and binaries of the web applications and the path to the Just-In-Time compiler.

The last two directives are mandantory. CB2Compile allows the Just-In-Time compiler to be run (otherwise just already precompiled binary applications will be run). CB2Verbose will give the web server module the permission to display verbose warnings and errors (which can be a possible security risk because of showing absolute file paths, etc.).

To make the changes apply, restart Apache server (i.e. /etc/init.d/apache restart).

Core components (src/common/common.h, src/common/common.cpp)

Core components represent a set of classes and macros which are common to the whole project. All global types and variables (except macros) in the whole ColorBox2 project are placed in the CB2 namespace.

There are special aliases type aliases for the most common types, i.e. String for PString< char>, Map and MapList for PMap< String, String> and PMapList< String, String>, etc.

Class

Class is the base of all classes in ColorBox2. The only public variable int tag can be used as user data storage.

Iterator< Tcontainer, Tref, Tmemb>

Iterator template is a generic class for creating iterators. The template parameters define:

The primary purpose of an iterator is to be created, derefenced (to access the item) and incremented using the prefix ++ operator (to move to the next item).

RevIterator< Tcontainer, Tref, Tmemb>

Reverse iterator has the same purpose as a normal iterator, except that it iterates using prefix decrement operator (--) from the last to the first item in the container type.

Array< Tmemb>

Low-level data storage which stores its items in a dynamically allocated memory buffer. The data items are stored as bit-by-bit copies (without the use of copy constructors or assignments), so the class is intended for storing simple data types (integers, characters, etc.).

The accesses to the array are range checked (access by iterators or direct access), new items can be added to the beginning or end of the array. The standard behaviour of the array is to grow in steps (default 4096 items) and never shrink (shrinking can be forced by Discart(true)). Multiple items can be cut out or inserted from another array. The array can be also casted to a plain "item pointer" (which is certainly then not range checked).

PString< Tchar>

ColorBox2's string implementation uses Array< Tchar> as data storage class, so it is suitable for simple data types (like char). The class is intended to be as universal as possible, so you can consruct and assign PString from C-style string (i.e. char * ), STL string, counted character array, integer or float numeric types (the standard representation is decimal). The string is represented as counted array, so it can contain NULL characters (but a special NULL character is always appended for safe conversion to C-style string).

Automatic conversion to other types (C-style string, STL string, numeric types) are done automatically where possible (an exception is thrown when the conversion is not possible). Single characters can be accessed by index or by iterator.

Other operators and methods are concatenation, substring copy, search and replacement. Methods like HTML(), HTMLdecode(), URL(), URLdecode(), etc. can be used to escape and unescape the string for various purposes.

List< Tmemb>

The List template stores items of the type Tmemb. Unlike Array class, the items are stored in a object-safe manner, the copy operation is done using the copy constructor.

Internally the data are stored as bi-directional linked list. Every item is stored either as a pointer to the external instance (operators <lt; and >gt;) or as a local copy which is deallocated during the destruction of the list (methods PushBack() and PushFront()).

The items can be accessed either by an index or by an interator.

PMap< Tkey, Tvalue>

Map stores a single key=value pair. The value can be either filled in or NULL (SQL syntax). Both the key and the value can be retrieved (if not NULL) and tested for NULL.

PMapList< Tkey, Tvalue>

This template is a combination of List and PMap, but inlike the obvious combination this class allows to access the values by the keys. So it works as an associative array.

Tree< Tmemb>

The Tree template represents a simple generic tree. Each node of the tree can store a value (either a pointer or a local copy) and any number of subtrees. The subtrees are accessible by iterators.

PStringTokenizer< Tchar>

This template creates a list of strings from a string splitted by a delimiter. The tokens can be accessed either by an index or by an iterator.

Exception, ExceptionRange, ExceptionConversion, etc.

The Exception class is the basic class for all exceptions generated in the ColorBox2 code. Special exceptions are thrown on range check error, conversion error, etc. The What() method can be used to get the description of the exception (if supplied).

Several macros (like CB2_ASSERT, CB2_RANGECHECK) are available to throw exceptions according to a condition test and in the same time report the file and line number of the exception occurance.

Web server module (src/mod_cb2/mod_cb2.h, src/mod_cb2/mod_cb2.c)

The web server module has several purpose. The main purpose is to execute the binary file of the web application, push the POST and GET parameters from the client to the application and get the output of the application. The POST parameters are pushed to the standard input of the web application, GET parameters are pushed as the first command-line parameter.

Another purpose of the module is to run the Just-In-Time compiler to check, whether the binary file is up-to-date with the source files. The Just-In-Time compiler gets as its parameters the source path, binary path and the relative path of the application.

Last (but not least) purpose of the module is to check for any malfunction of the compiler or application. The succesful run of the application is indicated by a return value of 0 (however when the application had already supplied some output data, the return value must be silentry ignored). The Just-In-Time compiler indicates its status also by the return value and in case of an error both standard and error output is displayed (as text).

The execution process is as follows:

  1. If the URL is http://www.example.org/dir/file.cb2, the contents of the file $HTTP_ROOT/dir/file.cb2 is read (where $HTTP_ROOT is the Apache document root directory. Check for safe file permissions.
  2. The contents of the .cb2 file is interpreted as relative path to the binary file. The binary file is checked for existence and safe file permissions.
  3. If the configuration directive CB2Compile is set, the Just-In-Time compiler from CB2JIT is executed (first command-line parameter is CB2BinaryPath, second is CB2SourcePath and third is the relative path). On error the standard output and error output of the compiler is displayed and the process is stopped.
  4. The binary file from CB2BinaryPath (+ the relative path) is executed. The first command-line parameter are the GET parameters (query from URL), the POST parameters are pushed to the standard input.
  5. The output of the application is forwarded to the client until end of output.

Just-In-Time compiler

Just-In-Time compiler is actually a wrapper which checks whether the given binary file is up-to-date. It is usually installed setuid to the user "cb2" which gives the binary files some sort of protection.

The Just-In-Time compiler gets three command-line parameters:

  1. Binary tree path.
  2. Source tree path.
  3. Relative path to the binary file.

The compiler splits the relative path to the directory component and filename component. The directory component is appended to the source tree path and the make utility is executed from this directory:

make 'CB2_FLAGS=-I/usr/include/mysql -lcb2 ... ' 'BIN_PATH=/var/cb2/bin/dir/...' filename

The argument CB2_FLAGS are compile flags for succesful compilation of the ColorBox2 application. BIN_PATH is the path component of the binary file. A typical Makefile looks like this:

$(BIN_PATH)/application.o: application.cpp application.h
	g++ $(CB2_FLAGS) -o $(BIN_PATH)/application.o application.cpp
	strip $(BIN_PATH)/application.o

The shared library

The shared library contains classes directly used by the web applications.

Main application (src/libcb2/Application.h, src/libcb2/Application.cpp)

To create a web application, it is essential to derive a new class from Application class and use the CB2_IMPLEMENT_APP macro, as this example shows:

#include <cb2/Application.h>

using namespace CB2;

class MyApplication : public Application {
	public:
		MyApplication();
};

MyApplication::MyApplication()
	: Application() {
	
	SetTemplate(new Template(" ... &&BODY; ... "), "BODY");
	
	/* ... */

}

CB2_IMPLEMENT_APP(App);

The Application derived class works as a placeholder for any other widgets and containers of the application. The SetTemplate() method sets the template of the application.

Widgets (src/libcb2/Widgets.h, src/libcb2/Widgets.cpp)

Widget is a visual component of an application. Every widget must have a parent (either an application class or a container, see below) which supplies a template for the widget. The widget then renders itself to the parent template.

Containers (src/libcb2/Widgets.h, src/libcb2/Containers.h, src/libcb2/Containers.cpp)

A container is a special kind of widget which generates the template for its nested widgets ("children") and arranges them in a special way. A typical example of the use of one container (ContainerBin stores nested widgets as they are created) and two widgets (one Spacer and one Paragraph):

MyApplication::MyApplication()
	: Application() {
	
	SetTemplate(...);
	
	ContainerBin * bin = new ContainerBin(*this);
	new Spacer(*bin, Size(10, Size::px));
	new Paragraph(*bin, "Some text in paragraph.");
	
}

Templates (src/libcb2/Template.h, src/libcb2/Template.cpp)

A template is the main mean to abstract application visual representation and functionality. A template is basically a string containing anchors (like &&ELEMENT;) which are substituted by the real contents of a widget or container (possibly another template with another anchors).

After the application generates the whole output, there should be no unsubstituted anchors in the main template.

Rich text (src/libcb2/Paragraph.h, src/libcb2/Paragraph.cpp)

The Text class stores a rich text — a string which can contain hyperlinks, different styles, etc. Such a rich text can be used as the contents of the Paragraph class.

Data sources (src/libcb2/DS.h, src/libcb2/DS.cpp)

Data sources represent an universal mean to access data. A data source is an object (descended from DataSource class), which can create query objects (Quory) for specific operations.

The operation is defined by a Domain which is actually a conjuctive-disjuctive normal form of a database query.