This file is indexed.

/usr/share/doc/libplib-doc/html/util/index.html is in libplib-doc 1:1.8.5-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
<!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 &lt;<A HREF="mailto:ude@handshake.de">ude@handshake.de</A>&gt;
</ADDRESS>
</table>
</BODY>
</HTML>