[Home]
[Search]
[D]
Open-RJ is an open-source library that implements readers of the Record-Jar structured text file format, designed and implemented by Matthew Wilson, as an exemplar project for his column Positive Integration in C/C++ Users Journal.
It is implemented in C & C++, with a C-API. The implementation of the basic library is platform-independent. Mappings are provided to several languages (including C++, D, Ruby and STL), and others (COM, Java, .NET, Perl, Python) are planned. In addition to platform-independence, the library focuses on small runtime costs - memory and speed - and the classic UNIX attributes of discoverability and visibility.
As described in the excellent book "The Art Of UNIX Programming", a Record-Jar structured format file consists of records and fields.
A field is a single line - optionally extended with trailing '\' - that contains a name, separated from an optional value by ':'.
A record is a list of fields, whose contents are arbitrary and can vary between records in the same database. Records are separated by a line that begins with "%%". The record separator also acts as a comment, so anything can come on a record separator line after the first two characters.
A database is a correctly parsed Record-Jar file. The Open-RJ API (and language mappings) provide access to all the records in the database and the complete set of fields. Hence, you may work with fields on a per-record basis, or treat the database as a single record and with all fields in the database.
A very simple Record-Jar file, representing a Pets Database, is shown below:
Name: Elsa
Species: Dog
Breed: Mixed
%%
Name: Fluffy Kitten
Species: Cat
%%
Name: Rebel
Species: Dog
Breed: German \
Shepherd
%%
Name: Pepper
Species: Dog
Breed: Border Collie
%%
Name: Samson
Species: Dog
Breed: Ridgeback
%%
Name: Sheltie
Species: Dog
Breed: Shetland \
Sheepdog
%%
Name: Sparky
Species: Cat
%%
And that's pretty much all there is to it. There are no restrictions on what fields may be in a record, and no controls over whether all records have the same fields or not. That's the job of higher layers of application functionality. We keep Record-Jar simple so it's reliable, portable and fast, and it's those things in spades!
The D mapping of Open-RJ is packaged with Phobos in the std.openrj module. It consists of four classes:
and one enumeration: The basic usage is as follows:
char[] contents = cast(char[])(std.file.read("pets.orj"));
Database db = new Database(contents, ORJ_FLAG.ELIDE_BLANK_RECORDS);
foreach(Record r; db)
{
. . . // Process the record
}
or by indexed lookup (which returns a Record instance):
for(int i = 0; i < db.length; ++i)
{
Record r = db[i];
. . . // Process the record
}
Processing of the record may be done by either ...
foreach(Field f; r)
{
char[] name = f.name;
char[] value = f.value;
printf(" %.*s=%.*s\n", name, value); // e.g. "Breed=German Shepherd"
}
or by indexed lookup (which returns a Field instance):
for(int i = 0; i < r.length; ++i)
{
Field f = r[i];
. . . // Process the field
}
printf(" The value of the \"Species\" field is %.*s\n", r["Species"]);
std.openrj.Database
The Database class has the following methods:
std.openrj.Record
The Record class has the following methods:
std.openrj.Field
The Field class has the following properties:
methods:
std.openrj.OpenRJException
Base exception class used by the openrj module.
std.openrj.DatabaseException
Exception class, derived from OpenRJException,
thrown if the database Jar file cannot be opened, or its contents do not represent a
correctly formed Open-RJ database.
The DatabaseException class has the following properties: methods:
std.openrj.InvalidKeyException
Exception class, derived from OpenRJException,
thrown when named fields are not found.
std.openrj.ORJ_FLAG
Enumeration, whose values control the loading behaviour of the
Database class.
std.openrj.ORJRC
Enumeration representing general database processing errors encountered in
the loading of the Database class.
std.openrj.ORJ_PARSE_ERROR
Enumeration representing database parsing errors encountered in
the loading of the Database class.