The environment class allows you to get or set the value of environment variables. The following example gets, sets and resets the environment variable TEST.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/environment.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// print the environment variable "TEST"
printf("TEST=%s\n",environment::getValue("TEST"));
// set the value of "TEST" to "value"
if (environment::setValue("TEST","value")) {
printf("TEST=%s\n",environment::getValue("TEST"));
} else {
printf("setValue() failed\n");
}
// set the value of "TEST" to "newvalue"
if (environment::setValue("TEST","newvalue")) {
printf("TEST=%s\n",environment::getValue("TEST"));
} else {
printf("setValue() failed\n");
}
// remove "TEST" from the environment
environment::remove("TEST");
// print the (non-existent) environment variable "TEST"
printf("TEST=%s\n",environment::getValue("TEST"));
printf("\n\n");
environment::print();
printf("\n\n");
environment::clear();
printf("\n\nclear?\n");
environment::print();
}
Using the commandline ClassMost programs take command line options in the option/value pair format:
program -option value -option value ...
or
program --option=value --option=value ...
The commandline class makes it easy to deal with command line options of either of these formats. Below is some code illustrating the use of the commandline class.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/commandline.h>
#include <rudiments/charstring.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
commandline cmdline(argc,argv);
// if -help was specified, display a usage message
if (cmdline.found("-help")) {
printf("usage: divide -divisor number -dividend number\n");
exit(0);
}
// If -divisor and -dividend are supplied, use them. Otherwise
// display an error message.
if (cmdline.found("-divisor") && cmdline.found("-dividend")) {
double divisor=charstring::toFloat(
cmdline.getValue("-divisor"));
double dividend=charstring::toFloat(
cmdline.getValue("-dividend"));
printf("%0.2f\n",divisor/dividend);
} else {
printf("You must supply a divisor and a dividend.\n");
}
}
Using the parameterstring ClassSometimes a function needs to take an arbitrary set of parameters. For example, a function for connecting to a database may need host, port, socket, username and password, any of which could be omitted depending on the database. Though C++ support methods which take an arbitrary number of parameters, sometimes it is more convenient to for the method to accept a single string parameter with name/value pairs in it instead.
The parameterstring class provides methods for parsing and accessing a parameter string of the following form:
name1='value1';name2='value2';name3='value3'
The single quotes are optional. If a parameter needs to contain a single quote, then it can be escaped as follows:
name='\'value\''
Backslashes can be similarly escaped:
name='\\value\\'
...
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/parameterstring.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, char **argv) {
parameterstring pstr;
pstr.parse("name1=value1;name2='value2';name3='\\'value3\\'';name4=\\\\value4\\\\");
printf("By Name:\nname1=%s\nname2=%s\nname3=%s\nname4=%s\nname5=%s\n",
pstr.getValue("name1"),
pstr.getValue("name2"),
pstr.getValue("name3"),
pstr.getValue("name4"),
pstr.getValue("name5"));
}
Using the datetime ClassOne of the most difficult things to do in a Unix environment is deal with dates and times. The "standard" functions and structures associated with dates and times are complex, vary widely from platform to platform and in many cases are not thread safe. The datetime class attempts to rectify this situation.
The datetime class allows you to query and set the system clock. If your platform has a working real-time-clock (/dev/rtc), then you can query or set the hardware clock as well. Note that your program must run as root in order to set the system or hardware clock. Since it is common for the system clock to be set to the local time zone and the hardware clock to be set to GMT, a method is provided for converting the hardware clock time to the system's time zone.
Additionally there is a method for switching the time zone of the time currently represented in the class.
The datetime class also provides methods for converting between several common ways of representing time. Such as a formatted string, the number of seconds since 1970 and "struct tm".
There are also methods for adding discrete amounts of time to the time currently stored in the class. You can, for example add 150 seconds to "12:30:50 01/02/2003 EST" and get "12:32:20 01/02/2003 EST". You can add negative numbers to subtract time.
Below is some code illustrating the use of the datetime class.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/datetime.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// set current time zone to America/New_York
printf("setting TZ=America/New_York...\n");
environment env;
env.setValue("TZ","America/New_York");
// get the current date
datetime dt;
dt.getSystemDateAndTime();
// Write out the different parts of the date.
printf("Hour : %d\n",dt.getHour());
printf("Minutes : %d\n",dt.getMinutes());
printf("Seconds : %d\n",dt.getSeconds());
printf("Month : %d\n",dt.getMonth());
printf("DayOfMonth : %d\n",dt.getDayOfMonth());
printf("DayOfWeek : %d\n",dt.getDayOfWeek());
printf("DayOfYear : %d\n",dt.getDayOfYear());
printf("Year : %d\n",dt.getYear());
printf("Daylight Savings Time : %d\n",dt.isDaylightSavingsTime());
printf("Time Zone : %s\n",dt.getTimeZoneString());
printf("Offset from GMT : %ld\n",dt.getTimeZoneOffset());
printf("Seconds since 1970 : %ld\n",dt.getEpoch());
printf("Date String : %s\n",dt.getString());
// use static methods to translate between formats
char *string=datetime::getString(dt.getEpoch());
printf("String from Epoch : %s\n",string);
delete[] string;
string=datetime::getString(dt.getTm());
printf("String from tm : %s\n",string);
// use static methods to translate between formats
time_t epoch=datetime::getEpoch(string);
printf("Epoch from String : %ld\n",epoch);
delete[] string;
epoch=datetime::getEpoch(dt.getTm());
printf("Epoch from tm : %ld\n",epoch);
// get time from hardware clock
printf("Hardware Clock (assuming GMT): %s\n",
(dt.getHardwareDateAndTime("GMT"))?
dt.getString():"failed");
// get time from hardware clock adjusting for timezone
printf("Adjusted Hardware Clock : %s\n",
(dt.getAdjustedHardwareDateAndTime("GMT"))?
dt.getString():"failed");
// switch time zones
dt.adjustTimeZone("MST");
printf("Adjusting time zone to Mountain time: %s\n",dt.getString());
// valid date
const char *str="02/20/1974 12:00:00";
printf("valid date? %s : %d\n",str,datetime::validDateTime(str));
str="02/30/1974 12:00:00";
printf("valid date? %s : %d\n",str,datetime::validDateTime(str));
str="02/20/1974 12:00:00 EST5EDT";
printf("valid date? %s : %d\n",str,datetime::validDateTime(str));
str="02/30/1974 12:00:00 EST5EDT";
printf("valid date? %s : %d\n",str,datetime::validDateTime(str));
}
Using the timezonefile ClassWhile I was working on timezone support in the datetime class I originally thought that it might be useful to be able to parse timezone files. I could not find any standard C functions for parsing them, so I wrote a class that parses them.
It turned out to be of very limited value, but it works and I never removed it. So, if you need such functionality, it exists.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/timezonefile.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, char **argv) {
// parse the timezone file specified in the first argument
timezonefile tz;
if (!tz.parseFile(argv[1])) {
printf("usage: tzn file\n");
exit(1);
}
// print using built-in method
tz.print();
printf("\n\n");
// print manually
printf("ttisgmtcnt: %ld\n",tz.getIsGMTCount());
printf("ttisstdcnt: %ld\n",tz.getIsSTDCount());
printf("leapcnt: %ld\n",tz.getLeapCount());
printf("timecnt: %ld\n",tz.getTimeCount());
printf("typecnt: %ld\n",tz.getTypeCount());
printf("charcnt: %ld\n",tz.getCharacterCount());
int i;
for (i=0; i<tz.getTimeCount(); i++) {
printf("transitiontime[%d]: %ld\n",i,tz.getTransitionTime(i));
}
for (i=0; i<tz.getTimeCount(); i++) {
printf("localtime[%d]: %d\n",i,tz.getLocalTimes(i));
}
for (i=0; i<tz.getTypeCount(); i++) {
printf("ttinfo[%d] {\n",i);
printf(" tt_gmtoff: %ld\n",
tz.getTimeTypeInfo(i)->tt_gmtoff);
printf(" tt_isdst: %d\n",
tz.getTimeTypeInfo(i)->tt_isdst);
printf(" tt_abbrind: %d\n",
tz.getTimeTypeInfo(i)->tt_abbrind);
printf("}\n");
}
printf("rawtimezonestring: ");
for (int i=0; i<tz.getCharacterCount(); i++) {
if (tz.getRawTimeZoneString()[i]==(char)NULL) {
printf(" ");
}
printf("%c",tz.getRawTimeZoneString()[i]);
}
printf("\n");
for (i=0; i<tz.getLeapCount(); i++) {
printf("leapsecondtime[%d]: %ld\n",i,
tz.getLeapSecondTime(i));
printf("totalleapseconds[%d]: %ld\n",i,
tz.getTotalLeapSeconds(i));
}
for (int counter=0; counter<tz.getTypeCount(); counter++) {
printf("timezonestrings[%d]=%s\n",counter,
tz.getTimeZoneString(counter));
}
for (i=0; i<tz.getIsSTDCount(); i++) {
printf("transstdwall[%d]: %d\n",i,
tz.getStandardOrWallIndicator(i));
}
for (i=0; i<tz.getIsGMTCount(); i++) {
printf("transutclocal[%d]: %d\n",i,
tz.getUTCOrLocalIndicator(i));
}
}
Using the directory Class
// Copyright (c) 2004 David Muse
// See the file COPYING for more information
#include <rudiments/directory.h>
#include <rudiments/file.h>
#include <rudiments/permissions.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
directory::create("testdir",permissions::evalPermString("rwxr-xr-x"));
file f;
f.create("testdir/testfile1",permissions::evalPermString("rw-r--r--"));
f.close();
f.create("testdir/testfile2",permissions::evalPermString("rw-r--r--"));
f.close();
printf("Contents of testdir:\n");
directory d;
d.open("testdir");
char *name;
for (off64_t index=0; (name=d.getChildName(index)); index++) {
printf("%lld: %s\n",index,name);
delete[] name;
}
printf("%d entries\n",d.getChildCount());
char *cwd=directory::getCurrentWorkingDirectory();
printf("cwd=%s\n",cwd);
delete[] cwd;
directory::changeDirectory("testdir");
cwd=directory::getCurrentWorkingDirectory();
printf("cwd=%s\n",cwd);
delete[] cwd;
directory::changeDirectory("..");
cwd=directory::getCurrentWorkingDirectory();
printf("cwd=%s\n",cwd);
delete[] cwd;
file::remove("testdir/testfile1");
file::remove("testdir/testfile2");
directory::remove("testdir");
printf("maxFileNameLength(/usr/local)=%d\n",
directory::maxFileNameLength("/usr/local"));
printf("maxPathLength(/usr/local)=%d\n",
directory::maxPathLength("/usr/local"));
printf("canAccessLongFileNames(/usr/local)=%d\n",
directory::canAccessLongFileNames("/usr/local"));
}
Using the filesystem ClassThe filesystem class provides methods for collecting statistics about a filesystem. The "standard" function for getting filesystem statistics is either statfs or statvfs. Few operating systems implement statvfs and the structure returned by statfs varies greatly between operating systems. The filesystem class attempts to remedy this situation. However, no operating system supports every method in the filesystem class.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/filesystem.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
filesystem fs;
fs.initialize("/");
printf("root fileststem stats:\n");
printf(" type: 0x%08x\n",
fs.getType());
printf(" block size: %ld\n",
fs.getBlockSize());
printf(" optimum tranfer block size: %ld\n",
fs.getOptimumTransferBlockSize());
printf(" total blocks: %ld\n",
fs.getTotalBlocks());
printf(" free blocks: %ld\n",
fs.getFreeBlocks());
printf(" available blocks: %ld\n",
fs.getAvailableBlocks());
printf(" total nodes: %ld\n",
fs.getTotalFileNodes());
printf(" free nodes: %ld\n",
fs.getFreeFileNodes());
printf(" available nodes: %ld\n",
fs.getAvailableFileNodes());
printf(" filesystem id: %ld\n",
fs.getFileSystemId());
printf(" maximum file name length: %ld\n",
fs.getMaximumFileNameLength());
printf(" owner: %ld\n",
fs.getOwner());
printf(" sync writes: %ld\n",
fs.getSyncWrites());
printf(" async writes: %ld\n",
fs.getAsyncWrites());
printf(" fs type name: %s\n",
fs.getTypeName());
printf(" mount point: %s\n",
fs.getMountPoint());
printf(" sync reads: %ld\n",
fs.getSyncReads());
printf(" async reads: %ld\n",
fs.getAsyncReads());
printf(" device name: %s\n",
fs.getDeviceName());
printf(" fs specific string: %s\n",
fs.getFilesystemSpecificString());
}
Using the logger ClassThe logger class and associated logdestination classes provide a framework for generating log messages from applications. An application can define a set of logdestinations and attach them to an instance of the logger class. Then, when the application calls one of the write() methods of the logger class, the log message is written to each of the logdestinations. For example, an application could simultaneously log to stderr and to a file. Currently stdout, stderr, file and syslog logdestinations are supported. If an application needs to send one set of log messages to one destination and another set to a different destinations, it can create two instances of the logger class and use one for each set of messages.
The following example illustrates use of the logger class.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/logger.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
logger lg;
syslogdestination sd;
filedestination fd;
stdoutdestination sod;
stderrdestination sed;
// initialize and add a syslog log destination
sd.open("logtest",LOG_CONS,LOG_USER,LOG_INFO);
lg.addLogDestination(&sd);
// initialize and add a file log destination
fd.open("test.log");
lg.addLogDestination(&fd);
// add a standard output log destination
lg.addLogDestination(&sod);
// add a standard error log destination
lg.addLogDestination(&sed);
// write a string, character, long and float value to the log, along
// with a standard log header for each
char *header=logger::logHeader("logtest");
lg.write(header,0,"test");
lg.write(header,0,'t');
lg.write(header,0,(int32_t)12345);
lg.write(header,0,123.45);
delete[] header;
// remove all log destinations
lg.removeAllLogDestinations();
// add each of the log destinations back
lg.addLogDestination(&sd);
lg.addLogDestination(&fd);
lg.addLogDestination(&sod);
lg.addLogDestination(&sed);
// remove them one by one
lg.removeLogDestination(&sd);
lg.removeLogDestination(&fd);
lg.removeLogDestination(&sod);
lg.removeLogDestination(&sed);
lg.removeAllLogDestinations();
// close the syslog log destination
sd.close();
// close the file log destination
fd.close();
}
Using the permissions ClassThe permissions class provides simple methods for generating permissions. The output of these methods can be used whenever a function takes an argument of type mode_t. Below is some code illustrating the use of the permissions class.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/permissions.h>
#include <rudiments/file.h>
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// Create a file with rw-r--r-- permissions
file fd;
fd.open("/tmp/tempfile",O_RDWR|O_CREAT,
permissions::evalPermString("rw-r--r--"));
system("ls -l /tmp/tempfile");
// change the permissions to rw-rw-r--
permissions::setFilePermissions(fd.getFileDescriptor(),
permissions::evalPermString("rw-rw-r--"));
system("ls -l /tmp/tempfile");
// close and delete the file
fd.close();
file::remove("/tmp/tempfile");
// do the same as above using different methods
fd.open("/tmp/tempfile",O_RDWR|O_CREAT,
permissions::ownerReadWrite()|
permissions::groupRead()|
permissions::othersRead());
system("ls -l /tmp/tempfile");
permissions::setFilePermissions(fd.getFileDescriptor(),
permissions::ownerReadWrite()|
permissions::groupReadWrite()|
permissions::othersRead());
system("ls -l /tmp/tempfile");
fd.close();
file::remove("/tmp/tempfile");
}
Using the randomnumber ClassFunctions for generating random numbers vary from platform to platform. The randomnumber class attempts to rectify this situation. Below is some code illustrating the use of the randomnumber class.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/datetime.h>
#include <rudiments/randomnumber.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// it's common to seed a random number generator with the number of
// seconds since 1970 (the epoch), so we'll get the current date.
datetime dt;
dt.getSystemDateAndTime();
printf("A random number between 0 and %d: ",RAND_MAX);
printf("%d",randomnumber::generateNumber(dt.getEpoch()));
printf("\n");
printf("A random number between 100 and 1000: ");
printf("%d",randomnumber::generateScaledNumber(dt.getEpoch(),100,1000));
printf("\n");
printf("Another random number between 100 and 1000: ");
int basenumber=randomnumber::generateNumber(dt.getEpoch()+1);
int scalednumber=randomnumber::scaleNumber(basenumber,100,1000);
printf("%d",scalednumber);
printf("\n");
printf("A random number between -100 and -1000: ");
printf("%d",randomnumber::generateScaledNumber(dt.getEpoch(),
-100,-1000));
printf("\n");
printf("Another random number between -100 and -1000: ");
basenumber=randomnumber::generateNumber(dt.getEpoch()+1);
scalednumber=randomnumber::scaleNumber(basenumber,-100,-1000);
printf("%d",scalednumber);
printf("\n");
printf("A random number between -100 and 100: ");
printf("%d",randomnumber::generateScaledNumber(dt.getEpoch(),-100,100));
printf("\n");
printf("Another random number between -100 and 100: ");
basenumber=randomnumber::generateNumber(dt.getEpoch()+1);
scalednumber=randomnumber::scaleNumber(basenumber,-100,100);
printf("%d",scalednumber);
printf("\n");
}
Using the regularexpression ClassRegular expressions allow a programmer to perform complex string matching but methods for using regular expressions vary from platform to platform. The regularexpression class attempts to rectify this situation. Below is some code illustrating the use of the regularexpression class.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/regularexpression.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
void printMatches(regularexpression *re) {
printf("match 0: \"%s\"\n",re->getSubstringStart(0));
for (int i=1; i<re->getSubstringCount(); i++) {
printf("match: \"%s\"\n",re->getSubstringStart(i));
}
printf("%d matches\n",re->getSubstringCount());
}
int main(int argc, const char **argv) {
// A quick match...
if (regularexpression::match("Hello!",".*Dave.*")) {
printf("The string contains .*Dave.*\n");
} else {
printf("The string doesn't contain Dave\n");
}
if (regularexpression::match("Hello Dave!",".*Dave.*")) {
printf("The string contains .*Dave.*\n");
} else {
printf("The string doesn't contain Dave\n");
}
// If you need to match over and over...
regularexpression re("Dave");
if (re.match("Hello!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("Hello Dave!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
re.study();
if (re.match("Goodbye!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("Goodbye Dave!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
re.study();
if (re.match("He is a jerk!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("Dave is a jerk!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("He writes cool software!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("Dave writes cool software!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("See ya later Dave!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("See ya later!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
if (re.match("Dave, Dave, Dave!")) {
printf("The string contains Dave\n");
} else {
printf("The string doesn't contain Dave\n");
}
printMatches(&re);
}
Using the chat Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the crypt Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the dynamiclib Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the error Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the intervaltimer Class...
#include <rudiments/intervaltimer.h>
#include <rudiments/signalclasses.h>
#include <rudiments/snooze.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
RETSIGTYPE alarmhandler() {
printf("alarm!\n");
}
void waitForTimer(intervaltimer *t) {
itimerval itv;
t->getIntervals(&itv);
printf("initial: %dsec %dusec ",
itv.it_value.tv_sec,itv.it_value.tv_usec);
printf("interval: %dsec %dusec\n",
itv.it_interval.tv_sec,itv.it_interval.tv_usec);
for (;;) {
timeval gtv;
t->getTimeRemaining(>v);
printf("time remaining: %dsec %dusec\n",gtv.tv_sec,gtv.tv_usec);
if (gtv.tv_sec==0 && gtv.tv_usec==0) {
break;
}
snooze::macrosnooze(1);
}
}
int main(int argc, char **argv) {
signalhandler ah;
ah.setHandler((void *)alarmhandler);
ah.handleSignal(SIGALRM);
intervaltimer t(ITIMER_REAL);
t.setInitialInterval(2,0);
t.start();
waitForTimer(&t);
t.setInitialInterval(2,500000);
t.start();
waitForTimer(&t);
timeval tv;
tv.tv_sec=2;
tv.tv_usec=500000;
t.setInitialInterval(&tv);
t.start();
waitForTimer(&t);
itimerval stv;
stv.it_value.tv_sec=2;
stv.it_value.tv_usec=0;
stv.it_interval.tv_sec=0;
stv.it_interval.tv_usec=0;
t.setIntervals(&stv);
t.start();
waitForTimer(&t);
}
Using the math Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the mutex Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the process Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the serialportprofile Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the snooze Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the Signal ClassesSignals allow processes to interrupt the execution of other processes. Signal handlers allow processes to intercept and react to the signals sent to them.
Rudiments provides 3 classes for working with signals: signalset, signalmanager and signalhandler.
A signalset is just a collection of signals. The signalset class allows a programmer to build up a collection of signals.
The signalmanager class provides methods for sending signals, ignoring signals, waiting for signals and examining blocked signals.
The signalhandler class provides methods for catching and handling signals.
Below is some code illustrating the use of all three classes. Note that you'll have to kill this program with a -9.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/signalclasses.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
void handleSigusr1() {
printf("Got a SIGUSR1!\n");
}
int main(int argc, const char **argv) {
// this program will ignore all signals except SIGUSR1
signalset ignoreset;
ignoreset.addAllSignals();
ignoreset.removeSignal(SIGUSR1);
signalmanager::ignoreSignals(ignoreset.getSignalSet());
// when it gets a SIGUSR1, it will run the handleSigusr1() function
signalhandler shandler(SIGUSR1,(void *)&handleSigusr1);
// Loop forever, each time waiting for a signal not in the ignoreset
// to be sent. Since SIGUSR1 is the only signal not in the ignoreset,
// waitForSignals will fall through only when SIGUSR1 is received.
for (;;) {
signalmanager::waitForSignals(ignoreset.getSignalSet());
}
}
Using the sharedmemory ClassShared memory allows seperate processes to access a common block of memory. The standard functions and structures for managing shared memory segments are complex. The sharedmemory class attempts to rectify this situation. Below is some code illustrating the use of the sharedmemory class.
There are methods in the sharedmemory class that allow you to get and set user/group ownership and permissions of a segment that are not documented here, but they are straightforward and rarely used.
This program puts some data into shared memory then goes to sleep, giving another program time to access the segment.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/sharedmemory.h>
#include <rudiments/permissions.h>
#include <rudiments/file.h>
#include <rudiments/snooze.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a file called /tmp/shm
file::remove("/tmp/shm");
file fd;
fd.create("/tmp/shm",permissions::evalPermString("rw-------"));
fd.close();
// create a shared memory segment, keyed to /tmp/shm, 128 bytes long
sharedmemory shm;
shm.create(file::generateKey("/tmp/shm",1),128,
permissions::evalPermString("rw-------"));
// write a string into the shared memory
char *shmptr=(char *)shm.getPointer();
strcpy(shmptr,"This string is in shared memory.");
// sleep while another process accesses the shared memory...
snooze::macrosnooze(1000);
}
This program reads the data from shared memory.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/sharedmemory.h>
#include <rudiments/permissions.h>
#include <rudiments/file.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// attach to a shared memory segment keyed to /tmp/shm
sharedmemory shm;
shm.attach(file::generateKey("/tmp/shm",1));
// display the data contained in the shared memory segment
char *shmptr=(char *)shm.getPointer();
printf("%s\n",shmptr);
}
Using the semaphoreset ClassSemaphores allow seperate processes or threads to synchronize activities. The standard functions and structures for managing semaphores are complex. The sempahoreset class attempts to rectify this situation. Below is some code illustrating the use of the semaphoreset class.
There are methods in the semaphoreset class that allow you to get and set user/group ownership and permissions of a semaphore set that are not documented here, but they are straightforward and rarely used.
The first program prints out 1 and 3, the second program prints out 2 and 4. They use a set of 2 semaphores to synchronize these activities. No matter what order the programs are started in, they will always print out
1
2
3
4
1
2
3
4
etc.
These programs must both be run to the background.
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/sharedmemory.h>
#include <rudiments/permissions.h>
#include <rudiments/file.h>
#include <rudiments/snooze.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a file called /tmp/shm
file::remove("/tmp/shm");
file fd;
fd.create("/tmp/shm",permissions::evalPermString("rw-------"));
fd.close();
// create a shared memory segment, keyed to /tmp/shm, 128 bytes long
sharedmemory shm;
shm.create(file::generateKey("/tmp/shm",1),128,
permissions::evalPermString("rw-------"));
// write a string into the shared memory
char *shmptr=(char *)shm.getPointer();
strcpy(shmptr,"This string is in shared memory.");
// sleep while another process accesses the shared memory...
snooze::macrosnooze(1000);
}
// Copyright (c) 2001 David Muse
// See the file COPYING for more information
#include <rudiments/sharedmemory.h>
#include <rudiments/permissions.h>
#include <rudiments/file.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// attach to a shared memory segment keyed to /tmp/shm
sharedmemory shm;
shm.attach(file::generateKey("/tmp/shm",1));
// display the data contained in the shared memory segment
char *shmptr=(char *)shm.getPointer();
printf("%s\n",shmptr);
}
Using the memorymap Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the memorypool ClassThe memorypool class implements a pool of memory that starts with an initial buffer and grows dynamically as needed. Each time the pool is freed, the dynamic buffers are deallocated. After a configurable number of free's, the initial buffer is resized to the average amount of memory that was requested between free's since the last time it resized.
The memorypool class is especially useful for applications that do the same task over and over where varying amounts of memory are required during each iteration. The class is particularly efficient in cases where memory requirements are fairly constant between iterations with sporadic requirements for lots of memory or where the memory requirements steadily get larger or smaller across iterations.
Using a memorypool can be faster than allocating memory on demand, then deallocating it later and more efficient than using static buffers that are large enough to contain the largest possible data.
The following code connects to a server on the local machine and reads variable/value pairs from it.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/memorypool.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
memorypool *mp=new memorypool(32,16,10);
printf("first run...\n");
for (int i=0; i<20; i++) {
char *segment=(char *)mp->malloc(6);
for (int j=0; j<6; j++) {
segment[j]=(char)'a'+i;
}
}
mp->print();
printf("free...\n");
mp->free();
mp->print();
printf("second run...\n");
char *segment=(char *)mp->malloc(40);
for (int j=0; j<40; j++) {
segment[j]='z';
}
for (int i=0; i<20; i++) {
char *segment=(char *)mp->malloc(6);
for (int j=0; j<6; j++) {
segment[j]=(char)'a'+i;
}
}
for (int i=0; i<20; i++) {
char *segment=(char *)mp->malloc(2);
for (int j=0; j<6; j++) {
segment[j]=(char)'A'+i;
}
}
mp->print();
printf("free...\n");
mp->free();
mp->print();
printf("short/long/float/double...\n");
short *sp=(short *)mp->malloc(sizeof(short));
long *lp=(long *)mp->malloc(sizeof(long));
float *fp=(float *)mp->malloc(sizeof(float));
double *dp=(double *)mp->malloc(sizeof(double));
*sp=1;
*lp=1;
*fp=1.1;
*dp=1.1;
printf("sp: %d lp: %ld ",*sp,*lp);
printf("fp: %f dp: %f \n",*fp,*dp);
mp->print();
printf("free...\n");
mp->free();
mp->print();
printf("short/long/float/double arrays...\n");
short *spa=(short *)mp->malloc(sizeof(short)*10);
long *lpa=(long *)mp->malloc(sizeof(long)*10);
float *fpa=(float *)mp->malloc(sizeof(float)*10);
double *dpa=(double *)mp->malloc(sizeof(double)*10);
for (int i=0; i<10; i++) {
spa[i]=i;
lpa[i]=i;
fpa[i]=i+((float)i/10.0);
dpa[i]=i+((float)i/10.0);
}
for (int i=0; i<10; i++) {
printf("sp: %d lp: %ld ",spa[i],lpa[i]);
printf("fp: %f dp: %f \n",fpa[i],dpa[i]);
}
mp->print();
printf("free...\n");
mp->free();
mp->print();
delete mp;
mp=new memorypool(32,16,10);
for (int i=0; i<10; i++) {
unsigned long total=0;
for (unsigned long j=0; j<11; j++) {
total=total+i+j;
mp->malloc(i+j);
mp->free();
}
printf("should be: %ld\n",total/11);
mp->print();
}
delete mp;
}
Using the variablebuffer ClassThe variablebuffer class allows you to manipulate a buffer of arbitrary length containing binary data. You can append data to a variablebuffer or write data at arbitrary positions in the buffer.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/variablebuffer.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a buffer
variablebuffer *vb=new variablebuffer(10,10);
// append some string sequences to the buffer and display the contents
// of the buffer byte by byte
vb->append((unsigned char *)"12345",5);
vb->append((unsigned char *)"12345",5);
vb->append((unsigned char *)"12345",5);
vb->append((unsigned char *)"12345",5);
vb->append((unsigned char *)"12345",5);
for (size_t i=0; i<vb->getSize(); i++) {
printf("%c",vb->getBuffer()[i]);
}
printf("\n");
// write 66666 to the buffer at position 0 and display it's contents
// byte by byte (the first 5 bytes should be overwritten)
vb->setPosition(0);
vb->write((unsigned char *)"66666",5);
for (size_t i=0; i<vb->getSize(); i++) {
printf("%c",vb->getBuffer()[i]);
}
printf("\n");
// write 66666 to the buffer at position 30 and display it's contents
// byte by byte, displaying nonprintable characters as .'s
// (there should be a gap in the buffer now containing random data)
vb->setPosition(30);
vb->write((unsigned char *)"66666",5);
for (size_t i=0; i<vb->getSize(); i++) {
if (vb->getBuffer()[i]>=' ' && vb->getBuffer()[i]<='~') {
printf("%c",vb->getBuffer()[i]);
} else {
printf(".");
}
}
printf("\n");
// set the current position to 50
vb->setPosition(50);
// Append 12345 to the buffer and display it's contents byte by byte,
// displaying nonprintable characters as .'s
// Since we used append() instead of write(), the data should not be
// written at position 50, but rather just at the current end of
// the buffer.
vb->append((unsigned char *)"12345",5);
for (size_t i=0; i<vb->getSize(); i++) {
if (vb->getBuffer()[i]>=' ' && vb->getBuffer()[i]<='~') {
printf("%c",vb->getBuffer()[i]);
} else {
printf(".");
}
}
printf("\n");
// Write 12345 to the buffer at the current position and display it's
// contents byte by byte, displaying nonprintable characters as .'s
// The current position should just be the end of the buffer, since
// we just appended. So calling write() here is equivalent to calling
// append.
vb->write((unsigned char *)"12345",5);
for (size_t i=0; i<vb->getSize(); i++) {
if (vb->getBuffer()[i]>=' ' && vb->getBuffer()[i]<='~') {
printf("%c",vb->getBuffer()[i]);
} else {
printf(".");
}
}
printf("\n");
// read 4 bytes from position 0 of the buffer and display them
unsigned char buffer[5];
buffer[4]=(unsigned char)NULL;
vb->setPosition(0);
unsigned long sizeread=vb->read(buffer,4);
printf("%ld: ",sizeread);
for (unsigned long i=0; i<sizeread; i++) {
printf("%c",buffer[i]);
}
printf("\n");
// read 4 bytes from position 5 of the buffer and display them
vb->setPosition(5);
sizeread=vb->read(buffer,4);
printf("%ld: ",sizeread);
for (unsigned long i=0; i<sizeread; i++) {
printf("%c",buffer[i]);
}
printf("\n");
// read 4 bytes from position 60 of the buffer and display them
// (since this is off of the end of the buffer, nothing should be
// displayed)
vb->setPosition(60);
sizeread=vb->read(buffer,4);
printf("%ld: ",sizeread);
for (unsigned long i=0; i<sizeread; i++) {
printf("%c",buffer[i]);
}
printf("\n");
delete vb;
}
Using the stringbuffer ClassThe stringbuffer class allows you to manipulate strings of arbitrary length. You can append data to a stringbuffer or write data at arbitrary positions in the buffer.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/stringbuffer.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a new string buffer
stringbuffer *str=new stringbuffer();
// append a NULL to the buffer
str->append((char *)NULL);
// append "hello there world" to the buffer in 3 parts
str->append("hello ")->append("there ")->append("world ");
// display the length and contents of the buffer
printf("length: %d\n\"%s\"\n",str->getStringLength(),str->getString());
// append some long integers to the buffer
str->append((int32_t)1)->append(" ");
str->append((int32_t)2)->append(" ");
str->append((int32_t)3)->append(" ");
str->append((int32_t)4)->append(" ");
str->append((int32_t)5)->append(" ");
// display the length and contents of the buffer
printf("length: %d\n\"%s\"\n",str->getStringLength(),str->getString());
str->append(" ");
// append some floating point numbers to the buffer
str->append(1.1,1,0)->append(" ");
str->append(2.02,2,0)->append(" ");
str->append(3.003,3,0)->append(" ");
str->append(4.0004,4,0)->append(" ");
str->append(5.00005,5,0)->append(" ");
// display the length and contents of the buffer
printf("length: %d\n\"%s\"\n",str->getStringLength(),str->getString());
// clear the buffer
str->clear();
// append 1024 *'s to the buffer and display it's length and contents
for (int i=0; i<1024; i++) {
str->append('*');
}
printf("length: %d\n%s\n",str->getStringLength(),str->getString());
// delete the buffer
delete str;
// create another buffer
stringbuffer *sb=new stringbuffer();
// append some string sequences to the buffer and display the contents
// of the buffer byte by byte
sb->append("12345");
sb->append("12345");
sb->append("12345");
sb->append("12345");
sb->append("12345");
for (unsigned int i=0; i<sb->getStringLength(); i++) {
printf("%c",sb->getString()[i]);
}
printf("\n");
// write 66666 to the buffer at position 0 and display it's contents
// byte by byte (the first 5 bytes should be overwritten)
sb->setPosition(0);
sb->write("66666");
for (unsigned int i=0; i<sb->getStringLength(); i++) {
printf("%c",sb->getString()[i]);
}
printf("\n");
// write 66666 to the buffer at position 30 and display it's contents
// byte by byte, displaying nonprintable characters as .'s
// (there should be a gap in the buffer now containing random data)
sb->setPosition(30);
sb->write("66666");
for (int i=0; i<35; i++) {
if (sb->getString()[i]>=' ' && sb->getString()[i]<='~') {
printf("%c",sb->getString()[i]);
} else {
printf(".");
}
}
printf("\n");
// set the current position to 50
sb->setPosition(50);
// Append 12345 to the buffer and display it's contents byte by byte,
// displaying nonprintable characters as .'s
// Since we used append() instead of write(), the data should not be
// written at position 50, but rather just at the current end of
// the buffer.
sb->append("12345");
for (int i=0; i<55; i++) {
if (sb->getString()[i]>=' ' && sb->getString()[i]<='~') {
printf("%c",sb->getString()[i]);
} else {
printf(".");
}
}
printf("\n");
// Write 12345 to the buffer at the current position and display it's
// contents byte by byte, displaying nonprintable characters as .'s
// The current position should just be the end of the buffer, since
// we just appended. So calling write() here is equivalent to calling
// append.
sb->write("12345");
for (int i=0; i<55; i++) {
if (sb->getString()[i]>=' ' && sb->getString()[i]<='~') {
printf("%c",sb->getString()[i]);
} else {
printf(".");
}
}
printf("\n");
// clear the buffer
sb->clear();
// append 1024 0's to the buffer and display it's length and contents
for (int i=0; i<1024; i++) {
sb->append("0");
}
printf("length: %d\n%s\n",str->getStringLength(),str->getString());
delete sb;
}
Using the character Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the charstring ClassThe charstring class contains some commonly needed string manipulation and evaluation functions. Below is some code illustrating the use of the string class.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/charstring.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a new string 50 bytes long
char s[50];
// set every byte in the string to NULL
charstring::zero(s,50);
// Append "hello there dave" to the string and display it.
// The 3rd call to append() only appends the first 4 bytes of "dave !!!"
charstring::append(s,"hello ");
charstring::append(s,"there ");
charstring::append(s,"dave !!!",4);
printf("\"%s\"\n",s);
// Replace the contents of the string and display it over and over.
// Note that the 2nd and 4th call to copy() only copy part of the
// string passed into them.
charstring::copy(s,"what's ");
printf("\"%s\"\n",s);
charstring::copy(s,"up !!!",2);
printf("\"%s\"\n",s);
charstring::copy(s,2," !!!");
printf("\"%s\"\n",s);
charstring::copy(s,6,"!!!!!!",1);
printf("\"%s\"\n",s);
// clear the string again.
charstring::zero(s,50);
// Append "hello" to the string.
charstring::append(s,"hello");
// perform several comparisons, all of which should return 0
printf("compare: %d=0\n",charstring::compare(s,"hello"));
printf("compare: %d=0\n",charstring::compare(s,"hello",3));
printf("compare: %d=0\n",charstring::compareIgnoringCase(s,"HELLO"));
printf("compare: %d=0\n",charstring::compareIgnoringCase(s,"HELLO",3));
// perform several contains() comparisons
printf("findFirst: \"%s\"=llo\n",charstring::findFirst(s,"llo"));
printf("contains: %d\n",charstring::contains(s,"llo"));
printf("findFirst: \"%s\"=llo\n",charstring::findFirst(s,'l'));
printf("contains: %d\n",charstring::contains(s,"llo"));
// duplicate the string and display the duplicated string
char *hellothere=charstring::duplicate(s);
char *ell=charstring::subString(hellothere,1,3);
char *lle=charstring::subString(hellothere,3,1);
printf("hello: %s\n",hellothere);
printf("ell: %s\n",ell);
printf("ell: %s\n",lle);
// make sure to clean up what duplicate() returns
delete[] hellothere;
delete[] ell;
delete[] lle;
// split
char **list;
uint64_t listlength;
charstring::split("hello||hi||bye||goodbye","||",false,
&list,&listlength);
printf("split(\"hello||hi||bye||goodbye\",\"||\")\n");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
charstring::split("hello||hi||bye||goodbye||","||",false,
&list,&listlength);
printf("split(\"hello||hi||bye||goodbye||\",\"||\")\n");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
charstring::split("||hello||hi||bye||goodbye||","||",false,
&list,&listlength);
printf("split(\"||hello||hi||bye||goodbye||\",\"||\")\n");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
charstring::split("||||hello||||hi||||bye||||goodbye||||","||",false,
&list,&listlength);
printf("split(\"||||hello||||hi||||bye||||goodbye||||\",\"||\")\n");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
charstring::split("||||||||||","||",false,&list,&listlength);
printf("split(\"||||||||||\",\"||\")\n");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
charstring::split("http://www.firstworks.com/application/app.cgi/skin/module/template.html","/",false,&list,&listlength);
printf("split(\"http://www.firstworks.com/application/app.cgi/skin/module/template.html\",\"/\"");
printf("%lld items\n",listlength);
for (uint64_t i=0; i<listlength; i++) {
printf(" %s\n",list[i]);
delete[] list[i];
}
delete[] list;
char str[]="hello'\"\\hello'\"\\";
char *escapedstr=charstring::escape(str,"\"'");
char *unescapedstr=charstring::unescape(escapedstr);
printf("str : %s\n",str);
printf("escapedstr : %s\n",escapedstr);
printf("unescapedstr : %s\n",unescapedstr);
delete[] unescapedstr;
delete[] escapedstr;
const char *alphabet="aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz";
printf("lengthContainingSet(\"%s\",\"gfedcba\")=%d\n",
alphabet,charstring::lengthContainingSet(alphabet,"gfedcba"));
printf("lengthNotContainingSet(\"%s\",\"hijklmnopqrstuvwxyz\")=%d\n",
alphabet,charstring::lengthNotContainingSet(alphabet,
"hijklmnopqrstuvwxyz"));
printf("findFirstOfSet(\"%s\",\"mlk\")=\"%s\"\n",
alphabet,charstring::findFirstOfSet(alphabet,"klm"));
// initialize a text buffer and print it out
char buffer[100];
charstring::copy(buffer," hello there buddy ");
printf("!%s!\n",buffer);
// trim the spaces off of the right hand side
charstring::rightTrim(buffer);
printf("!%s!\n",buffer);
// trim the spaces off of the left hand side
charstring::leftTrim(buffer);
printf("!%s!\n",buffer);
// strip the spaces out
charstring::copy(buffer," hello there buddy ");
charstring::strip(buffer,' ');
printf("!%s!\n",buffer);
// strip the " " out
charstring::copy(buffer," hello there buddy ");
charstring::strip(buffer," ");
printf("!%s!\n",buffer);
// convert buffer to uppercase
charstring::upper(buffer);
printf("!%s!\n",buffer);
// convert buffer to lowercase
charstring::lower(buffer);
printf("!%s!\n",buffer);
// http escape the buffer
char *escbuffer=charstring::httpEscape("!@#$%^&*()hello-+");
printf("!@#$\\%^&*()hello-+ http escaped is %s\n",escbuffer);
delete escbuffer;
// evaluate a string to see if it's a number
if (charstring::isNumber("-100.5")) {
printf("-100.5 is a number\n");
}
if (!charstring::isNumber("-100.5.10")) {
printf("-100.5.10 is not a number\n");
}
// evaluate a string to see if it's an integer
if (charstring::isInteger("-100")) {
printf("-100 is an integer\n");
}
if (!charstring::isInteger("-100.5")) {
printf("-100.5.10 is not an integer\n");
}
// create a new string containing text surrounded by spaces
char hello[16];
charstring::copy(hello," hello ");
printf("|%s|\n",hello);
// left justify the text
charstring::leftJustify(hello,15);
printf("|%s|\n",hello);
// right justify the text
charstring::rightJustify(hello,15);
printf("|%s|\n",hello);
// center the text over and over...
charstring::copy(hello,"hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello ");
charstring::center(hello,15);
printf("|%s|\n",hello);
charstring::copy(hello," hello");
charstring::center(hello,15);
printf("|%s|\n",hello);
// print the number of bytes necessary to store each number as a string
printf("size of 1 is: %d\n",charstring::integerLength((long)1));
printf("size of 10 is: %d\n",charstring::integerLength((long)10));
printf("size of 100 is: %d\n",charstring::integerLength((long)100));
printf("size of 1000 is: %d\n",charstring::integerLength((long)1000));
printf("size of -1 is: %d\n",charstring::integerLength((long)-1));
printf("size of -10 is: %d\n",charstring::integerLength((long)-10));
printf("size of -100 is: %d\n",charstring::integerLength((long)-100));
printf("size of -1000 is: %d\n",charstring::integerLength((long)-1000));
}
Using the rawbuffer Class...
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// FIXME: implement this...
}
Using the xmldom ClassThe xmldom and xmldomnode classes provide a framework for DOM parsing of XML documents. The xmldom class provides methods for parsing the document and accessing it's root node. Each node of the document is represented by an instance of the xmldomnode class. The xmldomnode class provides methods for accessing a node's data, attributes, child nodes, parent nodes and sibling nodes. Since the xmldom class creates a representation of the XML document in memory, it should not be used to process arbitrarily large documents which could exhaust system memory.
The following XML file contains an address book.
<?xml version="1.0"?>
<!DOCTYPE instances SYSTEM "adbook.dtd">
<addressbook>
<person firstname="David" middlename="Lee" lastname="Muse">
<phones>
<phone location="home" number="1-222-333-4444"/>
<phone location="work" number="1-333-444-5555"/>
<phone location="mobile" number="1-444-555-6666"/>
</phones>
<addresses>
<address location="home" address="1234 homestreet dr." city="mycity" state="GA" zip="12345"/>
<address location="work" address="2345 workstreet dr." city="mycity" state="GA" zip="23456"/>
</addresses>
<emails>
<email location="home" address="dmuse@firstworks.com"/>
<email location="work" address="dmuse@workemail.com"/>
</emails>
</person>
</addressbook>
The following program parses the addressbook and prints it to the screen.
#include <rudiments/xmldom.h>
#include <iostream>
using namespace rudiments;
using namespace std;
int main() {
xmldom x;
x.parseFile("addressbook.xml");
x.getRootNode()->cascadeOnDelete();
xmldomnode *addressbook=x.getRootNode()->getChild("addressbook");
for (int i=0; i<addressbook->getChildCount(); i++) {
xmldomnode *person=addressbook->getChild(i);
if (person->getType()!=TAG_XMLDOMNODETYPE) {
continue;
}
cout << person->getAttribute("firstname")->getValue() << " ";
cout << person->getAttribute("middlename")->getValue() << " ";
cout << person->getAttribute("lastname")->getValue() << endl;
xmldomnode *phones=person->getChild("phones");
cout << "Phones:" << endl;
for (int j=0; j<phones->getChildCount(); j++) {
xmldomnode *phone=phones->getChild(j);
if (phone->getType()!=TAG_XMLDOMNODETYPE) {
continue;
}
cout << " ";
cout << phone->getAttribute("location")->
getValue() << ": ";
cout << phone->getAttribute("number")->
getValue() << endl;
}
cout << endl;
xmldomnode *addresses=person->getChild("addresses");
cout << "Addresses:" << endl;
for (int j=0; j<addresses->getChildCount(); j++) {
xmldomnode *address=addresses->getChild(j);
if (address->getType()!=TAG_XMLDOMNODETYPE) {
continue;
}
cout << " ";
cout << address->getAttribute("location")->
getValue() << ": ";
cout << address->getAttribute("address")->
getValue() << " ";
cout << address->getAttribute("city")->
getValue() << ", ";
cout << address->getAttribute("state")->
getValue() << " ";
cout << address->getAttribute("zip")->
getValue() << endl;
}
cout << endl;
xmldomnode *emails=person->getChild("emails");
cout << "Emails:" << endl;
for (int j=0; j<emails->getChildCount(); j++) {
xmldomnode *email=emails->getChild(j);
if (email->getType()!=TAG_XMLDOMNODETYPE) {
continue;
}
cout << " ";
cout << email->getAttribute("location")->
getValue() << ": ";
cout << email->getAttribute("address")->
getValue() << endl;
}
cout << endl;
}
}
Here is the output of the program above.
David Lee Muse
Phones:
home: 1-222-333-4444
work: 1-333-444-5555
mobile: 1-444-555-6666
Addresses:
home: 1234 homestreet dr. mycity, GA 12345
work: 2345 workstreet dr. mycity, GA 23456
Emails:
home: dmuse@firstworks.com
work: dmuse@workemail.com
Using the xmlsax ClassThe xmlsax class provides a callback-based framework for parsing XML documents. The xmlsax class provides methods for parsing strings of XML or XML files. When it encounters a tag, attribute or other XML component, it calls one of it's callback methods. These methods may be overridden by a child class to perform specific tasks. The xmlsax class is especially useful if you can't afford to load the entire document into memory and use the xmldom class, or if you just need to extract specific data from an XML file.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/xmlsax.h>
#include <stdio.h>
using namespace rudiments;
class myxmlsax : public xmlsax {
public:
myxmlsax();
private:
int xmlVersionStart();
int xmlVersionEnd();
int doctypeStart(char *name);
int externalSubset(char *filename);
int doctypeEnd();
int tagStart(char *name);
int attributeName(char *name);
int attributeValue(char *value);
int text(char *string);
int tagEnd(char *name);
int comment(char *string);
int cdata(char *string);
void indent(int spaces);
int ind;
};
myxmlsax::myxmlsax() : xmlsax() {
ind=0;
}
int myxmlsax::xmlVersionStart() {
printf("XML version start:\n");
return 1;
}
int myxmlsax::xmlVersionEnd() {
printf("XML version end:\n");
return 1;
}
int myxmlsax::doctypeStart(char *name) {
printf("DOCTYPE start: %s\n",name);
return 1;
}
int myxmlsax::externalSubset(char *filename) {
printf(" external subset: %s\n",filename);
return 1;
}
int myxmlsax::doctypeEnd() {
printf("DOCTYPE end:\n");
return 1;
}
void myxmlsax::indent(int spaces) {
for (int i=0; i<spaces; i++) {
printf(" ");
}
}
int myxmlsax::tagStart(char *name) {
indent(ind);
printf("tagStart: %s\n",name);
ind++;
return 1;
}
int myxmlsax::attributeName(char *name) {
indent(ind+1);
printf("attribute name: %s\n",name);
return 1;
}
int myxmlsax::attributeValue(char *value) {
indent(ind+1);
printf("attribute value: %s\n",value);
return 1;
}
int myxmlsax::text(char *string) {
indent(ind+1);
printf("text: \n%s\n",string);
return 1;
}
int myxmlsax::tagEnd(char *name) {
ind--;
indent(ind);
printf("tagEnd: %s\n",name);
return 1;
}
int myxmlsax::comment(char *string) {
indent(ind);
printf("comment: \n%s\n",string);
return 1;
}
int myxmlsax::cdata(char *string) {
indent(ind);
printf("cdata: \n%s\n",string);
return 1;
}
int main(int argv, const char **argc) {
myxmlsax x;
x.parseFile("xmls.xml");
}
Using the dtd ClassThe dtd class provides methods for parsing an XML DTD. The result is an XML DOM tree representing the DTD. Once parsed, the tree can be accessed using the xmldom and xmldomnode classes.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/dtd.h>
#include <stdio.h>
using namespace rudiments;
int main(int argv, const char **argc) {
// display the contents of dtd.dtd
dtd d;
d.parseFile("dtd.dtd");
printf("%s\n",d.xml()->xml()->getString());
}
Using the passwdentry ClassThe passwdentry class allows you to look up entries from /etc/passwd or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/passwdentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the password entry for "root"
passwdentry pwent;
pwent.initialize("root");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",
pwent.getName());
printf(" Password: %s\n",
pwent.getPassword());
printf(" User Id: %d\n",
pwent.getUserId());
printf(" Primary Group Id: %d\n",
pwent.getPrimaryGroupId());
printf(" Real Name: %s\n",
pwent.getRealName());
printf(" Home Directory: %s\n",
pwent.getHomeDirectory());
printf(" Shell: %s\n",
pwent.getShell());
printf("\n");
// use the built in print method
printf("Built In...\n");
pwent.print();
printf("\n");
// get the password entry for user id 0
pwent.initialize((uid_t)0);
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",
pwent.getName());
printf(" Password: %s\n",
pwent.getPassword());
printf(" User Id: %d\n",
pwent.getUserId());
printf(" Primary Group Id: %d\n",
pwent.getPrimaryGroupId());
printf(" Real Name: %s\n",
pwent.getRealName());
printf(" Home Directory: %s\n",
pwent.getHomeDirectory());
printf(" Shell: %s\n",
pwent.getShell());
printf("\n");
// use the built in print method
printf("Built In...\n");
pwent.print();
printf("\n");
}
Using the shadowentry ClassThe shadowentry class allows you to look up entries from /etc/shadow or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/shadowentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the shadow entry for "root"
shadowentry spent;
spent.initialize("root");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",spent.getName());
printf(" Encrypted Password: %s\n",spent.getEncryptedPassword());
printf(" Last Change: %ld\n",
spent.getLastChangeDate());
printf(" Days Before Change Allowed: %d\n",
spent.getDaysBeforeChangeAllowed());
printf(" Days Before Change Required: %d\n",
spent.getDaysBeforeChangeRequired());
printf(" Days Before Expiration Warning: %d\n",
spent.getDaysBeforeExpirationWarning());
printf(" Days Of Inactivity Allowed: %d\n",
spent.getDaysOfInactivityAllowed());
printf(" Expiration Date: %d\n",
spent.getExpirationDate());
printf(" Flag: %d\n",spent.getFlag());
printf("\n");
// use the built in print method
printf("Built In...\n");
spent.print();
printf("\n");
}
Using the groupentry ClassThe groupentry class allows you to look up entries from /etc/group or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/groupentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the group entry for "bin"
groupentry grent;
grent.initialize("bin");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",grent.getName());
printf(" Password: %s\n",grent.getPassword());
printf(" Group Id: %d\n",grent.getGroupId());
printf(" Members:\n");
for (int i=0; grent.getMembers()[i]; i++) {
printf(" %s\n",grent.getMembers()[i]);
}
printf("\n");
// use the built in print method
printf("Built in...:\n");
grent.print();
printf("\n");
// get the group entry for group id 1
grent.initialize((gid_t)1);
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",grent.getName());
printf(" Password: %s\n",grent.getPassword());
printf(" Group Id: %d\n",grent.getGroupId());
printf(" Members:\n");
for (int i=0; grent.getMembers()[i]; i++) {
printf(" %s\n",grent.getMembers()[i]);
}
printf("\n");
// use the built in print method
printf("Built in...:\n");
grent.print();
printf("\n");
}
Using the hostentry ClassThe hostentry class allows you to look up entries from /etc/hosts or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/hostentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
// this function takes addr[]={127,1,1,0} and returns "127.1.1.0"
char *getAddressString(int length, const char *addr) {
char *address=new char[(length*4)+1];
address[0]=(char)NULL;
for (int byte=0; byte<length; byte++) {
sprintf(address,"%s%d",address,addr[byte]);
if (byte<length-1) {
sprintf(address,"%s.",address);
}
}
return address;
}
int main(int argc, const char **argv) {
// get the host information for "localhost"
hostentry he;
he.initialize("localhost");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",he.getName());
printf(" Alias list:\n");
for (int i=0; he.getAliasList()[i]; i++) {
printf(" %s\n",he.getAliasList()[i]);
}
printf(" Address type: %d\n",he.getAddressType());
printf(" Address length: %d\n",he.getAddressLength());
printf(" Address list:\n");
for (int i=0; he.getAddressList()[i]; i++) {
char *addr=getAddressString(he.getAddressLength(),
he.getAddressList()[i]);
printf(" %s\n",addr);
delete[] addr;
}
printf("\n");
// use the built in print method
printf("Built In...\n");
he.print();
printf("\n");
// get the host information for "127.0.0.1"
char address[]={127,0,0,1};
he.initialize(address,4,AF_INET);
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",he.getName());
printf(" Alias list:\n");
for (int i=0; he.getAliasList()[i]; i++) {
printf(" %s\n",he.getAliasList()[i]);
}
printf(" Address type: %d\n",he.getAddressType());
printf(" Address length: %d\n",he.getAddressLength());
printf(" Address list:\n");
for (int i=0; he.getAddressList()[i]; i++) {
char *addr=getAddressString(he.getAddressLength(),
he.getAddressList()[i]);
printf(" %s\n",addr);
delete[] addr;
}
printf("\n");
// use the built in print method
printf("Built In...\n");
he.print();
printf("\n");
}
Using the protocolentry ClassThe protocolentry class allows you to look up entries from /etc/protocols or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2002 David Muse
// See the file COPYING for more information
#include <rudiments/protocolentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the protocol information for "tcp"
protocolentry pe;
pe.initialize("tcp");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",pe.getName());
printf(" Alias list:\n");
for (int i=0; pe.getAliasList()[i]; i++) {
printf(" %s\n",pe.getAliasList()[i]);
}
printf(" Number: %d\n",pe.getNumber());
printf("\n");
// use the built in print method
printf("Built In...\n");
pe.print();
printf("\n");
// get the protocol information for protocol number 6
pe.initialize(6);
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",pe.getName());
printf(" Alias list:\n");
for (int i=0; pe.getAliasList()[i]; i++) {
printf(" %s\n",pe.getAliasList()[i]);
}
printf(" Number: %d\n",pe.getNumber());
printf("\n");
// use the built in print method
printf("Built In...\n");
pe.print();
printf("\n");
}
Using the serviceentry ClassThe serviceentry class allows you to look up entries from /etc/services or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/serviceentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the service information for "smtp","tcp"
serviceentry se;
se.initialize("smtp","tcp");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",se.getName());
printf(" Port: %d\n",se.getPort());
printf(" Protocol: %s\n",se.getProtocol());
printf(" Alias list:\n");
for (int i=0; se.getAliasList()[i]; i++) {
printf(" %s\n",se.getAliasList()[i]);
}
printf("\n");
// use the built in print method
printf("Built In...\n");
se.print();
printf("\n");
// get the service information for the service on port 25, "tcp"
se.initialize(25,"tcp");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",se.getName());
printf(" Port: %d\n",se.getPort());
printf(" Protocol: %s\n",se.getProtocol());
printf(" Alias list:\n");
for (int i=0; se.getAliasList()[i]; i++) {
printf(" %s\n",se.getAliasList()[i]);
}
printf("\n");
// use the built in print method
printf("Built In...\n");
se.print();
printf("\n");
}
Using the rpcentry ClassThe rpcentry class allows you to look up entries from /etc/rpc or from elsewhere if you're using the Name Service Switch.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/rpcentry.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// get the rpc information for "portmap"
rpcentry re;
re.initialize("portmap");
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",re.getName());
printf(" Number: %d\n",re.getNumber());
printf(" Alias list:\n");
for (int i=0; re.getAliasList()[i]; i++) {
printf(" %s\n",re.getAliasList()[i]);
}
printf("\n");
// use the built in print method
printf("Built In...\n");
re.print();
printf("\n");
// get the protocol information for protocol number 100000
re.initialize(100000);
// print the components individually
printf("Individually...\n");
printf(" Name: %s\n",re.getName());
printf(" Number: %d\n",re.getNumber());
printf(" Alias list:\n");
for (int i=0; re.getAliasList()[i]; i++) {
printf(" %s\n",re.getAliasList()[i]);
}
printf("\n");
// use the built in print method
printf("Built In...\n");
re.print();
printf("\n");
}
Using the linkedlist ClassThe linkedlist class allows you to store arbitrary data in a doubly-linked list.
Since lists of strings are commonly used, a stringlist typedef is provided for convenience.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/linkedlist.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, char **argv) {
// create a list of integers
linkedlist<int> intl;
// append values to the list, displaying the list after each append
printf("append(0)\n");
intl.append(0);
intl.print();
printf("append(1)\n");
intl.append(1);
intl.print();
printf("append(3)\n");
intl.append(3);
intl.print();
// insert a value into the middle of the list, display the list
printf("insert(2,2)\n");
intl.insert(2,2);
intl.print();
// remove values from the list, displaying the list after each removal
printf("removeByIndex(0)\n");
intl.removeByIndex(0);
intl.print();
printf("removeByData(3)\n");
intl.removeByData(3);
intl.print();
// change a value in the list, display the list
printf("setDataByIndex(1,50)\n");
intl.setDataByIndex(1,50);
intl.print();
// clear the list, display the list
printf("clear()\n");
intl.clear();
intl.print();
printf("\n\n");
// create a list of strings
stringlist strl;
// append values to the list, displaying the list after each append
printf("append(zero)\n");
strl.append("zero");
strl.print();
printf("append(one)\n");
strl.append("one");
strl.print();
printf("append(three)\n");
strl.append("three");
strl.print();
// insert a value into the middle of the list, display the list
printf("insert(2,two)\n");
strl.insert(2,"two");
strl.print();
// remove values from the list, displaying the list after each removal
printf("removeByIndex(0)\n");
strl.removeByIndex(0);
strl.print();
printf("removeByData(three)\n");
strl.removeByData("three");
strl.print();
// change a value in the list, display the list
printf("setDataByIndex(1,fifty)\n");
strl.setDataByIndex(1,"fifty");
strl.print();
// clear the list, display the list
printf("clear()\n");
strl.clear();
strl.print();
}
Using the dictionary ClassThe dictionary class allows you to store arbitrary key/value-pair data.
Since dictionaries with string and long integer keys and dictionaries with string keys and values are commonly used, convenience classes are provided for each.
// Copyright (c) 2003 David Muse
// See the file COPYING for more information
#include <rudiments/dictionary.h>
#include <stdio.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
int main(int argc, const char **argv) {
// create a dictionary containing string keys and string values
namevaluepairs dict;
printf("string keys, string values:\n");
// add values to the dictionary
dict.setData("1","one");
dict.setData("2","two");
dict.setData("3","three");
dict.setData("4","four");
// display the length and contents of the dictionary
printf("length: %ld\n",dict.getList()->getLength());
dict.print();
printf("\n");
// remove values, displaying the dictionary after each removal
dict.removeData("3");
dict.print();
printf("\n");
dict.removeData("2");
dict.print();
printf("\n");
dict.removeData("4");
dict.print();
printf("\n");
dict.removeData("1");
dict.print();
// create a dictionary containing long integer keys and string values
numericdictionary<char *> numdict;
printf("integer keys, string values:\n");
// add values to the dictionary
numdict.setData(1,"one");
numdict.setData(2,"two");
numdict.setData(3,"three");
numdict.setData(4,"four");
// display the length and contents of the dictionary
printf("length: %ld\n",numdict.getList()->getLength());
numdict.print();
printf("\n");
// remove values, displaying the dictionary after each removal
numdict.removeData(3);
numdict.print();
printf("\n");
numdict.removeData(2);
numdict.print();
printf("\n");
numdict.removeData(4);
numdict.print();
printf("\n");
numdict.removeData(1);
numdict.print();
printf("\n");
// create a dictionary containing double precision
// floating point keys and string values
dictionary<double,char *> doubledict;
printf("floating point keys, string values:\n");
// add values to the dictionary
doubledict.setData(1.1,"one point one");
doubledict.setData(2.2,"two point two");
doubledict.setData(3.3,"three point three");
doubledict.setData(4.4,"four point four");
// display the length and contents of the dictionary
printf("length: %ld\n",doubledict.getList()->getLength());
doubledict.print();
printf("\n");
// remove values, displaying the dictionary after each removal
doubledict.removeData(3.3);
doubledict.print();
printf("\n");
doubledict.removeData(2.2);
doubledict.print();
printf("\n");
doubledict.removeData(4.4);
doubledict.print();
printf("\n");
doubledict.removeData(1.1);
doubledict.print();
printf("\n");
}