PLIB 1.8.5+ r2173 from http://plib.svn.sourceforge.net/svnroot/plib/trunk
This commit is contained in:
626
doc/util/index.html
Normal file
626
doc/util/index.html
Normal file
@@ -0,0 +1,626 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<META name="keywords" content="UL, PLIB, OpenGL, utility, library, portable, Baker, Steve, ulDir, ulClock, ulDynamicLibrary, ulList, ulLinkedList, ulHashTable, ulPropertySet, ulSleep, ulMilliSecondSleep, ulFindFile, ulFileExists, ulIsAbsolutePathName, ulGetCWD, ulMakePath, ulSetErrorCallback, ulGetErrorCallback, ulGetError, ulClearError, ulStrEqual, ulStrNEqual">
|
||||
<META name="description" content="The PLIB Utility Library is targeted towards hiding common operating system functions behind a thin layer that makes them portable and provides some useful helper classes and routines.">
|
||||
<TITLE>The Utility Library.</TITLE>
|
||||
</HEAD>
|
||||
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B"
|
||||
bgcolor="#005000" background="../marble.png">
|
||||
|
||||
<H1>The PLIB general Utility Library.</H1>
|
||||
By Sebastian Ude
|
||||
<H2>Introduction</H2>
|
||||
The 'UL' utility library is primarily targeted towards hiding common
|
||||
operating system functions behind a thin layer that makes them portable.
|
||||
Additionally, it provides some helper classes or routines that were
|
||||
usually written to support certain parts of the
|
||||
<a href="../index.html">PLIB</a> library, but at some point we felt that
|
||||
they could be useful for user applications as well.
|
||||
<p>
|
||||
UL is a part of <a href="../index.html">PLIB</a>.
|
||||
|
||||
<h2>Contents:</h2>
|
||||
<ul>
|
||||
<li><a href="#miscFunc">Misc. routines</a>
|
||||
<li><a href="#fileHandling">File handling</a>
|
||||
<li><a href="#dirHandling">Directory handling</a>
|
||||
<li><a href="#dataStorage">Data storage</a>
|
||||
<li><a href="#errorHandling">Error handling</a>
|
||||
<li><a href="#miscClasses">Misc. classes</a>
|
||||
<li><a href="#endianHandling">Endian handling</a>
|
||||
</ul>
|
||||
|
||||
<h2>Quick reference:</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td><h3>Classes:</h3>
|
||||
<td colspan=2><h3>Non-class functions:</h3>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="#ulDir">ulDir</a>
|
||||
<li><a href="#ulClock">ulClock</a>
|
||||
<li><a href="#ulDynamicLibrary">ulDynamicLibrary</a>
|
||||
<li><a href="#ulList">ulList</a>
|
||||
<li><a href="#ulLinkedList">ulLinkedList</a>
|
||||
<li><a href="#ulHashTable">ulHashTable</a>
|
||||
<li><a href="#ulPropertySet">ulPropertySet</a>
|
||||
</ul>
|
||||
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="#ulSleep">ulSleep</a>, <a href="#ulMilliSecondSleep">ulMilliSecondSleep</a>
|
||||
<li><a href="#ulFindFile">ulFindFile</a>
|
||||
<li><a href="#ulFileExists">ulFileExists</a>
|
||||
<li><a href="#ulIsAbsolutePathName">ulIsAbsolutePathName</a>
|
||||
<li><a href="#ulGetCWD">ulGetCWD</a>
|
||||
<li><a href="#ulMakePath">ulMakePath</a>
|
||||
<li><a href="#ulSetErrorCallback">ulSetErrorCallback</a>, <a href="#ulGetErrorCallback">ulGetErrorCallback</a>
|
||||
</ul>
|
||||
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li><a href="#ulGetError">ulGetError</a>, <a href="#ulClearError">ulClearError</a>
|
||||
<li><a href="#ulStrEqual">ulStrEqual</a>, <a href="#ulStrNEqual">ulStrNEqual</a>
|
||||
</ul>
|
||||
</table>
|
||||
|
||||
<h2><a name="miscFunc">Misc. routines</a></h2>
|
||||
|
||||
<h3><a name="ulSleep">ulSleep</a></h3>
|
||||
<pre><i>
|
||||
void ulSleep ( int seconds ) ;
|
||||
</i></pre>
|
||||
Now comes a typical example of what the UL library does. If you need to
|
||||
'sleep' for, say, 3 seconds, then under Linux/UNIX, you'd need to call:
|
||||
<pre><i>
|
||||
sleep ( 3 ) ;
|
||||
</i></pre>
|
||||
But under MS-Windows, you have to say:
|
||||
<pre><i>
|
||||
Sleep ( 3000 ) ;
|
||||
</i></pre>
|
||||
In order to avoid writing non-portable code, you can instead call:
|
||||
<pre><i>
|
||||
ulSleep ( 3 ) ;
|
||||
</i></pre>
|
||||
...under either operating system.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulMilliSecondSleep">ulMilliSecondSleep</a></h3>
|
||||
<pre><i>
|
||||
void ulMilliSecondSleep ( int milliseconds ) ;
|
||||
</i></pre>
|
||||
Same as <a href="#ulSleep">ulSleep</a>, except that it sleeps (as you
|
||||
may have guessed) a certain number of milliseconds instead of seconds.
|
||||
|
||||
<h2><a name="fileHandling">File handling</a></h2>
|
||||
|
||||
<h3><a name="ulFindFile">ulFindFile</a></h3>
|
||||
<pre><i>
|
||||
void ulFindFile ( char *filenameOutput, const char *path, const char * tfnameInput, const char *sAPOM ) ;
|
||||
</i></pre>
|
||||
Basically, this utility function adds tfnameInput to the path and puts this
|
||||
into the buffer filenameOutput.
|
||||
<p>
|
||||
It handles special chars in path:
|
||||
<ul>
|
||||
<li>";;" is replaced by ";"
|
||||
<li>"$$" is replaced by "$"
|
||||
<li>"$(APOM)" is replaced by sAPOM
|
||||
</ul>
|
||||
If there are ";" in path, the path-variable is interpreted as several paths
|
||||
"segments", delimited by ";". The first file found by this function is
|
||||
returned. It looks from left to right. A segment may end in $(...). ulFindFile
|
||||
will then look in in this path and recursively in all the sub-paths.
|
||||
<p>
|
||||
Some examples:
|
||||
<p>
|
||||
To load *.MDl-models, it is very nice to set the texture path to
|
||||
"$(APOM);$(APOM)/texture;$(APOM)/../texture". This consists of three segments
|
||||
and tells ulFindFile to look in the path of the model, in a subpath texture
|
||||
and in a path texture "besides" the path of the model. Some *.mdl-models are
|
||||
shipped in a directory which contains a "texture"-directory, a
|
||||
"Model"-directory and others. In this case you find the texture in
|
||||
"$(APOM)/../texture".
|
||||
<p>
|
||||
Another example: You have all your textures in a directory-structure under
|
||||
/roomplan:
|
||||
<pre>
|
||||
textures --+-- Wallpapers
|
||||
|
|
||||
+-- Wood --+-- Oak
|
||||
| |
|
||||
| +-- pine
|
||||
...
|
||||
</pre>
|
||||
Then you should simply use the following texture path:
|
||||
"/roomplan/$(...)"
|
||||
|
||||
<p>
|
||||
<h3><a name="ulFileExists">ulFileExists</a></h3>
|
||||
<pre><i>
|
||||
bool ulFileExists ( const char *fileName ) ;
|
||||
</i></pre>
|
||||
Returns "true" if a file with the name 'fileName' exists, or "false" if
|
||||
it does not.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulIsAbsolutePathName">ulIsAbsolutePathName</a></h3>
|
||||
<pre><i>
|
||||
int ulIsAbsolutePathName ( const char *pathname ) ;
|
||||
</i></pre>
|
||||
Returns '1' if 'pathname' is an absolute pathname or '0' if it is an
|
||||
relative one.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulGetCWD">ulGetCWD</a></h3>
|
||||
<pre><i>
|
||||
char * ulGetCWD ( char *result, int maxlength ) ;
|
||||
</i></pre>
|
||||
Stores the current working directory in 'result', which has enough space
|
||||
for 'maxlength' characters, including the trailing '\0'. On success,
|
||||
'result' is returned.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulMakePath">ulMakePath</a></h3>
|
||||
<pre><i>
|
||||
char * ulMakePath ( char *path, const char *dir, const char *fname ) ;
|
||||
</i></pre>
|
||||
Concatenates the strings 'dir' and 'fname', puts the system's slash character
|
||||
inbetween and stores stores the result in 'path'. Be sure that the buffer
|
||||
'path' is large enough to store 'strlen ( dir ) + strlen ( fname ) + 2'
|
||||
(slash and trailing '\0') characters.
|
||||
|
||||
<h2><a name="dirHandling">Directory handling</a></h2>
|
||||
|
||||
<h3><a name="ulDir">struct ulDir</a></h3>
|
||||
This structure provides a portable way to read directories. To allocate and
|
||||
initialize a new ulDir structure, call:
|
||||
<pre><i>
|
||||
ulDir * ulOpenDir ( const char* dirname ) ;
|
||||
</i></pre>
|
||||
This function returns a pointer to a newly allocated ulDir structure on
|
||||
success or a NULL pointer if the specified directory could not be read.
|
||||
<p>
|
||||
After you have constructed an ulDir structure, the directory content can
|
||||
be read with subsequent calls to:
|
||||
<pre><i>
|
||||
struct ulDirEnt
|
||||
{
|
||||
char d_name [ UL_NAME_MAX+1 ] ;
|
||||
bool d_isdir ;
|
||||
} ;
|
||||
ulDirEnt * ulReadDir ( ulDir *dir ) ;
|
||||
</i></pre>
|
||||
This function returns a pointer to a ulDirEnt structure which resides in
|
||||
the corresponding ulDir structure and which has the above form. The "d_isdir"
|
||||
flag indicates if a directory entry is another directory. If the end of the
|
||||
directory has been reached, the function returns NULL.
|
||||
<p>
|
||||
To free an ulDir object and to close the associated directory stream,
|
||||
please call:
|
||||
<pre><i>
|
||||
void ulCloseDir ( ulDir *dir ) ;
|
||||
</i></pre>
|
||||
|
||||
<h2><a name="dataStorage">Data storage</a></h2>
|
||||
|
||||
<h3><a name="ulList">class ulList</a></h3>
|
||||
<pre><i>
|
||||
ulList::ulList ( int init_max = 1 ) ;
|
||||
</i></pre>
|
||||
This class stores a list of generic (void*) pointers using an
|
||||
automatically-growing array. Since the process of resizing the internal
|
||||
array is rather expensive, it is important that one picks a reasonable default
|
||||
array size (<i>init_max</i>) when constructing an ulList object if performance
|
||||
matters. Remember that a too large size means that some memory is wasted (but
|
||||
memory is cheap nowadays), while a too small one means that expensive array
|
||||
resize operations will be necessary later.
|
||||
<p>
|
||||
If you have absolutely no clue about how many entities will be stored,
|
||||
you should probably look at the <a href="#ulLinkedList">linked list class</a>
|
||||
below, which has it's own disadvantages, though.
|
||||
<p>
|
||||
Once you have constructed an ulList (hopefully with a good initial size),
|
||||
you can insert an element using one of the following methods:
|
||||
<pre><i>
|
||||
void ulList::addEntity ( void *entity ) ;
|
||||
void ulList::addBefore ( int n, void *entity ) ;
|
||||
</i></pre>
|
||||
While the first one simply adds the new entity to the tail of the list,
|
||||
the second one lets you specify an exact position (0 is the first element).
|
||||
Note that due to it's array implementation, inserting an entity at the head
|
||||
or the middle of the ulList requires that the following entities are all
|
||||
shifted one array slot to the right, which can be a rather expensive
|
||||
operation.
|
||||
<p>
|
||||
These functions automatically check whether there is room for one more element
|
||||
and double the internal array's size if necessary. However, as said
|
||||
previously, resizing the array is a rather expensive process, so it is not
|
||||
recommended that you rely too much on this behavior. Instead, pick a good
|
||||
initial array size.
|
||||
<p>
|
||||
Note that ulList allows you to have multiple entities with the same data
|
||||
value in the list. Please also note that ulList does not make it's own copy
|
||||
of the data pointed to by 'entity'. It is up to you to take care of that the
|
||||
memory region that 'entity' points to holds something useful as long as the
|
||||
ulList exists. Be especially careful with addresses of variables that have a
|
||||
limited lifetime.
|
||||
<p>
|
||||
To retrieve an entity, call:
|
||||
<pre><i>
|
||||
void * ulList::getEntity ( unsigned int n ) ;
|
||||
</i></pre>
|
||||
Where 'n' is the position of the entity in the list. If 'n' is not a valid
|
||||
index, NULL is returned. Once you have called this function, you can use
|
||||
subsequent calls to
|
||||
<pre><i>
|
||||
void * ulList::getNextEntity ( void ) ;
|
||||
</i></pre>
|
||||
in order to retrieve the following entities in the list. If there are no more
|
||||
entities, this function will return NULL.
|
||||
<p>
|
||||
To remove an entity, call one of:
|
||||
<pre><i>
|
||||
void ulList::removeEntity ( unsigned int n ) ;
|
||||
void ulList::removeEntity ( void *entity ) ;
|
||||
</i></pre>
|
||||
Where the second function removes the <b>first</b> entity with the specified
|
||||
data value in case there are multiple ones.
|
||||
<p>
|
||||
To replace the value of an entity, call one of:
|
||||
<pre><i>
|
||||
void ulList::replaceEntity ( unsigned int n, void *new_entity ) ;
|
||||
void ulList::replaceEntity ( void *old_entity, void *new_entity ) ;
|
||||
</i></pre>
|
||||
Where the second function will replace the value of the <b>first</b> entity
|
||||
with the specified old data value in case there are multiple ones.
|
||||
<p>
|
||||
And finally, you can retrieve the number of entities stored in the list
|
||||
(that's <b>not</b> necessarily the internal array's size), remove all
|
||||
entities or retrieve the position of an entity by specifying it's data
|
||||
value:
|
||||
<pre><i>
|
||||
void ulList::getNumEntities ( void ) const ;
|
||||
void ulList::removeAllEntities () ;
|
||||
int ulList::searchForEntity ( void *entity ) const ;
|
||||
</i></pre>
|
||||
Where the latter returns a negative value if no entity with the specified
|
||||
value was found in the list, and otherwise the position of the <b>first</b>
|
||||
entity with the specified data value.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulLinkedList">class ulLinkedList</a></h3>
|
||||
<pre><i>
|
||||
ulLinkedList::ulLinkedList () ;
|
||||
</i></pre>
|
||||
The ulLinkedList class stores generic (void*) pointers using a linked list
|
||||
of nodes where each node maintains a pointer to the next node.
|
||||
<p>
|
||||
This technique has some advantages compared to an array implementation of a
|
||||
list like <a href="#ulList">ulList</a>.
|
||||
<ul>
|
||||
<li>
|
||||
No wasted memory. When storing data using arrays (as
|
||||
<a href="#ulList">ulList</a> does), it is a common practice to choose an array
|
||||
size that seems "large enough". Most of the time the number of entities stored
|
||||
will be smaller than the available array slots, so some memory space is wasted.
|
||||
With a linked list, we allocate single nodes. No memory is wasted (except a
|
||||
few bytes for each node's pointer to the next node).
|
||||
|
||||
<li>
|
||||
Resizing an array is an expensive operation, since usually the whole array
|
||||
content has to be copied from the old to the new memory location. We do not
|
||||
have this problem with linked lists.
|
||||
|
||||
<li>
|
||||
In contrast to arrays, it is a cheap operation to insert or remove entities
|
||||
to / from the head or middle of a linked list. While with an array, the
|
||||
following entities must all be shifted one slot to the left or right, we
|
||||
simply need to (re)connect a few pointers with a linked list.
|
||||
</ul>
|
||||
There are some disadvantages, though:
|
||||
<ul>
|
||||
<li>
|
||||
In contrast to an array, there is no cheap way to locate the n-th entity in a
|
||||
linked list. With an array, you simply have to add the desired position
|
||||
multiplied with the size of an element to the array's base address and
|
||||
look at the content of the memory at this location - a very simple operation.
|
||||
With a linked list, however, we need to iterate over all nodes 'n' times,
|
||||
so locating the 1000th node is a rather expensive operation.
|
||||
|
||||
<li>
|
||||
One may argue that insertion operations are more expensive with linked lists
|
||||
than with arrays, since we allocate single nodes from the heap in contrast
|
||||
to an array, where the whole list is one huge allocated block of memory.
|
||||
Although allocation from the heap is indeed rather expensive, this is not
|
||||
true when it comes to insertions to the middle of a list, these are usually
|
||||
<b>way</b> more expensive with arrays. Furthermore, a list implemented using
|
||||
an array such as <a href="#ulList">ulList</a> may make resizes of the array
|
||||
necessary on insertions, which are again rather expensive.
|
||||
</ul>
|
||||
Decide yourself if a list implemented as an array such as
|
||||
<a href="#ulList">ulList</a> or a linked list implementation like this one fits
|
||||
your needs better.
|
||||
<p>
|
||||
Once you have constructed a ulLinkedList object, you can insert a node using
|
||||
one of:
|
||||
<pre><i>
|
||||
void ulLinkedList::appendNode ( void *data ) ;
|
||||
void ulLinkedList::prependNode ( void *data ) ;
|
||||
void ulLinkedList::insertNode ( void *data, int pos ) ;
|
||||
</i></pre>
|
||||
While "appendNode" adds the new node at the tail of the list, "prependNode"
|
||||
will place the new node at the head of the list, and "insertNode" allows
|
||||
you to specify the desired position ('0' is the first node) yourself; 'pos'
|
||||
must be either '0' or a number between '0' and the number of nodes minus one.
|
||||
"prependNode" is equal to calling "insertNode" with pos == 0.
|
||||
<p>
|
||||
Note that ulLinkedList allows you to have two nodes with the same data in
|
||||
the list. Also note that just as <a href="#ulList">ulList</a>, ulLinkedList
|
||||
does not make it's own copy of the memory pointed to by 'data', so make sure
|
||||
that the corresponding memory location holds something useful as long as the
|
||||
list exists.
|
||||
<p>
|
||||
To retrieve the number of nodes in the list, call:
|
||||
<pre><i>
|
||||
int ulLinkedList::getNumNodes ( void ) const ;
|
||||
</i></pre>
|
||||
<p>
|
||||
To retrieve the data of the node at a certain position in the list, call:
|
||||
<pre><i>
|
||||
void * ulLinkedList::getNodeData ( int pos ) const ;
|
||||
</i></pre>
|
||||
Where 'pos' must be a number between '0' and the number of nodes minus one,
|
||||
again.
|
||||
<p>
|
||||
If you need to retrieve the position of a node in the list by specifying it's
|
||||
data value, call:
|
||||
<pre><i>
|
||||
int ulLinkedList::getNodePosition ( void *data ) const ;
|
||||
</i></pre>
|
||||
If there is more than one node whose data value is 'data' in the list, this
|
||||
function will return the position of the <b>first</b> one. If there is no
|
||||
node with the specified data value in the list, this function will return a
|
||||
negative number to indicate failure.
|
||||
<p>
|
||||
Checking if the return value of "getNodePosition" is non-negative is also
|
||||
the recommended way to determine whether there exists at least one node with
|
||||
a certain data value in a list.
|
||||
<p>
|
||||
To remove a node from the list, call one of:
|
||||
<pre><i>
|
||||
bool ulLinkedList::removeNode ( void *data ) ;
|
||||
void * ulLinkedList::removeNode ( int pos ) ;
|
||||
</i></pre>
|
||||
Where the first function returns 'true' if the node was sucessfully removed or
|
||||
'false' if it could not find a node whose value is 'data'. In case there is
|
||||
more than one node whose data value is 'data', it will remove the <b>first</b>
|
||||
one. With the second function, 'pos' has to be a number between '0' and the
|
||||
number of nodes minus one. It's return value is the removed node's data
|
||||
value.
|
||||
<p>
|
||||
To iterate over the list (starting from the head) and to have a custom
|
||||
function being called for each node's data pointer, call:
|
||||
<pre><i>
|
||||
typedef bool (*ulIterateFunc)( void *data, void *user_data ) ;
|
||||
void * ulLinkedList::forEach ( ulIterateFunc fn, void *user_data = NULL ) const ;
|
||||
</i></pre>
|
||||
The iteration process will stop if your ulIterateFunc returns 'false', in
|
||||
which case "forEach" returns the data value of the node at which the iteration
|
||||
stopped, or if the tail of the list has been reached, in which case "forEach"
|
||||
returns NULL. The user_data pointer will be passed to your ulIterateFunc as
|
||||
the second argument.
|
||||
<p>
|
||||
ulLinkedList allows you to maintain a sorted list as an option. To set up
|
||||
a sorted list, simply be sure to insert all nodes using the sorted insertion
|
||||
function as soon as there is at least one node in the list. It's prototype is:
|
||||
<pre><i>
|
||||
typedef int (*ulCompareFunc)( const void *data1, const void *data2 ) ;
|
||||
int ulList::insertSorted ( void *data, ulCompareFunc comparefn ) ;
|
||||
</i></pre>
|
||||
Where 'comparefn' is your custom comparison function that takes two
|
||||
data pointers, compares them and returns a memcmp / strcmp-like result:
|
||||
<ul>
|
||||
<li>
|
||||
A number <b>less than zero</b> if "data1" is "smaller" than "data2", that
|
||||
means if "data1" had to be inserted <b>before</b> "data2" in the list.
|
||||
|
||||
<li>
|
||||
A number <b>equal to zero</b> if "data1" is equal to "data2", that means if
|
||||
"data" had to be inserted immediately before or after "data2" in the list.
|
||||
|
||||
<li>
|
||||
A number <b>greater than zero</b> if "data1" is "greater" than "data2",
|
||||
that means if "data" had to be inserted <b>after</b> "data2" in the list.
|
||||
</ul>
|
||||
The return value of "insertSorted" is the position of the new node in the list
|
||||
on success, or a negative value if you tried to do a sorted insertion on a
|
||||
non-sorted list, that is a list which contains more than one node of which
|
||||
at least one was not inserted using the sorted insertion function. In the
|
||||
latter case, the new node would not have been inserted to the list.
|
||||
<p>
|
||||
To determine whether a list is sorted or not, call the following function:
|
||||
<pre><i>
|
||||
bool ulLinkedList::isSorted ( void ) const ;
|
||||
</i></pre>
|
||||
Note that with a linked list, you <b>must not</b> modify the criteria of a
|
||||
node's data that is used for sorting without removing the node from the list
|
||||
and re-inserting it.
|
||||
<p>
|
||||
Finally, you can empty a list (remove all nodes) by calling:
|
||||
<pre><i>
|
||||
typedef bool (*ulIterateFunc)( const void *data ) ;
|
||||
void ulList::empty ( ulIterateFunc destroyfn = NULL, void *user_data = NULL ) ;
|
||||
</i></pre>
|
||||
Where "destroyfn" is an optionally specified function that will be called
|
||||
with each destroyed node's data pointer as the first and with user_data as
|
||||
the second argument. This is for example useful if the list entries are
|
||||
pointers to dynamically allocated objects that have to be freed on destruction
|
||||
of the list. The return value of the specified function is ignored.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulHashTable">ulHashTable</a></h3>
|
||||
Not yet.
|
||||
|
||||
<h2><a name="errorHandling">Error handling</a></h2>
|
||||
|
||||
<h3><a name="ulSetErrorCallback">ulSetErrorCallback</a></h3>
|
||||
<pre><i>
|
||||
typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ;
|
||||
void ulSetErrorCallback ( ulErrorCallback cb ) ;
|
||||
</i></pre>
|
||||
<a href="../index.html">PLIB</a> has an internal error handling system
|
||||
that the subsystems use to report debug, warning or error messages.
|
||||
An application can set up an error callback that PLIB will call whenever such
|
||||
a message occurs in addition to printing the message on the user's terminal.
|
||||
<p>
|
||||
ulSeverety indicates the importance of an message and is currently defined
|
||||
the following way:
|
||||
<pre><i>
|
||||
enum ulSeverity
|
||||
{
|
||||
UL_DEBUG,
|
||||
UL_WARNING,
|
||||
UL_FATAL
|
||||
} ;
|
||||
</i></pre>
|
||||
Where
|
||||
<ul>
|
||||
<li>UL_DEBUG are unimportant debug messages that can usually safely be ignored
|
||||
<li>UL_WARNING are important warning messages that should not be ignored
|
||||
<li>UL_FATAL are fatal errors that PLIB can not recover from
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h3><a name="ulGetErrorCallback">ulGetErrorCallback</a></h3>
|
||||
<pre><i>
|
||||
typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ;
|
||||
ulErrorCallback ulGetErrorCallback ( void ) ;
|
||||
</i></pre>
|
||||
Returns the current <a href="#ulSetErrorCallback">error callback</a> (if
|
||||
any, else NULL is returned).
|
||||
|
||||
<p>
|
||||
<h3><a name="ulGetError">ulGetError</a></h3>
|
||||
<pre><i>
|
||||
char * ulGetError ( void ) ;
|
||||
</i></pre>
|
||||
Returns a pointer to the error buffer, that is, the last error message or an
|
||||
empty string if there were not any error messages or if the error buffer has
|
||||
just been <a href="#ulClearError">cleared</a>.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulClearError">ulClearError</a></h3>
|
||||
<pre><i>
|
||||
void ulClearError ( void ) ;
|
||||
</i></pre>
|
||||
Clears the <a href="#ulGetError">error buffer</a>.
|
||||
|
||||
<h2><a name="miscClasses">Misc. classes</a></h2>
|
||||
|
||||
<h3><a name="ulDynamicLibrary">class ulDynamicLibrary</a></h3>
|
||||
<pre><i>
|
||||
ulDynamicLibrary::ulDynamicLibrary ( const char *libname ) ;
|
||||
</i></pre>
|
||||
This class provides a portable way to load a dynamic library and to retrieve
|
||||
the memory address of a specific function afterwards. When constructing an
|
||||
ulDynamicLibrary object, you have to specify the name of the dynamic library
|
||||
you want to operate on <b>without</b> the platform-specific file extension
|
||||
for dynamic libraries.
|
||||
<p>
|
||||
Afterwards, you can retrieve the memory address where a function / symbol of
|
||||
the library has been loaded by calling:
|
||||
<pre><i>
|
||||
void * ulDynamicLibrary::getFuncAddress ( const char *funcname ) :
|
||||
</i></pre>
|
||||
This function returns NULL if the specified symbol was not found.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulClock">ulClock</a></h3>
|
||||
<pre><i>
|
||||
ulClock::ulClock () ;
|
||||
</i></pre>
|
||||
No further documentation yet.
|
||||
|
||||
<h3><a name="ulPropertySet">ulPropertySet</a></h3>
|
||||
Not yet.
|
||||
|
||||
<h2><a name="stringHandling">String handling</a></h2>
|
||||
|
||||
<h3><a name="ulStrEqual">ulStrEqual</a></h3>
|
||||
<pre><i>
|
||||
int ulStrEqual ( const char *s1, const char *s2 ) ;
|
||||
</i></pre>
|
||||
This function provides a portable way to compare two strings while ignoring
|
||||
the case of the characters. We need it since half of the machines on the
|
||||
planet provide strcasecmp and the other half stricmp for this purpose.
|
||||
<p>
|
||||
In contrast to the libc string comparison routines, this routine returns '1'
|
||||
if the strings are <b>equal</b> and '0' if they are <b>not</b>.
|
||||
|
||||
<p>
|
||||
<h3><a name="ulStrNEqual">ulStrNEqual</a></h3>
|
||||
<pre><i>
|
||||
int ulStrNEqual ( const char *s1, const char *s2, int len ) ;
|
||||
</i></pre>
|
||||
Same as ulStrEqual, except that it only compares the first 'len' characters
|
||||
of the strings.
|
||||
|
||||
<p>
|
||||
<h2><a name="endianHandling">Endian handling</a></h2>
|
||||
<pre><i>
|
||||
bool ulIsLittleEndian ( void ) ;
|
||||
bool ulIsBigEndian ( void ) ;
|
||||
|
||||
unsigned short ulEndianLittle16 ( unsigned short x ) ;
|
||||
unsigned int ulEndianLittle32 ( unsigned int x ) ;
|
||||
float ulEndianLittleFloat ( float x ) ;
|
||||
|
||||
unsigned short ulEndianBig16 ( unsigned short x ) ;
|
||||
unsigned int ulEndianBig32 ( unsigned int x ) ;
|
||||
float ulEndianBigFloat ( float x ) ;
|
||||
|
||||
void ulEndianLittleArray16 ( unsigned short *x, int length ) ;
|
||||
void ulEndianLittleArray32 ( unsigned int *x, int length ) ;
|
||||
void ulEndianLittleArrayFloat ( float *x, int length ) ;
|
||||
|
||||
void ulEndianBigArray16 ( unsigned short *x, int length ) ;
|
||||
void ulEndianBigArray32 ( unsigned int *x, int length ) ;
|
||||
void ulEndianBigArrayFloat ( float *x, int length ) ;
|
||||
|
||||
unsigned short ulEndianReadLittle16 ( FILE *f ) ;
|
||||
unsigned int ulEndianReadLittle32 ( FILE *f ) ;
|
||||
float ulEndianReadLittleFloat ( FILE *f ) ;
|
||||
|
||||
unsigned short ulEndianReadBig16 ( FILE *f ) ;
|
||||
unsigned int ulEndianReadBig32 ( FILE *f ) ;
|
||||
float ulEndianReadBigFloat ( FILE *f ) ;
|
||||
|
||||
size_t ulEndianWriteLittle16 ( FILE *f, unsigned short x ) ;
|
||||
size_t ulEndianWriteLittle32 ( FILE *f, unsigned int x ) ;
|
||||
size_t ulEndianWriteLittleFloat ( FILE *f, float x ) ;
|
||||
|
||||
size_t ulEndianWriteBig16 ( FILE *f, unsigned short x ) ;
|
||||
size_t ulEndianWriteBig32 ( FILE *f, unsigned int x ) ;
|
||||
size_t ulEndianWriteBigFloat ( FILE *f, float x ) ;
|
||||
</i></pre>
|
||||
No further documentation yet.
|
||||
|
||||
<hr>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://validator.w3.org/check/referer"><img border="0" src="../valid-html40.png" alt="Valid HTML 4.0!" height="31" width="88"></a>
|
||||
<td>
|
||||
<ADDRESS>
|
||||
Sebastian Ude <<A HREF="mailto:ude@handshake.de">ude@handshake.de</A>>
|
||||
</ADDRESS>
|
||||
</table>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
Reference in New Issue
Block a user