1 /*
2  * Copyright (c) 2007,2008 Mij <mij@bitchx.it>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 
18 /*
19  * SimCList library. See http://mij.oltrelinux.com/devel/simclist
20  */
21 
22 
23 #ifndef SIMCLIST_H
24 #define SIMCLIST_H
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <inttypes.h>
31 #include <errno.h>
32 #include <sys/types.h>
33 
34 /* Be friend of both C90 and C99 compilers */
35 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
36     /* "inline" and "restrict" are keywords */
37 #else
38 #   define inline           /* inline */
39 #   define restrict         /* restrict */
40 #endif
41 
42 
43 /**
44  * Type representing list hashes.
45  *
46  * This is a signed integer value.
47  */
48 typedef int32_t list_hash_t;
49 
50 #ifndef SIMCLIST_NO_DUMPRESTORE
51 typedef struct {
52     uint16_t version;       /* dump version */
53     int64_t timestamp;      /* when the list has been dumped, microseconds from UNIX epoch */
54     uint32_t list_size;
55     uint32_t list_numels;
56     list_hash_t list_hash;       /* hash of the list when dumped, or 0 if invalid */
57     uint32_t dumpsize;
58     int consistent;         /* 1 if the dump is verified complete/consistent; 0 otherwise */
59 } list_dump_info_t;
60 #endif
61 
62 /**
63  * a comparator of elements.
64  *
65  * A comparator of elements is a function that:
66  *      -# receives two references to elements a and b
67  *      -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
68  *
69  * It is responsability of the function to handle possible NULL values.
70  */
71 typedef int (*element_comparator)(const void *a, const void *b);
72 
73 /**
74  * an element synthesizer / sort key generator.
75  *
76  * Takes an element and returns an integer key suitable to direct sorting.
77  * Elements are sorted by key of increasing value. To invert the sorting
78  * direction, invert the sign of the key.
79  *
80  * @see list_sort()
81  */
82 typedef long int (*element_keymaker)(const void *el);
83 
84 /**
85  * a seeker of elements.
86  *
87  * An element seeker is a function that:
88  *      -# receives a reference to an element el
89  *      -# receives a reference to some indicator data
90  *      -# returns non-0 if the element matches the indicator, 0 otherwise
91  *
92  * It is responsability of the function to handle possible NULL values in any
93  * argument.
94  */
95 typedef int (*element_seeker)(const void *el, const void *indicator);
96 
97 /**
98  * an element lenght meter.
99  *
100  * An element meter is a function that:
101  *      -# receives the reference to an element el
102  *      -# returns its size in bytes
103  *
104  * It is responsability of the function to handle possible NULL values.
105  */
106 typedef size_t (*element_meter)(const void *el);
107 
108 /**
109  * a function computing the hash of elements.
110  *
111  * An hash computing function is a function that:
112  *      -# receives the reference to an element el
113  *      -# returns a hash value for el
114  *
115  * It is responsability of the function to handle possible NULL values.
116  */
117 typedef list_hash_t (*element_hash_computer)(const void *el);
118 
119 /**
120  * a function for serializing an element.
121  *
122  * A serializer function is one that gets a reference to an element,
123  * and returns a reference to a buffer that contains its serialization
124  * along with the length of this buffer.
125  * It is responsability of the function to handle possible NULL values,
126  * returning a NULL buffer and a 0 buffer length.
127  *
128  * These functions have 3 goals:
129  *  -# "freeze" and "flatten" the memory representation of the element
130  *  -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
131  *  -# possibly extract a compressed representation of the element
132  *
133  * @param el                reference to the element data
134  * @param serialize_buffer  reference to fill with the length of the buffer
135  * @return                  reference to the buffer with the serialized data
136  */
137 typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
138 
139 /**
140  * a function for un-serializing an element.
141  *
142  * An unserializer function accomplishes the inverse operation of the
143  * serializer function.  An unserializer function is one that gets a
144  * serialized representation of an element and turns it backe to the original
145  * element. The serialized representation is passed as a reference to a buffer
146  * with its data, and the function allocates and returns the buffer containing
147  * the original element, and it sets the length of this buffer into the
148  * integer passed by reference.
149  *
150  * @param data              reference to the buffer with the serialized representation of the element
151  * @param data_len          reference to the location where to store the length of the data in the buffer returned
152  * @return                  reference to a buffer with the original, unserialized representation of the element
153  */
154 typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
155 
156 /* [private-use] list entry -- olds actual user datum */
157 struct list_entry_s {
158     void *data;
159 
160     /* doubly-linked list service references */
161     struct list_entry_s *next;
162     struct list_entry_s *prev;
163 };
164 
165 /* [private-use] list attributes */
166 struct list_attributes_s {
167     /* user-set routine for comparing list elements */
168     element_comparator comparator;
169     /* user-set routine for synthesizing an element into an int value for sorting */
170     element_keymaker keymaker;
171     /* user-set routing for seeking elements */
172     element_seeker seeker;
173     /* user-set routine for determining the length of an element */
174     element_meter meter;
175     int copy_data;
176     /* user-set routine for computing the hash of an element */
177     element_hash_computer hasher;
178     /* user-set routine for serializing an element */
179     element_serializer serializer;
180     /* user-set routine for unserializing an element */
181     element_unserializer unserializer;
182 };
183 
184 /** list object */
185 typedef struct {
186     struct list_entry_s *head_sentinel;
187     struct list_entry_s *tail_sentinel;
188     struct list_entry_s *mid;
189 
190     unsigned int numels;
191 
192     /* array of spare elements */
193     struct list_entry_s **spareels;
194     unsigned int spareelsnum;
195 
196 #ifdef SIMCLIST_WITH_THREADS
197     /* how many threads are currently running */
198     unsigned int threadcount;
199 #endif
200 
201     /* service variables for list iteration */
202     int iter_active;
203     unsigned int iter_pos;
204     struct list_entry_s *iter_curentry;
205 
206     /* list attributes */
207     struct list_attributes_s attrs;
208 } list_t;
209 
210 /**
211  * initialize a list object for use.
212  *
213  * @param l     must point to a user-provided memory location
214  * @return      0 for success. -1 for failure
215  */
216 int list_init(list_t *restrict l);
217 
218 /**
219  * completely remove the list from memory.
220  *
221  * This function is the inverse of list_init(). It is meant to be called when
222  * the list is no longer going to be used. Elements and possible memory taken
223  * for internal use are freed.
224  *
225  * @param l     list to destroy
226  */
227 void list_destroy(list_t *restrict l);
228 
229 /**
230  * set the comparator function for list elements.
231  *
232  * Comparator functions are used for searching and sorting. If NULL is passed
233  * as reference to the function, the comparator is disabled.
234  *
235  * @param l     list to operate
236  * @param comparator_fun    pointer to the actual comparator function
237  * @return      0 if the attribute was successfully set; -1 otherwise
238  *
239  * @see element_comparator()
240  */
241 int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
242 
243 /**
244  * set the keymaker functions for list elements.
245  *
246  * @see element_keymaker
247  *
248  * @param l     list to operate
249  * @param keymaker_fun    pointer to the actual keymaker function
250  * @return      0 if the attribute was successfully set; -1 otherwise
251  */
252 int list_attributes_keymaker(list_t *restrict l, element_keymaker keymaker_fun);
253 
254 /**
255  * set a seeker function for list elements.
256  *
257  * Seeker functions are used for finding elements. If NULL is passed as reference
258  * to the function, the seeker is disabled.
259  *
260  * @param l     list to operate
261  * @param seeker_fun    pointer to the actual seeker function
262  * @return      0 if the attribute was successfully set; -1 otherwise
263  *
264  * @see element_seeker()
265  */
266 int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
267 
268 /**
269  * require to free element data when list entry is removed (default: don't free).
270  *
271  * [ advanced preference ]
272  *
273  * By default, when an element is removed from the list, it disappears from
274  * the list by its actual data is not free()d. With this option, every
275  * deletion causes element data to be freed.
276  *
277  * It is responsability of this function to correctly handle NULL values, if
278  * NULL elements are inserted into the list.
279  *
280  * @param l             list to operate
281  * @param metric_fun    pointer to the actual metric function
282  * @param copy_data     0: do not free element data (default); non-0: do free
283  * @return          0 if the attribute was successfully set; -1 otherwise
284  *
285  * @see element_meter()
286  * @see list_meter_int8_t()
287  * @see list_meter_int16_t()
288  * @see list_meter_int32_t()
289  * @see list_meter_int64_t()
290  * @see list_meter_uint8_t()
291  * @see list_meter_uint16_t()
292  * @see list_meter_uint32_t()
293  * @see list_meter_uint64_t()
294  * @see list_meter_float()
295  * @see list_meter_double()
296  * @see list_meter_string()
297  */
298 int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
299 
300 /**
301  * set the element hash computing function for the list elements.
302  *
303  * [ advanced preference ]
304  *
305  * An hash can be requested depicting the list status at a given time. An hash
306  * only depends on the elements and their order. By default, the hash of an
307  * element is only computed on its reference. With this function, the user can
308  * set a custom function computing the hash of an element. If such function is
309  * provided, the list_hash() function automatically computes the list hash using
310  * the custom function instead of simply referring to element references.
311  *
312  * @param l             list to operate
313  * @param hash_computer_fun pointer to the actual hash computing function
314  * @return              0 if the attribute was successfully set; -1 otherwise
315  *
316  * @see element_hash_computer()
317  */
318 int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
319 
320 /**
321  * set the element serializer function for the list elements.
322  *
323  * [ advanced preference ]
324  *
325  * Serialize functions are used for dumping the list to some persistent
326  * storage.  The serializer function is called for each element; it is passed
327  * a reference to the element and a reference to a size_t object. It will
328  * provide (and return) the buffer with the serialization of the element and
329  * fill the size_t object with the length of this serialization data.
330  *
331  * @param   l   list to operate
332  * @param   serializer_fun  pointer to the actual serializer function
333  * @return      0 if the attribute was successfully set; -1 otherwise
334  *
335  * @see     element_serializer()
336  * @see     list_dump_filedescriptor()
337  * @see     list_restore_filedescriptor()
338  */
339 int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
340 
341 /**
342  * set the element unserializer function for the list elements.
343  *
344  * [ advanced preference ]
345  *
346  * Unserialize functions are used for restoring the list from some persistent
347  * storage. The unserializer function is called for each element segment read
348  * from the storage; it is passed the segment and a reference to an integer.
349  * It shall allocate and return a buffer compiled with the resumed memory
350  * representation of the element, and set the integer value to the length of
351  * this buffer.
352  *
353  * @param   l       list to operate
354  * @param   unserializer_fun    pointer to the actual unserializer function
355  * @return      0 if the attribute was successfully set; -1 otherwise
356  *
357  * @see     element_unserializer()
358  * @see     list_dump_filedescriptor()
359  * @see     list_restore_filedescriptor()
360  */
361 int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
362 
363 /**
364  * append data at the end of the list.
365  *
366  * This function is useful for adding elements with a FIFO/queue policy.
367  *
368  * @param l     list to operate
369  * @param data  pointer to user data to append
370  *
371  * @return      1 for success. < 0 for failure
372  */
373 int list_append(list_t *restrict l, const void *data);
374 
375 /**
376  * insert data in the head of the list.
377  *
378  * This function is useful for adding elements with a LIFO/Stack policy.
379  *
380  * @param l     list to operate
381  * @param data  pointer to user data to append
382  *
383  * @return      1 for success. < 0 for failure
384  */
385 int list_prepend(list_t *restrict l, const void *restrict data);
386 
387 /**
388  * extract the element in the top of the list.
389  *
390  * This function is for using a list with a FIFO/queue policy.
391  *
392  * @param l     list to operate
393  * @return      reference to user datum, or NULL on errors
394  */
395 void *list_fetch(list_t *restrict l);
396 
397 /**
398  * retrieve an element at a given position.
399  *
400  * @param l     list to operate
401  * @param pos   [0,size-1] position index of the element wanted
402  * @return      reference to user datum, or NULL on errors
403  */
404 void *list_get_at(const list_t *restrict l, unsigned int pos);
405 
406 /**
407  * return the maximum element of the list.
408  *
409  * @warning Requires a comparator function to be set for the list.
410  *
411  * Returns the maximum element with respect to the comparator function output.
412  *
413  * @see list_attributes_comparator()
414  *
415  * @param l     list to operate
416  * @return      the reference to the element, or NULL
417  */
418 void *list_get_max(const list_t *restrict l);
419 
420 /**
421  * return the minimum element of the list.
422  *
423  * @warning Requires a comparator function to be set for the list.
424  *
425  * Returns the minimum element with respect to the comparator function output.
426  *
427  * @see list_attributes_comparator()
428  *
429  * @param l     list to operate
430  * @return      the reference to the element, or NULL
431  */
432 void *list_get_min(const list_t *restrict l);
433 
434 /**
435  * retrieve and remove from list an element at a given position.
436  *
437  * @param l     list to operate
438  * @param pos   [0,size-1] position index of the element wanted
439  * @return      reference to user datum, or NULL on errors
440  */
441 void *list_extract_at(list_t *restrict l, unsigned int pos);
442 
443 /**
444  * insert an element at a given position.
445  *
446  * @param l     list to operate
447  * @param data  reference to data to be inserted
448  * @param pos   [0,size-1] position index to insert the element at
449  * @return      positive value on success. Negative on failure
450  */
451 int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
452 
453 /**
454  * expunge the first found given element from the list.
455  *
456  * Inspects the given list looking for the given element; if the element
457  * is found, it is removed. Only the first occurence is removed.
458  * If a comparator function was not set, elements are compared by reference.
459  * Otherwise, the comparator is used to match the element.
460  *
461  * @param l     list to operate
462  * @param data  reference of the element to search for
463  * @return      0 on success. Negative value on failure
464  *
465  * @see list_attributes_comparator()
466  * @see list_delete_at()
467  */
468 int list_delete(list_t *restrict l, const void *data);
469 
470 /**
471  * expunge an element at a given position from the list.
472  *
473  * @param l     list to operate
474  * @param pos   [0,size-1] position index of the element to be deleted
475  * @return      0 on success. Negative value on failure
476  */
477 int list_delete_at(list_t *restrict l, unsigned int pos);
478 
479 /**
480  * expunge an array of elements from the list, given their position range.
481  *
482  * @param l     list to operate
483  * @param posstart  [0,size-1] position index of the first element to be deleted
484  * @param posend    [posstart,size-1] position of the last element to be deleted
485  * @return      the number of elements successfully removed
486  */
487 int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
488 
489 /**
490  * clear all the elements off of the list.
491  *
492  * The element datums will not be freed.
493  *
494  * @see list_delete_range()
495  * @see list_size()
496  *
497  * @param l     list to operate
498  * @return      the number of elements in the list before cleaning
499  */
500 int list_clear(list_t *restrict l);
501 
502 /**
503  * inspect the number of elements in the list.
504  *
505  * @param l     list to operate
506  * @return      number of elements currently held by the list
507  */
508 unsigned int list_size(const list_t *restrict l);
509 
510 /**
511  * inspect whether the list is empty.
512  *
513  * @param l     list to operate
514  * @return      0 iff the list is not empty
515  *
516  * @see list_size()
517  */
518 int list_empty(const list_t *restrict l);
519 
520 /**
521  * find the position of an element in a list.
522  *
523  * @warning Requires a comparator function to be set for the list.
524  *
525  * Inspects the given list looking for the given element; if the element
526  * is found, its position into the list is returned.
527  * Elements are inspected comparing references if a comparator has not been
528  * set. Otherwise, the comparator is used to find the element.
529  *
530  * @param l     list to operate
531  * @param data  reference of the element to search for
532  * @return      position of element in the list, or <0 if not found
533  *
534  * @see list_attributes_comparator()
535  * @see list_get_at()
536  */
537 int list_locate(const list_t *restrict l, const void *data);
538 
539 /**
540  * returns an element given an indicator.
541  *
542  * @warning Requires a seeker function to be set for the list.
543  *
544  * Inspect the given list looking with the seeker if an element matches
545  * an indicator. If such element is found, the reference to the element
546  * is returned.
547  *
548  * @param l     list to operate
549  * @param indicator indicator data to pass to the seeker along with elements
550  * @return      reference to the element accepted by the seeker, or NULL if none found
551  */
552 void *list_seek(list_t *restrict l, const void *indicator);
553 
554 /**
555  * inspect whether some data is member of the list.
556  *
557  * @warning Requires a comparator function to be set for the list.
558  *
559  * By default, a per-reference comparison is accomplished. That is,
560  * the data is in list if any element of the list points to the same
561  * location of data.
562  * A "semantic" comparison is accomplished, otherwise, if a comparator
563  * function has been set previously, with list_attributes_comparator();
564  * in which case, the given data reference is believed to be in list iff
565  * comparator_fun(elementdata, userdata) == 0 for any element in the list.
566  *
567  * @param l     list to operate
568  * @param data  reference to the data to search
569  * @return      0 iff the list does not contain data as an element
570  *
571  * @see list_attributes_comparator()
572  */
573 int list_contains(const list_t *restrict l, const void *data);
574 
575 /**
576  * concatenate two lists
577  *
578  * Concatenates one list with another, and stores the result into a
579  * user-provided list object, which must be different from both the
580  * lists to concatenate. Attributes from the original lists are not
581  * cloned.
582  * The destination list referred is threated as virgin room: if it
583  * is an existing list containing elements, memory leaks will happen.
584  * It is OK to specify the same list twice as source, for "doubling"
585  * it in the destination.
586  *
587  * @param l1    base list
588  * @param l2    list to append to the base
589  * @param dest  reference to the destination list
590  * @return      0 for success, -1 for errors
591  */
592 int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
593 
594 /**
595  * sort list elements.
596  *
597  * @warning Requires a comparator function to be set for the list.
598  *
599  * Sorts the list in ascending or descending order as specified by the versus
600  * flag. The algorithm chooses autonomously what algorithm is best suited for
601  * sorting the list wrt its current status.
602  *
603  * @param l     list to operate
604  * @param versus positive: order small to big; negative: order big to small
605  * @return      0: sorting went OK      non-0: errors happened
606  *
607  * @see list_attributes_comparator()
608  * @see list_attributes_keymaker()
609  */
610 int list_sort(list_t *restrict l, int versus);
611 
612 /**
613  * start an iteration session.
614  *
615  * This function prepares the list to be iterated.
616  *
617  * @param l     list to operate
618  * @return         0 if the list cannot be currently iterated. >0 otherwise
619  *
620  * @see list_iterator_stop()
621  */
622 int list_iterator_start(list_t *restrict l);
623 
624 /**
625  * return the next element in the iteration session.
626  *
627  * @param l     list to operate
628  * @return        element datum, or NULL on errors
629  */
630 void *list_iterator_next(list_t *restrict l);
631 
632 /**
633  * inspect whether more elements are available in the iteration session.
634  *
635  * @param l     list to operate
636  * @return      0 iff no more elements are available.
637  */
638 int list_iterator_hasnext(const list_t *restrict l);
639 
640 /**
641  * end an iteration session.
642  *
643  * @param l     list to operate
644  * @return      0 iff the iteration session cannot be stopped
645  */
646 int list_iterator_stop(list_t *restrict l);
647 
648 /**
649  * return the hash of the current status of the list.
650  *
651  * @param l     list to operate
652  * @param hash  where the resulting hash is put
653  *
654  * @return      0 for success; <0 for failure
655  */
656 int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
657 
658 #ifndef SIMCLIST_NO_DUMPRESTORE
659 /**
660  * get meta informations on a list dump on filedescriptor.
661  *
662  * [ advanced function ]
663  *
664  * Extracts the meta information from a SimCList dump located in a file
665  * descriptor. The file descriptor must be open and positioned at the
666  * beginning of the SimCList dump block.
667  *
668  * @param fd        file descriptor to get metadata from
669  * @param info      reference to a dump metainformation structure to fill
670  * @return          0 for success; <0 for failure
671  *
672  * @see list_dump_filedescriptor()
673  */
674 int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
675 
676 /**
677  * get meta informations on a list dump on file.
678  *
679  * [ advanced function ]
680  *
681  * Extracts the meta information from a SimCList dump located in a file.
682  *
683  * @param filename  filename of the file to fetch from
684  * @param info      reference to a dump metainformation structure to fill
685  * @return          0 for success; <0 for failure
686  *
687  * @see list_dump_filedescriptor()
688  */
689 int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
690 
691 /**
692  * dump the list into an open, writable file descriptor.
693  *
694  * This function "dumps" the list to a persistent storage so it can be
695  * preserved across process terminations.
696  * When called, the file descriptor must be open for writing and positioned
697  * where the serialized data must begin. It writes its serialization of the
698  * list in a form which is portable across different architectures. Dump can
699  * be safely performed on stream-only (non seekable) descriptors. The file
700  * descriptor is not closed at the end of the operations.
701  *
702  * To use dump functions, either of these conditions must be satisfied:
703  *      -# a metric function has been specified with list_attributes_copy()
704  *      -# a serializer function has been specified with list_attributes_serializer()
705  *
706  * If a metric function has been specified, each element of the list is dumped
707  * as-is from memory, copying it from its pointer for its length down to the
708  * file descriptor. This might have impacts on portability of the dump to
709  * different architectures.
710  *
711  * If a serializer function has been specified, its result for each element is
712  * dumped to the file descriptor.
713  *
714  *
715  * @param l     list to operate
716  * @param fd    file descriptor to write to
717  * @param len   location to store the resulting length of the dump (bytes), or NULL
718  *
719  * @return      0 if successful; -1 otherwise
720  *
721  * @see element_serializer()
722  * @see list_attributes_copy()
723  * @see list_attributes_serializer()
724  */
725 int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
726 
727 /**
728  * dump the list to a file name.
729  *
730  * This function creates a filename and dumps the current content of the list
731  * to it. If the file exists it is overwritten. The number of bytes written to
732  * the file can be returned in a specified argument.
733  *
734  * @param l     list to operate
735  * @param filename    filename to write to
736  * @param len   location to store the resulting length of the dump (bytes), or NULL
737  *
738  * @return      0 if successful; -1 otherwise
739  *
740  * @see list_attributes_copy()
741  * @see element_serializer()
742  * @see list_attributes_serializer()
743  * @see list_dump_filedescriptor()
744  * @see list_restore_file()
745  *
746  * This function stores a representation of the list
747  */
748 int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
749 
750 /**
751  * restore the list from an open, readable file descriptor to memory.
752  *
753  * This function is the "inverse" of list_dump_filedescriptor(). It restores
754  * the list content from a (open, read-ready) file descriptor to memory. An
755  * unserializer might be needed to restore elements from the persistent
756  * representation back into memory-consistent format. List attributes can not
757  * be restored and must be set manually.
758  *
759  * @see list_dump_filedescriptor()
760  * @see list_attributes_serializer()
761  * @see list_attributes_unserializer()
762  *
763  * @param l     list to restore to
764  * @param fd    file descriptor to read from.
765  * @param len   location to store the length of the dump read (bytes), or NULL
766  * @return      0 if successful; -1 otherwise
767  */
768 int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
769 
770 /**
771  * restore the list from a file name.
772  *
773  * This function restores the content of a list from a file into memory. It is
774  * the inverse of list_dump_file().
775  *
776  * @see element_unserializer()
777  * @see list_attributes_unserializer()
778  * @see list_dump_file()
779  * @see list_restore_filedescriptor()
780  *
781  * @param l         list to restore to
782  * @param filename  filename to read data from
783  * @param len       location to store the length of the dump read (bytes), or NULL
784  * @return          0 if successful; -1 otherwise
785  */
786 int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
787 #endif
788 
789 /* ready-made comparators, meters and hash computers */
790                                 /* comparator functions */
791 /**
792  * ready-made comparator for int8_t elements.
793  * @see list_attributes_comparator()
794  */
795 int list_comparator_int8_t(const void *a, const void *b);
796 
797 /**
798  * ready-made comparator for int16_t elements.
799  * @see list_attributes_comparator()
800  */
801 int list_comparator_int16_t(const void *a, const void *b);
802 
803 /**
804  * ready-made comparator for int32_t elements.
805  * @see list_attributes_comparator()
806  */
807 int list_comparator_int32_t(const void *a, const void *b);
808 
809 /**
810  * ready-made comparator for int64_t elements.
811  * @see list_attributes_comparator()
812  */
813 int list_comparator_int64_t(const void *a, const void *b);
814 
815 /**
816  * ready-made comparator for uint8_t elements.
817  * @see list_attributes_comparator()
818  */
819 int list_comparator_uint8_t(const void *a, const void *b);
820 
821 /**
822  * ready-made comparator for uint16_t elements.
823  * @see list_attributes_comparator()
824  */
825 int list_comparator_uint16_t(const void *a, const void *b);
826 
827 /**
828  * ready-made comparator for uint32_t elements.
829  * @see list_attributes_comparator()
830  */
831 int list_comparator_uint32_t(const void *a, const void *b);
832 
833 /**
834  * ready-made comparator for uint64_t elements.
835  * @see list_attributes_comparator()
836  */
837 int list_comparator_uint64_t(const void *a, const void *b);
838 
839 /**
840  * ready-made comparator for float elements.
841  * @see list_attributes_comparator()
842  */
843 int list_comparator_float(const void *a, const void *b);
844 
845 /**
846  * ready-made comparator for double elements.
847  * @see list_attributes_comparator()
848  */
849 int list_comparator_double(const void *a, const void *b);
850 
851 /**
852  * ready-made comparator for string elements.
853  * @see list_attributes_comparator()
854  */
855 int list_comparator_string(const void *a, const void *b);
856 
857                                 /*          metric functions        */
858 /**
859  * ready-made metric function for int8_t elements.
860  * @see list_attributes_copy()
861  */
862 size_t list_meter_int8_t(const void *el);
863 
864 /**
865  * ready-made metric function for int16_t elements.
866  * @see list_attributes_copy()
867  */
868 size_t list_meter_int16_t(const void *el);
869 
870 /**
871  * ready-made metric function for int32_t elements.
872  * @see list_attributes_copy()
873  */
874 size_t list_meter_int32_t(const void *el);
875 
876 /**
877  * ready-made metric function for int64_t elements.
878  * @see list_attributes_copy()
879  */
880 size_t list_meter_int64_t(const void *el);
881 
882 /**
883  * ready-made metric function for uint8_t elements.
884  * @see list_attributes_copy()
885  */
886 size_t list_meter_uint8_t(const void *el);
887 
888 /**
889  * ready-made metric function for uint16_t elements.
890  * @see list_attributes_copy()
891  */
892 size_t list_meter_uint16_t(const void *el);
893 
894 /**
895  * ready-made metric function for uint32_t elements.
896  * @see list_attributes_copy()
897  */
898 size_t list_meter_uint32_t(const void *el);
899 
900 /**
901  * ready-made metric function for uint64_t elements.
902  * @see list_attributes_copy()
903  */
904 size_t list_meter_uint64_t(const void *el);
905 
906 /**
907  * ready-made metric function for float elements.
908  * @see list_attributes_copy()
909  */
910 size_t list_meter_float(const void *el);
911 
912 /**
913  * ready-made metric function for double elements.
914  * @see list_attributes_copy()
915  */
916 size_t list_meter_double(const void *el);
917 
918 /**
919  * ready-made metric function for string elements.
920  * @see list_attributes_copy()
921  */
922 size_t list_meter_string(const void *el);
923 
924                                 /*          hash functions          */
925 /**
926  * ready-made hash function for int8_t elements.
927  * @see list_attributes_hash_computer()
928  */
929 list_hash_t list_hashcomputer_int8_t(const void *el);
930 
931 /**
932  * ready-made hash function for int16_t elements.
933  * @see list_attributes_hash_computer()
934  */
935 list_hash_t list_hashcomputer_int16_t(const void *el);
936 
937 /**
938  * ready-made hash function for int32_t elements.
939  * @see list_attributes_hash_computer()
940  */
941 list_hash_t list_hashcomputer_int32_t(const void *el);
942 
943 /**
944  * ready-made hash function for int64_t elements.
945  * @see list_attributes_hash_computer()
946  */
947 list_hash_t list_hashcomputer_int64_t(const void *el);
948 
949 /**
950  * ready-made hash function for uint8_t elements.
951  * @see list_attributes_hash_computer()
952  */
953 list_hash_t list_hashcomputer_uint8_t(const void *el);
954 
955 /**
956  * ready-made hash function for uint16_t elements.
957  * @see list_attributes_hash_computer()
958  */
959 list_hash_t list_hashcomputer_uint16_t(const void *el);
960 
961 /**
962  * ready-made hash function for uint32_t elements.
963  * @see list_attributes_hash_computer()
964  */
965 list_hash_t list_hashcomputer_uint32_t(const void *el);
966 
967 /**
968  * ready-made hash function for uint64_t elements.
969  * @see list_attributes_hash_computer()
970  */
971 list_hash_t list_hashcomputer_uint64_t(const void *el);
972 
973 /**
974  * ready-made hash function for float elements.
975  * @see list_attributes_hash_computer()
976  */
977 list_hash_t list_hashcomputer_float(const void *el);
978 
979 /**
980  * ready-made hash function for double elements.
981  * @see list_attributes_hash_computer()
982  */
983 list_hash_t list_hashcomputer_double(const void *el);
984 
985 /**
986  * ready-made hash function for string elements.
987  * @see list_attributes_hash_computer()
988  */
989 list_hash_t list_hashcomputer_string(const void *el);
990 
991 #ifdef __cplusplus
992 }
993 #endif
994 
995 #endif
996 
997