blob: 1232cff0acc1c4e6289da8ad2936126089e447d7 [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Linked objects, lists, templates, and containers.
20 * Common support for objects that might be organized as single and double
21 * linked lists, rings and queues, and tree oriented data structures. These
22 * generic classes may be used to help form anything from callback
23 * registration systems and indexed memory hashes to xml parsed tree nodes.
24 * @file ucommon/linked.h
25 */
26
27/**
28 * An example of the linked object classes and their use.
29 * @example linked.cpp
30 */
31
32#ifndef _UCOMMON_LINKED_H_
33#define _UCOMMON_LINKED_H_
34
35#ifndef _UCOMMON_CONFIG_H_
36#include <ucommon/platform.h>
37#endif
38
39#ifndef _UCOMMON_OBJECT_H_
40#include <ucommon/object.h>
41#endif
42
43NAMESPACE_UCOMMON
44
45class OrderedObject;
46
47/**
48 * Common base class for all objects that can be formed into a linked list.
49 * This base class is used directly for objects that can be formed into a
50 * single linked list. It is also used directly as a type for a pointer to the
51 * start of list of objects that are linked together as a list.
52 * @author David Sugar <dyfet@gnutelephony.org>
53 */
54class __EXPORT LinkedObject : public ObjectProtocol
55{
56protected:
57 friend class OrderedIndex;
58 friend class LinkedRing;
59 friend class NamedObject;
60 friend class ObjectStack;
61
62 LinkedObject *Next;
63
64 /**
65 * Construct base class attached to a chain of objects.
66 * @param root pointer to chain of objects we are part of.
67 */
68 LinkedObject(LinkedObject **root);
69
70 /**
71 * Construct base class unattached to anyone. This might be
72 * used to construct intermediary base classes that may form
73 * lists through indexing objects.
74 */
75 LinkedObject();
76
77public:
78 static const LinkedObject *nil; /**< Marker for end of linked list. */
79 static const LinkedObject *inv; /**< Marker for invalid list pointer */
80
81 virtual ~LinkedObject();
82
83 /**
84 * Release list, mark as no longer linked. Inherited from base Object.
85 */
86 virtual void release(void);
87
88 /**
89 * Retain by marking as self referenced list. Inherited from base Object.
90 */
91 virtual void retain(void);
92
93 /**
94 * Add our object to an existing linked list through a pointer. This
95 * forms a container sorted in lifo order since we become the head
96 * of the list, and the previous head becomes our next.
97 * @param root pointer to list we are adding ourselves to.
98 */
99 void enlist(LinkedObject **root);
100
101 /**
102 * Locate and remove ourselves from a list of objects. This searches
103 * the list to locate our object and if found relinks the list around
104 * us.
105 * @param root pointer to list we are removing ourselves from.
106 */
107 void delist(LinkedObject **root);
108
109 /**
110 * Search to see if we are a member of a specific list.
111 * @return true if we are member of the list.
112 */
113 bool is_member(LinkedObject *list) const;
114
115 /**
116 * Release all objects from a list.
117 * @param root pointer to list we are purging.
118 */
119 static void purge(LinkedObject *root);
120
121 /**
122 * Count the number of linked objects in a list.
123 * @param root pointer to list we are counting.
124 */
125 static unsigned count(const LinkedObject *root);
126
127 /**
128 * Get member by index.
129 * @return indexed member in linked list.
130 * @param root pointer to list we are indexing.
131 * @param index member to find.
132 */
133 static LinkedObject *getIndexed(LinkedObject *root, unsigned index);
134
135 /**
136 * Get next effective object when iterating.
137 * @return next linked object in list.
138 */
139 inline LinkedObject *getNext(void) const
140 {return Next;};
141};
142
143/**
144 * Reusable objects for forming private heaps. Reusable objects are
145 * linked objects that may be allocated in a private heap, and are
146 * returned to a free list when they are no longer needed so they can
147 * be reused without having to be re-allocated. The free list is the
148 * root of a linked object chain. This is used as a base class for those
149 * objects that will be managed through reusable heaps.
150 * @author David Sugar <dyfet@gnutelephony.org>
151 */
152class __EXPORT ReusableObject : public LinkedObject
153{
154 friend class ReusableAllocator;
155
156protected:
157 virtual void release(void);
158
159public:
160 /**
161 * Get next effective reusable object when iterating.
162 * @return next reusable object in list.
163 */
164 inline ReusableObject *getNext(void)
165 {return static_cast<ReusableObject*>(LinkedObject::getNext());};
166};
167
168/**
169 * An index container for maintaining an ordered list of objects.
170 * This index holds a pointer to the head and tail of an ordered list of
171 * linked objects. Fundamental methods for supporting iterators are
172 * also provided.
173 * @author David Sugar <dyfet@gnutelephony.org>
174 */
175class __EXPORT OrderedIndex
176{
177protected:
178 friend class OrderedObject;
179 friend class DLinkedObject;
180 friend class LinkedList;
181 friend class NamedObject;
182
183 OrderedObject *head, *tail;
184
185 void copy(const OrderedIndex& source);
186
187public:
188 /**
189 * Create and initialize an empty index.
190 */
191 OrderedIndex();
192
193 inline OrderedIndex(const OrderedIndex& source)
194 {copy(source);}
195
196 /**
197 * Destroy index.
198 */
199 virtual ~OrderedIndex();
200
201 /**
202 * Find a specific member in the ordered list.
203 * @param offset to member to find.
204 */
205 LinkedObject *find(unsigned offset) const;
206
207 /**
208 * Count of objects this list manages.
209 * @return number of objects in the list.
210 */
211 unsigned count(void) const;
212
213 /**
214 * Purge the linked list and then set the index to empty.
215 */
216 void purge(void);
217
218 /**
219 * Reset linked list to empty without purging.
220 */
221 void reset(void);
222
223 /**
224 * Used to synchronize lists managed by multiple threads. A derived
225 * locking method would be invoked.
226 */
227 virtual void lock_index(void);
228
229 /**
230 * Used to synchronize lists managed by multiple threads. A derived
231 * unlocking method would be invoked.
232 */
233 virtual void unlock_index(void);
234
235 /**
236 * Return a pointer to the head of the list. This allows the head
237 * pointer to be used like a simple root list pointer for pure
238 * LinkedObject based objects.
239 * @return LinkedIndex style object.
240 */
241 LinkedObject **index(void) const;
242
243 /**
244 * Get (pull) object off the list. The start of the list is advanced to
245 * the next object.
246 * @return LinkedObject based object that was head of the list.
247 */
248 LinkedObject *get(void);
249
250 /**
251 * Add an object into the ordered index.
252 * @param ordered object to add to the index.
253 */
254 void add(OrderedObject *ordered);
255
256 /**
257 * Get an indexed member from the ordered index.
258 * @param index of member to fetch.
259 * @return LinkedObject member of index.
260 */
261 inline LinkedObject *getIndexed(unsigned index) const
262 {return LinkedObject::getIndexed((LinkedObject*)head, index);};
263
264 /**
265 * Return first object in list for iterators.
266 * @return first object in list.
267 */
268 inline LinkedObject *begin(void) const
269 {return (LinkedObject*)(head);};
270
271 /**
272 * Return last object in list for iterators.
273 * @return last object in list.
274 */
275 inline LinkedObject *end(void) const
276 {return (LinkedObject*)(tail);};
277
278 /**
279 * Return head object pointer.
280 * @return head pointer.
281 */
282 inline LinkedObject *operator*() const
283 {return (LinkedObject*)(head);};
284
285 /**
286 * Assign ordered index.
287 * @param object to copy from.
288 */
289 OrderedIndex& operator=(const OrderedIndex& object)
290 {copy(object); return *this;}
291
292 /**
293 * Add object to our list.
294 * @param object to add.
295 */
296 void operator*=(OrderedObject *object);
297};
298
299/**
300 * A linked object base class for ordered objects. This is used for
301 * objects that must be ordered and listed through the OrderedIndex
302 * class.
303 * @author David Sugar <dyfet@gnutelephony.org>
304 */
305class __EXPORT OrderedObject : public LinkedObject
306{
307protected:
308 friend class LinkedList;
309 friend class OrderedIndex;
310 friend class DLinkedObject;
311 friend class ObjectQueue;
312
313 /**
314 * Construct an ordered object aot end of a an index.
315 * @param index we are listed on.
316 */
317 OrderedObject(OrderedIndex *index);
318
319 /**
320 * Construct an ordered object unattached.
321 */
322 OrderedObject();
323
324public:
325 /**
326 * List our ordered object at end of a linked list on an index.
327 * @param index we are listing on.
328 */
329 void enlistTail(OrderedIndex *index);
330
331 /**
332 * List our ordered object at start of a linked list on an index.
333 * @param index we are listing on.
334 */
335 void enlistHead(OrderedIndex *index);
336
337 /**
338 * List our ordered object in default strategy mode. The default
339 * base class uses enlistTail.
340 * @param index we are listing on.
341 */
342 virtual void enlist(OrderedIndex *index);
343
344 /**
345 * Remove our ordered object from an existing index.
346 * @param index we are listed on.
347 */
348 void delist(OrderedIndex *index);
349
350 /**
351 * Get next ordered member when iterating.
352 * @return next ordered object.
353 */
354 inline OrderedObject *getNext(void) const
355 {return static_cast<OrderedObject *>(LinkedObject::getNext());};
356};
357
358/**
359 * A double-linked Object, used for certain kinds of lists.
360 * @author David Sugar <dyfet@gnutelephony.org>
361 */
362class __EXPORT DLinkedObject : public OrderedObject
363{
364public:
365 friend class ObjectQueue;
366
367 /**
368 * Construct an empty object.
369 */
370 DLinkedObject();
371
372protected:
373 /**
374 * Remove a cross-linked list from itself.
375 */
376 void delist(void);
377
378private:
379 DLinkedObject *Prev;
380};
381
382/**
383 * A linked object base class with members found by name. This class is
384 * used to help form named option lists and other forms of name indexed
385 * associative data structures. The id is assumed to be passed from a
386 * dupped or dynamically allocated string. If a constant string is used
387 * then you must not call delete for this object.
388 *
389 * Named objects are either listed on an ordered list or keyed through an
390 * associate hash map table. When using a hash table, the name id string is
391 * used to determine the slot number to use in a list of n sized linked
392 * object lists. Hence, a hash index refers to a specific sized array of
393 * object indexes.
394 * @author David Sugar <dyfet@gnutelephony.org>
395 */
396class __EXPORT NamedObject : public OrderedObject
397{
398protected:
399 char *Id;
400
401 /**
402 * Create an empty unnamed cell object.
403 */
404 NamedObject();
405
406 /**
407 * Create a named object and add to hash indexed list.
408 * @param hash map table to list node on.
409 * @param name of the object we are listing.
410 * @param size of hash map table used.
411 */
412 NamedObject(NamedObject **hash, char *name, unsigned size = 1);
413
414 /**
415 * Created a named object on an ordered list. This is commonly used
416 * to form attribute lists.
417 * @param index to list object on.
418 * @param name of the object we are listing.
419 */
420 NamedObject(OrderedIndex *index, char *name);
421
422 /**
423 * Destroy named object. We do not always destroy named objects, since
424 * we may use them in reusable pools or we may initialize a list that we
425 * keep permanently. If we do invoke delete for something based on
426 * NamedObject, then be aware the object id is assumed to be formed from
427 * a dup'd string which will also be freed unless clearId is overridden.
428 */
429 ~NamedObject();
430
431 /**
432 * The behavior of clearing id's can be overridden if they are not
433 * assigned as strdup's from the heap...
434 */
435 virtual void clearId(void);
436
437public:
438 /**
439 * Add object to hash indexed list.
440 * @param hash map table to list node on.
441 * @param name of the object we are listing.
442 * @param size of hash map table used.
443 */
444 void add(NamedObject **hash, char *name, unsigned size = 1);
445
446 /**
447 * Purge a hash indexed table of named objects.
448 * @param hash map table to purge.
449 * @param size of hash map table used.
450 */
451 static void purge(NamedObject **hash, unsigned size);
452
453 /**
454 * Convert a hash index into a linear object pointer array. The
455 * object pointer array is created from the heap and must be deleted
456 * when no longer used.
457 * @param hash map table of objects to index.
458 * @param size of hash map table used.
459 * @return array of named object pointers.
460 */
461 static NamedObject **index(NamedObject **hash, unsigned size);
462
463 /**
464 * Count the total named objects in a hash table.
465 * @param hash map table of objects to index.
466 * @param size of hash map table used.
467 */
468 static unsigned count(NamedObject **hash, unsigned size);
469
470 /**
471 * Find a named object from a simple list. This may also use the
472 * begin() member of an ordered index of named objects.
473 * @param root node of named object list.
474 * @param name of object to find.
475 * @return object pointer or NULL if not found.
476 */
477 static NamedObject *find(NamedObject *root, const char *name);
478
479 /**
480 * Remove a named object from a simple list.
481 * @param root node of named object list.
482 * @param name of object to find.
483 * @return object pointer or NULL if not found.
484 */
485 static NamedObject *remove(NamedObject **root, const char *name);
486
487 /**
488 * Find a named object through a hash map table.
489 * @param hash map table of objects to search.
490 * @param name of object to find.
491 * @param size of hash map table.
492 * @return object pointer or NULL if not found.
493 */
494 static NamedObject *map(NamedObject **hash, const char *name, unsigned size);
495
496 /**
497 * Remove an object from a hash map table.
498 * @param hash map table of object to remove from.
499 * @param name of object to remove.
500 * @param size of hash map table.
501 * @return object that is removed or NULL if not found.
502 */
503 static NamedObject *remove(NamedObject **hash, const char *name, unsigned size);
504
505 /**
506 * Iterate through a hash map table.
507 * @param hash map table to iterate.
508 * @param current named object we iterated or NULL to find start of list.
509 * @param size of map table.
510 * @return next named object in hash map or NULL if no more objects.
511 */
512 static NamedObject *skip(NamedObject **hash, NamedObject *current, unsigned size);
513
514 /**
515 * Internal function to convert a name to a hash index number.
516 * @param name to convert into index.
517 * @param size of map table.
518 */
519 static unsigned keyindex(const char *name, unsigned size);
520
521 /**
522 * Sort an array of named objects in alphabetical order. This would
523 * typically be used to sort a list created and returned by index().
524 * @param list of named objects to sort.
525 * @param count of objects in the list or 0 to find by NULL pointer.
526 * @return list in sorted order.
527 */
528 static NamedObject **sort(NamedObject **list, size_t count = 0);
529
530 /**
531 * Get next effective object when iterating.
532 * @return next linked object in list.
533 */
534 inline NamedObject *getNext(void) const
535 {return static_cast<NamedObject*>(LinkedObject::getNext());};
536
537 /**
538 * Get the named id string of this object.
539 * @return name id.
540 */
541 inline char *getId(void) const
542 {return Id;};
543
544 /**
545 * Compare the name of our object to see if equal. This is a virtual
546 * so that it can be overridden when using named lists or hash lookups
547 * that must be case insensitive.
548 * @param name to compare our name to.
549 * @return 0 if effectivily equal, used for sorting keys.
550 */
551 virtual int compare(const char *name) const;
552
553 /**
554 * Equal function which calls compare.
555 * @param name to compare our name to.
556 * @return true if equal.
557 */
558 inline bool equal(const char *name) const
559 {return (compare(name) == 0);};
560
561 /**
562 * Comparison operator between our name and a string.
563 * @param name to compare with.
564 * @return true if equal.
565 */
566 inline bool operator==(const char *name) const
567 {return compare(name) == 0;};
568
569 /**
570 * Comparison operator between our name and a string.
571 * @param name to compare with.
572 * @return true if not equal.
573 */
574 inline bool operator!=(const char *name) const
575 {return compare(name) != 0;};
576};
577
578/**
579 * The named tree class is used to form a tree oriented list of associated
580 * objects. Typical uses for such data structures might be to form a
581 * parsed XML document, or for forming complex configuration management
582 * systems or for forming system resource management trees.
583 * @author David Sugar <dyfet@gnutelephony.org>
584 */
585class __EXPORT NamedTree : public NamedObject
586{
587protected:
588 NamedTree *Parent;
589 OrderedIndex Child;
590
591 /**
592 * Create a stand-alone or root tree node, with an optional name.
593 * @param name for this node.
594 */
595 NamedTree(char *name = NULL);
596
597 /**
598 * Create a tree node as a child of an existing node.
599 * @param parent node we are listed under.
600 * @param name of our node.
601 */
602 NamedTree(NamedTree *parent, char *name);
603
604 /**
605 * Construct a copy of the tree.
606 * @param source object to copy from.
607 */
608 NamedTree(const NamedTree& source);
609
610 /**
611 * Delete node in a tree. If we delete a node, we must delist it from
612 * it's parent. We must also delink any child nodes. This is done by
613 * calling the purge() member.
614 */
615 virtual ~NamedTree();
616
617 /**
618 * Performs object destruction. Note, if we delete a named tree object
619 * the name of our member object is assumed to be a dynamically allocated
620 * string that will also be free'd.
621 */
622 void purge(void);
623
624public:
625 /**
626 * Find a child node of our object with the specified name. This will
627 * also recursivily search all child nodes that have children until
628 * the named node can be found. This seeks a child node that has
629 * children.
630 * @param name to search for.
631 * @return tree object found or NULL.
632 */
633 NamedTree *find(const char *name) const;
634
635 /**
636 * Find a subnode by a dot separated list of node names. If one or
637 * more lead dots are used, then the search will go through parent
638 * node levels of our node. The dot separated list could be thought
639 * of as a kind of pathname where dot is used like slash. This implies
640 * that individual nodes can never use names which contain dot's if
641 * the path function will be used.
642 * @param path name string being sought.
643 * @return tree node object found at the path or NULL.
644 */
645 NamedTree *path(const char *path) const;
646
647 /**
648 * Find a child leaf node of our object with the specified name. This
649 * will recursively search all our child nodes until it can find a leaf
650 * node containing the specified id but that holds no further children.
651 * @param name of leaf node to search for.
652 * @return tree node object found or NULL.
653 */
654 NamedTree *leaf(const char *name) const;
655
656 /**
657 * Find a direct child of our node which matches the specified name.
658 * @param name of child node to find.
659 * @return tree node object of child or NULL.
660 */
661 NamedTree *getChild(const char *name) const;
662
663 /**
664 * Find a direct leaf node on our node. A leaf node is a node that has
665 * no children of it's own. This does not perform a recursive search.
666 * @param name of leaf child node to find.
667 * @return tree node object of leaf or NULL.
668 */
669 NamedTree *getLeaf(const char *name) const;
670
671 /**
672 * Get first child node in our ordered list of children. This might
673 * be used to iterate child nodes. This may also be used to get
674 * unamed child nodes.
675 * @return first child node or NULL if no children.
676 */
677 inline NamedTree *getFirst(void) const
678 {return static_cast<NamedTree *>(Child.begin());};
679
680 /**
681 * Get parent node we are listed as a child on.
682 * @return parent node or NULL if none.
683 */
684 inline NamedTree *getParent(void) const
685 {return Parent;};
686
687 /**
688 * Get child by index number.
689 * @param index of child to fetch.
690 * @return indexed child node.
691 */
692 inline NamedTree *getIndexed(unsigned index) const
693 {return static_cast<NamedTree *>(Child.getIndexed(index));};
694
695 /**
696 * Get the ordered index of our child nodes.
697 * @return ordered index of our children.
698 */
699 inline OrderedIndex *getIndex(void) const
700 {return const_cast<OrderedIndex*>(&Child);};
701
702 /**
703 * Test if this node has a name.
704 * @return true if name is set.
705 */
706 inline operator bool() const
707 {return (Id != NULL);};
708
709 /**
710 * Test if this node is unnamed.
711 * @return false if name is set.
712 */
713 inline bool operator!() const
714 {return (Id == NULL);};
715
716 /**
717 * Set or replace the name id of this node. This will free the string
718 * if a name had already been set.
719 * @param name for this node to set.
720 */
721 void setId(char *name);
722
723 /**
724 * Remove our node from our parent list. The name is set to NULL to
725 * keep delete from freeing the name string.
726 */
727 void remove(void);
728
729 /**
730 * Test if node has children.
731 * @return true if node contains child nodes.
732 */
733 inline bool is_leaf(void) const
734 {return (Child.begin() == NULL);};
735
736 /**
737 * Test if node is root node.
738 * @return true if node is root node.
739 */
740 inline bool is_root(void) const
741 {return (Parent == NULL);};
742
743 /**
744 * Add leaf to a trunk, by order. If NULL, just remove.
745 * @param trunk we add leaf node to.
746 */
747 void relistTail(NamedTree *trunk);
748
749 /**
750 * Add leaf to a trunk, by reverse order. If NULL, just remove.
751 * @param trunk we add leaf node to.
752 */
753 void relistHead(NamedTree *trunk);
754
755 /**
756 * Default relist is by tail...
757 * @param trunk we add leaf node to, NULL to delist.
758 */
759 inline void relist(NamedTree *trunk = NULL)
760 {relistTail(trunk);};
761};
762
763/**
764 * A double linked list object. This is used as a base class for objects
765 * that will be organized through ordered double linked lists which allow
766 * convenient insertion and deletion of list members anywhere in the list.
767 * @author David Sugar <dyfet@gnutelephony.org>
768 */
769class __EXPORT LinkedList : public OrderedObject
770{
771protected:
772 friend class ObjectQueue;
773
774 LinkedList *Prev;
775 OrderedIndex *Root;
776
777 /**
778 * Construct and add our object to an existing double linked list at end.
779 * @param index of linked list we are listed in.
780 */
781 LinkedList(OrderedIndex *index);
782
783 /**
784 * Construct an unlinked object.
785 */
786 LinkedList();
787
788 /**
789 * Delete linked list object. If it is a member of a list of objects,
790 * then the list is reformed around us.
791 */
792 virtual ~LinkedList();
793
794public:
795 /**
796 * Remove our object from the list it is currently part of.
797 */
798 void delist(void);
799
800 /**
801 * Attach our object to the start of a linked list though an ordered index.
802 * If we are already attached to a list we are delisted first.
803 * @param index of linked list we are joining.
804 */
805 void enlistHead(OrderedIndex *index);
806
807 /**
808 * Attach our object to the end of a linked list though an ordered index.
809 * If we are already attached to a list we are delisted first.
810 * @param index of linked list we are joining.
811 */
812 void enlistTail(OrderedIndex *index);
813
814 /**
815 * Attach our object to a linked list. The default strategy is to add
816 * to tail.
817 * @param index of linked list we are joining.
818 */
819 void enlist(OrderedIndex *index);
820
821 /**
822 * Test if we are at the head of a list.
823 * @return true if we are the first node in a list.
824 */
825 inline bool is_head(void) const
826 {return Root->head == (OrderedObject *)this;};
827
828 /**
829 * Test if we are at the end of a list.
830 * @return true if we are the last node in a list.
831 */
832 inline bool is_tail(void) const
833 {return Root->tail == (OrderedObject *)this;};
834
835 /**
836 * Get previous node in the list for reverse iteration.
837 * @return previous node in list.
838 */
839 inline LinkedList *getPrev(void) const
840 {return Prev;};
841
842 /**
843 * Get next node in the list when iterating.
844 * @return next node in list.
845 */
846 inline LinkedList *getNext(void) const
847 {return static_cast<LinkedList*>(LinkedObject::getNext());};
848
849 /**
850 * Insert object behind our object.
851 * @param object to add to list.
852 */
853 void insertTail(LinkedList *object);
854
855 /**
856 * Insert object in front of our object.
857 * @param object to add to list.
858 */
859 void insertHead(LinkedList *object);
860
861 /**
862 * Insert object, method in derived object.
863 * @param object to add to list.
864 */
865 virtual void insert(LinkedList *object);
866
867 /**
868 * Insert object behind our object.
869 * @param object to add to list.
870 */
871 inline void operator+=(LinkedList *object)
872 {insertTail(object);};
873
874 /**
875 * Insert object in front of our object.
876 * @param object to add to list.
877 */
878 inline void operator-=(LinkedList *object)
879 {insertHead(object);};
880
881 /**
882 * Insert object in list with our object.
883 * @param object to add to list.
884 */
885 inline void operator*=(LinkedList *object)
886 {insert(object);};
887};
888
889/**
890 * A queue of double linked object. This uses the linkedlist class to
891 * form a basic queue of objects.
892 * @author David Sugar <dyfet@gnutelephony.org>
893 */
894class __EXPORT ObjectQueue : public OrderedIndex
895{
896public:
897 /**
898 * Create an empty object queue.
899 */
900 ObjectQueue();
901
902 /**
903 * Add an object to the end of the queue.
904 * @param object to add.
905 */
906 void add(DLinkedObject *object);
907
908 /**
909 * Push an object to the front of the queue.
910 * @param object to push.
911 */
912 void push(DLinkedObject *object);
913
914 /**
915 * Pull an object from the front of the queue.
916 * @return object pulled or NULL if empty.
917 */
918 DLinkedObject *pull(void);
919
920 /**
921 * Pop an object from the end of the queue.
922 * @return object popped or NULL if empty.
923 */
924 DLinkedObject *pop(void);
925};
926
927class __EXPORT ObjectStack
928{
929protected:
930 LinkedObject *root;
931
932public:
933 /**
934 * Create an empty stack.
935 */
936 ObjectStack();
937
938 /**
939 * Create a stack from an existing list of objects.
940 * @param list of already linked objects.
941 */
942 ObjectStack(LinkedObject *list);
943
944 /**
945 * Push an object onto the stack.
946 * @param object to push.
947 */
948 void push(LinkedObject *object);
949
950 /**
951 * Pull an object from the stack.
952 * @return object popped from stack or NULL if empty.
953 */
954 LinkedObject *pull(void);
955
956 /**
957 * Pop an object from the stack.
958 * @return object popped from stack or NULL if empty.
959 */
960 inline LinkedObject *pop(void)
961 {return ObjectStack::pull();};
962};
963
964
965/**
966 * A multipath linked list where membership is managed in multiple
967 * lists.
968 * @author David Sugar <dyfet@gnutelephony.org>
969 */
970class __EXPORT MultiMap : public ReusableObject
971{
972private:
973 typedef struct {
974 const char *key;
975 size_t keysize;
976 MultiMap *next;
977 MultiMap **root;
978 } link_t;
979
980 unsigned paths;
981 link_t *links;
982
983protected:
984 /**
985 * Initialize a multilist object.
986 * @param count of link paths.
987 */
988 MultiMap(unsigned count);
989
990 /**
991 * Destroy a multilist object.
992 */
993 virtual ~MultiMap();
994
995 /**
996 * Modifiable interface for key matching.
997 * @param path to check.
998 * @param key to check.
999 * @param size of key to check or 0 if NULL terminated string.
1000 * @return true if matches key.
1001 */
1002 virtual bool equal(unsigned path, caddr_t key, size_t size) const;
1003
1004public:
1005 /**
1006 * Enlist on a single linked list.
1007 * @param path to attach through.
1008 * @param root of list to attach.
1009 */
1010 void enlist(unsigned path, MultiMap **root);
1011
1012 /**
1013 * Enlist binary key on a single map path.
1014 * @param path to attach through.
1015 * @param index to attach to.
1016 * @param key value to use.
1017 * @param size of index.
1018 * @param keysize of key or 0 if NULL terminated string.
1019 */
1020 void enlist(unsigned path, MultiMap **index, caddr_t key, unsigned size, size_t keysize = 0);
1021
1022 /**
1023 * De-list from a single map path.
1024 * @param path to detach from.
1025 */
1026 void delist(unsigned path);
1027
1028 /**
1029 * Get next node from single chain.
1030 * @param path to follow.
1031 */
1032 MultiMap *next(unsigned path) const;
1033
1034 /**
1035 * Compute binary key index.
1036 * @param key memory to compute.
1037 * @param max size of index.
1038 * @param size of key or 0 if NULL terminated string.
1039 * @return associated hash value.
1040 */
1041 static unsigned keyindex(caddr_t key, unsigned max, size_t size = 0);
1042
1043 /**
1044 * Find a multikey node.
1045 * @return node that is found or NULL if none.
1046 * @param path of table.
1047 * @param index of hash table.
1048 * @param key to locate.
1049 * @param max size of index.
1050 * @param size of key or 0 if NULL terminated string.
1051 */
1052 static MultiMap *find(unsigned path, MultiMap **index, caddr_t key, unsigned max, size_t size = 0);
1053};
1054
1055/**
1056 * Template value class to embed data structure into a named list.
1057 * This is used to form a class which can be searched by name and that
1058 * contains a member value object. Most of the core logic for this
1059 * template is found in and derived from the object_value template.
1060 * @author David Sugar <dyfet@gnutelephony.org>
1061 */
1062template <typename T, class O=NamedObject>
1063class named_value : public object_value<T, O>
1064{
1065public:
1066 /**
1067 * Construct embedded named object on a linked list.
1068 * @param root node or pointer for list.
1069 * @param name of our object.
1070 */
1071 inline named_value(LinkedObject **root, char *name)
1072 {LinkedObject::enlist(root); O::id = name;};
1073
1074 /**
1075 * Assign embedded value from related type.
1076 * @param typed_value to assign.
1077 */
1078 inline void operator=(const T& typed_value)
1079 {this->set(typed_value);};
1080
1081 /**
1082 * Find embedded object in chain by name.
1083 * @param first object in list to search from.
1084 * @param name to search for.
1085 * @return composite object found by name or NULL if not found.
1086 */
1087 inline static named_value find(named_value *first, const char *name)
1088 {return static_cast<named_value *>(NamedObject::find(first, name));};
1089};
1090
1091/**
1092 * Template value class to embed data structure into a linked list.
1093 * This is used to form a class which can be linked together using
1094 * either an ordered index or simple linked pointer chain and that
1095 * contains a member value object. Most of the core logic for this
1096 * template is found in and derived from the object_value template.
1097 * @author David Sugar <dyfet@gnutelephony.org>
1098 */
1099template <typename T, class O=OrderedObject>
1100class linked_value : public object_value<T, O>
1101{
1102public:
1103 /**
1104 * Create embedded value object unlinked.
1105 */
1106 inline linked_value() {};
1107
1108 /**
1109 * Construct embedded object on a linked list.
1110 * @param root node or pointer for list.
1111 */
1112 inline linked_value(LinkedObject **root)
1113 {LinkedObject::enlist(root);};
1114
1115 /**
1116 * Construct embedded object on an ordered list.
1117 * @param index pointer for the ordered list.
1118 */
1119 inline linked_value(OrderedIndex *index)
1120 {O::enlist(index);};
1121
1122 /**
1123 * Assign embedded value from related type and link to list.
1124 * @param root node or pointer for list.
1125 * @param typed_value to assign.
1126 */
1127 inline linked_value(LinkedObject **root, const T& typed_value)
1128 {LinkedObject::enlist(root); this->set(typed_value);};
1129
1130 /**
1131 * Assign embedded value from related type and add to list.
1132 * @param index to list our object on.
1133 * @param typed_value to assign.
1134 */
1135 inline linked_value(OrderedIndex *index, const T& typed_value)
1136 {O::enlist(index); this->set(typed_value);};
1137
1138 /**
1139 * Assign embedded value from related type.
1140 * @param typed_value to assign.
1141 */
1142 inline void operator=(const T& typed_value)
1143 {this->set(typed_value);};
1144};
1145
1146/**
1147 * Template for typesafe basic object stack container. The object type, T,
1148 * that is contained in the stack must be derived from LinkedObject.
1149 * @author David Sugar <dyfet@gnutelephony.org>
1150 */
1151template <class T>
1152class objstack : public ObjectStack
1153{
1154public:
1155 /**
1156 * Create a new object stack.
1157 */
1158 inline objstack() : ObjectStack() {}
1159
1160 /**
1161 * Create an object stack from a list of objects.
1162 */
1163 inline objstack(T *list) : ObjectStack(list) {}
1164
1165 /**
1166 * Push an object onto the object stack.
1167 * @param object of specified type to push.
1168 */
1169 inline void push(T *object)
1170 {ObjectStack::push(object);}
1171
1172 /**
1173 * Add an object onto the object stack.
1174 * @param object of specified type to push.
1175 */
1176 inline void add(T *object)
1177 {ObjectStack::push(object);}
1178
1179 /**
1180 * Pull an object from the object stack.
1181 * @return object of specified type or NULL if empty.
1182 */
1183 inline T *pull(void)
1184 {return (T *)ObjectStack::pull();}
1185
1186 /**
1187 * Pull (pop) an object from the object stack.
1188 * @return object of specified type or NULL if empty.
1189 */
1190 inline T *pop(void)
1191 {return (T *)ObjectStack::pull();}
1192};
1193
1194/**
1195 * Template for typesafe basic object fifo container. The object type, T,
1196 * that is contained in the fifo must be derived from OrderedObject or
1197 * LinkedObject.
1198 * @author David Sugar <dyfet@gnutelephony.org>
1199 */
1200template <class T>
1201class objfifo : public OrderedIndex
1202{
1203public:
1204 /**
1205 * Create a new object stack.
1206 */
1207 inline objfifo() : OrderedIndex() {}
1208
1209 /**
1210 * Push an object onto the object fifo.
1211 * @param object of specified type to push.
1212 */
1213 inline void push(T *object)
1214 {OrderedIndex::add((OrderedObject *)object);}
1215
1216 /**
1217 * Add an object onto the object fifo.
1218 * @param object of specified type to push.
1219 */
1220 inline void add(T *object)
1221 {OrderedIndex::add((OrderedObject *)object);}
1222
1223 /**
1224 * Pull an object from the object stack.
1225 * @return object of specified type or NULL if empty.
1226 */
1227 inline T *pull(void)
1228 {return (T *)OrderedIndex::get();}
1229
1230 /**
1231 * Pull (pop) an object from the object stack.
1232 * @return object of specified type or NULL if empty.
1233 */
1234 inline T *pop(void)
1235 {return (T *)OrderedIndex::get();}
1236};
1237
1238/**
1239 * Template for typesafe basic object queue container. The object type, T,
1240 * that is contained in the fifo must be derived from DLinkedObject.
1241 * @author David Sugar <dyfet@gnutelephony.org>
1242 */
1243template <class T>
1244class objqueue : public ObjectQueue
1245{
1246public:
1247 /**
1248 * Create a new object stack.
1249 */
1250 inline objqueue() : ObjectQueue() {}
1251
1252 /**
1253 * Push an object to start of queue.
1254 * @param object of specified type to push.
1255 */
1256 inline void push(T *object)
1257 {ObjectQueue::push((DLinkedObject *)object);}
1258
1259 /**
1260 * Add an object to the end of the object queue.
1261 * @param object of specified type to add.
1262 */
1263 inline void add(T *object)
1264 {ObjectQueue::add((DLinkedObject *)object);}
1265
1266 /**
1267 * Pull an object from the start of the object queue.
1268 * @return object of specified type or NULL if empty.
1269 */
1270 inline T *pull(void)
1271 {return (T *)ObjectQueue::pull();}
1272
1273 /**
1274 * Pop an object from the end of the object queue.
1275 * @return object of specified type or NULL if empty.
1276 */
1277 inline T *pop(void)
1278 {return (T *)ObjectQueue::pop();}
1279};
1280
1281/**
1282 * A smart pointer template for iterating linked lists. This class allows
1283 * one to access a list of single or double linked objects and iterate
1284 * through each member of a list.
1285 * @author David Sugar <dyfet@gnutelephony.org>
1286 */
1287template <class T>
1288class linked_pointer
1289{
1290private:
1291 T *ptr;
1292
1293public:
1294 /**
1295 * Create a linked pointer and assign to start of a list.
1296 * @param pointer to first member of a linked list.
1297 */
1298 inline linked_pointer(T *pointer)
1299 {ptr = pointer;};
1300
1301 /**
1302 * Create a copy of an existing linked pointer.
1303 * @param pointer to copy from.
1304 */
1305 inline linked_pointer(const linked_pointer &pointer)
1306 {ptr = pointer.ptr;};
1307
1308 /**
1309 * Create a linked pointer assigned from a raw linked object pointer.
1310 * @param pointer to linked object.
1311 */
1312 inline linked_pointer(LinkedObject *pointer)
1313 {ptr = static_cast<T*>(pointer);};
1314
1315 inline linked_pointer(const LinkedObject *pointer)
1316 {ptr = static_cast<T*>(pointer);};
1317
1318 /**
1319 * Create a linked pointer to examine an ordered index.
1320 * @param index of linked objects to iterate through.
1321 */
1322 inline linked_pointer(OrderedIndex *index)
1323 {ptr = static_cast<T*>(index->begin());};
1324
1325 /**
1326 * Create a linked pointer not attached to a list.
1327 */
1328 inline linked_pointer()
1329 {ptr = NULL;};
1330
1331 /**
1332 * Assign our typed iterative pointer from a matching typed object.
1333 * @param pointer to typed object.
1334 */
1335 inline void operator=(T *pointer)
1336 {ptr = pointer;};
1337
1338 /**
1339 * Assign our pointer from another pointer.
1340 * @param pointer to assign from.
1341 */
1342 inline void operator=(linked_pointer &pointer)
1343 {ptr = pointer.ptr;};
1344
1345 /**
1346 * Assign our pointer from the start of an ordered index.
1347 * @param index to assign pointer from.
1348 */
1349 inline void operator=(OrderedIndex *index)
1350 {ptr = static_cast<T*>(index->begin());};
1351
1352 /**
1353 * Assign our pointer from a generic linked object pointer.
1354 * @param pointer of linked list.
1355 */
1356 inline void operator=(LinkedObject *pointer)
1357 {ptr = static_cast<T*>(pointer);};
1358
1359 /**
1360 * Return member from typed object our pointer references.
1361 * @return evaluated member of object we point to.
1362 */
1363 inline T* operator->() const
1364 {return ptr;};
1365
1366 /**
1367 * Return object we currently point to.
1368 * @return object linked pointer references.
1369 */
1370 inline T* operator*() const
1371 {return ptr;};
1372
1373 /**
1374 * Return object we point to by casting.
1375 * @return object linked pointer references.
1376 */
1377 inline operator T*() const
1378 {return ptr;};
1379
1380 /**
1381 * Move (iterate) pointer to previous member in double linked list.
1382 */
1383 inline void prev(void)
1384 {ptr = static_cast<T*>(ptr->getPrev());};
1385
1386 /**
1387 * Move (iterate) pointer to next member in linked list.
1388 */
1389 inline void next(void)
1390 {ptr = static_cast<T*>(ptr->getNext());};
1391
1392 /**
1393 * Get the next member in linked list. Do not change who we point to.
1394 * @return next member in list or NULL if end of list.
1395 */
1396 inline T *getNext(void) const
1397 {return static_cast<T*>(ptr->getNext());};
1398
1399 /**
1400 * Get the previous member in double linked list. Do not change who we
1401 * point to.
1402 * @return previous member in list or NULL if start of list.
1403 */
1404 inline T *getPrev(void) const
1405 {return static_cast<T*>(ptr->getPrev());};
1406
1407 /**
1408 * Move (iterate) pointer to next member in linked list.
1409 */
1410 inline void operator++()
1411 {ptr = static_cast<T*>(ptr->getNext());};
1412
1413 /**
1414 * Move (iterate) pointer to previous member in double linked list.
1415 */
1416 inline void operator--()
1417 {ptr = static_cast<T*>(ptr->getPrev());};
1418
1419 /**
1420 * Test for next member in linked list.
1421 * @return true if there is more members after current one.
1422 */
1423 inline bool is_next(void) const
1424 {return (ptr->getNext() != NULL);};
1425
1426 /**
1427 * Test for previous member in double linked list.
1428 * @return true if there is more members before current one.
1429 */
1430 inline bool is_prev(void) const
1431 {return (ptr->getPrev() != NULL);};
1432
1433 /**
1434 * Test if linked pointer is set/we are not at end of list.
1435 * @return true if we are not at end of list.
1436 */
1437 inline operator bool() const
1438 {return (ptr != NULL);};
1439
1440 /**
1441 * Test if linked list is empty/we are at end of list.
1442 * @return true if we are at end of list.
1443 */
1444 inline bool operator!() const
1445 {return (ptr == NULL);};
1446
1447 /**
1448 * Return pointer to our linked pointer to use as root node of a chain.
1449 * @return our object pointer as a root index.
1450 */
1451 inline LinkedObject **root(void) const
1452 {T **r = &ptr; return (LinkedObject**)r;};
1453};
1454
1455/**
1456 * Embed data objects into a multipap structured memory database. This
1457 * can be used to form multi-key hash nodes. Embedded values can either be
1458 * of direct types that are then stored as part of the template object, or
1459 * of class types that are data pointers.
1460 * @author David Sugar <dyfet@gnutelephony.org>
1461 */
1462template <typename T, unsigned P>
1463class multimap : public MultiMap
1464{
1465protected:
1466 T value;
1467
1468public:
1469 /**
1470 * Construct a multimap node.
1471 */
1472 inline multimap() : MultiMap(P) {};
1473
1474 /**
1475 * Destroy a multimap object.
1476 */
1477 inline ~multimap() {};
1478
1479 /**
1480 * Return the typed value of this node.
1481 * @return reference to value of node.
1482 */
1483 inline T &get(void) const
1484 {return value;};
1485
1486 /**
1487 * Return next multimap typed object.
1488 * @param path to follow.
1489 * @return multimap typed.
1490 */
1491 inline multimap *next(unsigned path)
1492 {return static_cast<multimap*>(MultiMap::next(path));};
1493
1494 /**
1495 * Return typed value of this node by pointer reference.
1496 * @return value of node.
1497 */
1498 inline T& operator*() const
1499 {return value;};
1500
1501 /**
1502 * Set the pointer of a pointer based value tree.
1503 * @param pointer to set.
1504 */
1505 inline void setPointer(const T pointer)
1506 {value = pointer;};
1507
1508 /**
1509 * Set the value of a data based value tree.
1510 * @param reference to value to copy into node.
1511 */
1512 inline void set(const T &reference)
1513 {value = reference;};
1514
1515 /**
1516 * Assign the value of our node.
1517 * @param data value to assign.
1518 */
1519 inline void operator=(const T& data)
1520 {value = data;};
1521
1522 /**
1523 * Find multimap key entry.
1524 * @param path to search through.
1525 * @param index of associated keys.
1526 * @param key to search for, binary or NULL terminated string.
1527 * @param size of index used.
1528 * @param keysize or 0 if NULL terminated string.
1529 * @return multipath typed object.
1530 */
1531 inline static multimap *find(unsigned path, MultiMap **index, caddr_t key, unsigned size, unsigned keysize = 0)
1532 {return static_cast<multimap*>(MultiMap::find(path, index, key, size, keysize));};
1533};
1534
1535/**
1536 * Embed data objects into a tree structured memory database. This can
1537 * be used to form XML document trees or other data structures that
1538 * can be organized in trees. The NamedTree class is used to manage
1539 * the structure of the tree, and the type specified is embedded as a
1540 * data value object which can be manipulated. Name identifiers are
1541 * assumed to be dynamically allocated if tree node elements are deletable.
1542 *
1543 * Embedded values can either be of direct types that are then stored as
1544 * part of the template object, or of class types that are data pointers.
1545 * The latter might be used for trees that contain data which might be
1546 * parsed dynamically from a document and/or saved on a heap. Pointer trees
1547 * assume that NULL pointers are for nodes that are empty, and that NULL data
1548 * value nodes with children are trunk nodes. Generally data values are then
1549 * allocated with a pointer stored in pure leaf nodes.
1550 * @author David Sugar <dyfet@gnutelephony.org>
1551 */
1552template <typename T>
1553class treemap : public NamedTree
1554{
1555protected:
1556 T value;
1557
1558public:
1559 /**
1560 * Construct a typed root node for the tree. The root node may be
1561 * named as a stand-alone node or unnamed.
1562 * @param name of the node we are creating.
1563 */
1564 inline treemap(char *name = NULL) : NamedTree(name) {};
1565
1566 /**
1567 * Construct a copy of the treemap object.
1568 * @param source of copy for new object.
1569 */
1570 inline treemap(const treemap& source) : NamedTree(source)
1571 {value = source.value;};
1572
1573 /**
1574 * Construct a child node on an existing tree.
1575 * @param parent of this node to attach.
1576 * @param name of this node.
1577 */
1578 inline treemap(treemap *parent, char *name) : NamedTree(parent, name) {};
1579
1580 /**
1581 * Construct a child node on an existing tree and assign it's value.
1582 * @param parent of this node to attach.
1583 * @param name of this node.
1584 * @param reference to value to assign to this node.
1585 */
1586 inline treemap(treemap *parent, char *name, T& reference) :
1587 NamedTree(parent, name) {value = reference;};
1588
1589 /**
1590 * Return the typed value of this node.
1591 * @return reference to value of node.
1592 */
1593 inline const T& get(void) const
1594 {return value;};
1595
1596 /**
1597 * Return typed value of this node by pointer reference.
1598 * @return value of node.
1599 */
1600 inline const T& operator*() const
1601 {return value;};
1602
1603 /**
1604 * Return value from tree element when value is a pointer.
1605 * @param node in our typed tree.
1606 * @return value of node.
1607 */
1608 static inline T getPointer(treemap *node)
1609 {return (node == NULL) ? NULL : node->value;};
1610
1611 /**
1612 * Test if this node is a leaf node for a tree pointer table.
1613 * @return true if value pointer is not NULL and there are no children.
1614 */
1615 inline bool is_attribute(void) const
1616 {return (!Child.begin() && value != NULL);};
1617
1618 /**
1619 * Get the pointer of a pointer based value tree.
1620 * @return value pointer of node.
1621 */
1622 inline const T getPointer(void) const
1623 {return value;};
1624
1625 /**
1626 * Get the data value of a data based value tree.
1627 * @return data value of node.
1628 */
1629 inline const T& getData(void) const
1630 {return value;};
1631
1632 /**
1633 * Set the pointer of a pointer based value tree.
1634 * @param pointer to set.
1635 */
1636 inline void setPointer(const T pointer)
1637 {value = pointer;};
1638
1639 /**
1640 * Set the value of a data based value tree.
1641 * @param reference to value to copy into node.
1642 */
1643 inline void set(const T& reference)
1644 {value = reference;};
1645
1646 /**
1647 * Assign the value of our node.
1648 * @param data value to assign.
1649 */
1650 inline void operator=(const T& data)
1651 {value = data;};
1652
1653 /**
1654 * Get child member node by index.
1655 * @param index of child member.
1656 * @return node or NULL if past end.
1657 */
1658 inline treemap *getIndexed(unsigned index) const
1659 {return static_cast<treemap*>(Child.getIndexed(index));};
1660
1661 /**
1662 * Get the typed parent node for our node.
1663 * @return parent node or NULL if root of tree.
1664 */
1665 inline treemap *getParent(void) const
1666 {return static_cast<treemap*>(Parent);};
1667
1668 /**
1669 * Get direct typed child node of our node of specified name. This
1670 * does not perform a recursive search.
1671 * @param name of child node.
1672 * @return typed child node pointer or NULL if not found.
1673 */
1674 inline treemap *getChild(const char *name) const
1675 {return static_cast<treemap*>(NamedTree::getChild(name));};
1676
1677 /**
1678 * Find a direct typed leaf node on our node. A leaf node is a node that
1679 * has no children of it's own. This does not perform a recursive search.
1680 * @param name of leaf child node to find.
1681 * @return typed leaf node object of leaf or NULL.
1682 */
1683 inline treemap *getLeaf(const char *name) const
1684 {return static_cast<treemap*>(NamedTree::getLeaf(name));};
1685
1686 /**
1687 * Get the value pointer of a leaf node of a pointer tree. This allows
1688 * one to find a leaf node and return it's pointer value in a single
1689 * operation.
1690 * @param name of leaf node.
1691 * @return value of leaf pointer if found and contains value, or NULL.
1692 */
1693 inline T getValue(const char *name) const
1694 {return getPointer(getLeaf(name));};
1695
1696 /**
1697 * Find a subnode from our node by name. This performs a recursive
1698 * search.
1699 * @param name to search for.
1700 * @return typed node that is found or NULL if none is found.
1701 */
1702 inline treemap *find(const char *name) const
1703 {return static_cast<treemap*>(NamedTree::find(name));};
1704
1705 /**
1706 * Find a subnode by pathname. This is the same as the NamedTree
1707 * path member function.
1708 * @param path name to search for node.
1709 * @return typed node that is found at path or NULL.
1710 */
1711 inline treemap *path(const char *path) const
1712 {return static_cast<treemap*>(NamedTree::path(path));};
1713
1714 /**
1715 * Search for a leaf node of our node. This performs a recursive
1716 * search.
1717 * @param name to search for.
1718 * @return typed not that is found or NULL if none is found.
1719 */
1720 inline treemap *leaf(const char *name) const
1721 {return static_cast<treemap*>(NamedTree::leaf(name));};
1722
1723 /**
1724 * Get first child of our node. This is useful for iterating children.
1725 * @return first child or NULL.
1726 */
1727 inline treemap *getFirst(void) const
1728 {return static_cast<treemap*>(NamedTree::getFirst());};
1729};
1730
1731/**
1732 * A template class for a hash map. This provides a has map index object as
1733 * a chain of keyindex selected linked pointers of a specified size. This
1734 * is used for the index and size values for NamedObject's which are listed
1735 * on a hash map.
1736 * @author David Sugar <dyfet@gnutelephony.org>
1737 */
1738template <class T, unsigned M = 177>
1739class keymap
1740{
1741private:
1742 NamedObject *idx[M];
1743
1744public:
1745 /**
1746 * Destroy the hash map by puring the index chains.
1747 */
1748 inline ~keymap()
1749 {NamedObject::purge(idx, M);};
1750
1751 /**
1752 * Retrieve root of index to use in NamedObject constructors.
1753 * @return root node of index.
1754 */
1755 inline NamedObject **root(void) const
1756 {return idx;};
1757
1758 /**
1759 * Retrieve key size to use in NamedObject constructors.
1760 * @return key size of hash map.
1761 */
1762 inline unsigned limit(void) const
1763 {return M;};
1764
1765 /**
1766 * Find a typed object derived from NamedObject in the hash map by name.
1767 * @param name to search for.
1768 * @return typed object if found through map or NULL.
1769 */
1770 inline T *get(const char *name) const
1771 {return static_cast<T*>(NamedObject::map(idx, name, M));};
1772
1773 /**
1774 * Find a typed object derived from NamedObject in the hash map by name.
1775 * @param name to search for.
1776 * @return typed object if found through map or NULL.
1777 */
1778 inline T& operator[](const char *name) const
1779 {return static_cast<T*>(NamedObject::map(idx, name, M));};
1780
1781 /**
1782 * Add a typed object derived from NamedObject to the hash map by name.
1783 * @param name to add.
1784 * @param object to add.
1785 */
1786 inline void add(const char *name, T& object)
1787 {object.NamedObject::add(idx, name, M);};
1788
1789 /**
1790 * Add a typed object derived from NamedObject to the hash map by name.
1791 * @param name to add.
1792 * @param object to add.
1793 */
1794 inline void add(const char *name, T *object)
1795 {object->NamedObject::add(idx, name, M);};
1796
1797 /**
1798 * Remove a typed object derived from NamedObject to the hash map by name.
1799 * @param name to remove.
1800 * @return object removed if found or NULL.
1801 */
1802 inline T *remove(const char *name)
1803 {return static_cast<T*>(NamedObject::remove(idx, name, M));};
1804
1805 /**
1806 * Find first typed object in hash map to iterate.
1807 * @return first typed object or NULL if nothing in list.
1808 */
1809 inline T *begin(void) const
1810 {return static_cast<T*>(NamedObject::skip(idx, NULL, M));};
1811
1812 /**
1813 * Find next typed object in hash map for iteration.
1814 * @param current typed object we are referencing.
1815 * @return next iterative object or NULL if past end of map.
1816 */
1817 inline T *next(T *current) const
1818 {return static_cast<T*>(NamedObject::skip(idx, current, M));};
1819
1820 /**
1821 * Count the number of typed objects in our hash map.
1822 * @return count of typed objects.
1823 */
1824 inline unsigned count(void) const
1825 {return NamedObject::count(idx, M);};
1826
1827 /**
1828 * Convert our hash map into a linear object pointer array. The
1829 * object pointer array is created from the heap and must be deleted
1830 * when no longer used.
1831 * @return array of typed named object pointers.
1832 */
1833 inline T **index(void) const
1834 {return NamedObject::index(idx, M);};
1835
1836 /**
1837 * Convert our hash map into an alphabetically sorted linear object
1838 * pointer array. The object pointer array is created from the heap
1839 * and must be deleted when no longer used.
1840 * @return sorted array of typed named object pointers.
1841 */
1842 inline T **sort(void) const
1843 {return NamedObject::sort(NamedObject::index(idx, M));};
1844
1845 /**
1846 * Convenience typedef for iterative pointer.
1847 */
1848 typedef linked_pointer<T> iterator;
1849};
1850
1851/**
1852 * A template for ordered index of typed name key mapped objects.
1853 * This is used to hold an iterable linked list of typed named objects
1854 * where we can find objects by their name as well as through iteration.
1855 * @author David Sugar <dyfet@gnutelephony.org>
1856 */
1857template <class T>
1858class keylist : public OrderedIndex
1859{
1860public:
1861 /**
1862 * Return a root node pointer to use in NamedObject constructors.
1863 * @return pointer to index root.
1864 */
1865 inline NamedObject **root(void)
1866 {return static_cast<NamedObject**>(&head);};
1867
1868 /**
1869 * Return first item in ordered list. This is commonly used to
1870 * iterate the list.
1871 * @return first item in list or NULL if empty.
1872 */
1873 inline T *begin(void)
1874 {return static_cast<T*>(head);};
1875
1876 /**
1877 * Return last item in ordered list. This is commonly used to determine
1878 * end of list iteration.
1879 * @return last item in list or NULL if empty.
1880 */
1881 inline T *end(void)
1882 {return static_cast<T*>(tail);};
1883
1884 /**
1885 * Create a new typed named object with default constructor.
1886 * This creates a new object which can be deleted.
1887 * @param name of object to create.
1888 * @return typed named object.
1889 */
1890 inline T *create(const char *name)
1891 {return new T(this, name);};
1892
1893 /**
1894 * Iterate next object in list.
1895 * @param current object we are referencing.
1896 * @return next logical object in linked list or NULL if end.
1897 */
1898 inline T *next(LinkedObject *current)
1899 {return static_cast<T*>(current->getNext());};
1900
1901 /**
1902 * Find a specific object by name.
1903 * @param name to search for.
1904 * @return type named object that matches or NULL if not found.
1905 */
1906 inline T *find(const char *name)
1907 {return static_cast<T*>(NamedObject::find(begin(), name));};
1908
1909 inline T *offset(unsigned offset)
1910 {return static_cast<T*>(OrderedIndex::find(offset));};
1911
1912 /**
1913 * Retrieve a specific object by position in list.
1914 * @param offset in list for object we want.
1915 * @return type named object or NULL if past end of list.
1916 */
1917 inline T& operator[](unsigned offset)
1918 {return static_cast<T&>(OrderedIndex::find(offset));};
1919
1920 inline T& operator[](const char *name)
1921 {return static_cast<T&>(NamedObject::find(begin(), name));};
1922
1923 /**
1924 * Convert our linked list into a linear object pointer array. The
1925 * object pointer array is created from the heap and must be deleted
1926 * when no longer used.
1927 * @return array of typed named object pointers.
1928 */
1929 inline T **index(void)
1930 {return static_cast<T**>(OrderedIndex::index());};
1931
1932 /**
1933 * Convert our linked list into an alphabetically sorted linear object
1934 * pointer array. The object pointer array is created from the heap
1935 * and must be deleted when no longer used.
1936 * @return array of typed named object pointers.
1937 */
1938 inline T **sort(void)
1939 {return static_cast<T**>(NamedObject::sort(index()));};
1940
1941 /**
1942 * Convenience typedef for iterative pointer.
1943 */
1944 typedef linked_pointer<T> iterator;
1945};
1946
1947/**
1948 * Convenience typedef for root pointers of single linked lists.
1949 */
1950typedef LinkedObject *LinkedIndex;
1951
1952/**
1953 * Convenience type for a stack of linked objects.
1954 */
1955typedef ObjectStack objstack_t;
1956
1957/**
1958 * Convenience type for a fifo of linked objects.
1959 */
1960typedef OrderedIndex objfifo_t;
1961
1962/**
1963 * Convenience type for a queue of linked objects.
1964 */
1965typedef ObjectQueue objqueue_t;
1966
1967END_NAMESPACE
1968
1969#endif