1 | /* |
1 | /* |
2 | list.h - Part of psiconv, a PSION 5 file formats converter |
2 | list.h - Part of psiconv, a PSION 5 file formats converter |
3 | Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl> |
3 | Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl> |
4 | |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; either version 2 of the License, or |
7 | the Free Software Foundation; either version 2 of the License, or |
8 | (at your option) any later version. |
8 | (at your option) any later version. |
… | |
… | |
24 | #define PSICONV_LIST_H |
24 | #define PSICONV_LIST_H |
25 | |
25 | |
26 | #include <stddef.h> |
26 | #include <stddef.h> |
27 | #include <stdio.h> |
27 | #include <stdio.h> |
28 | |
28 | |
|
|
29 | #include <psiconv/general.h> |
|
|
30 | |
|
|
31 | #ifdef __cplusplus |
|
|
32 | extern "C" { |
|
|
33 | #endif /* __cplusplus */ |
|
|
34 | |
29 | /* Always use psiconv_list, never struct psiconv_list */ |
35 | /* Always use psiconv_list, never struct psiconv_list */ |
30 | /* No need to export the actual internal format */ |
36 | /* No need to export the actual internal format */ |
31 | typedef struct psiconv_list *psiconv_list; |
37 | typedef struct psiconv_list_s *psiconv_list; |
32 | |
38 | |
33 | /* Before using a list, call list_new. It takes the size of a single element |
39 | /* Before using a list, call list_new. It takes the size of a single element |
34 | as its argument. Always compute it with a sizeof() expression, just to be |
40 | as its argument. Always compute it with a sizeof() expression, just to be |
35 | safe. The returned list is empty. */ |
41 | safe. The returned list is empty. |
|
|
42 | If there is not enough memory available, NULL is returned. You should |
|
|
43 | always test for this explicitely, because the other functions do not |
|
|
44 | like a psiconv_list argument that is equal to NULL */ |
36 | extern psiconv_list psiconv_list_new(int element_size); |
45 | extern psiconv_list psiconv_list_new(size_t element_size); |
37 | |
46 | |
38 | /* This frees the list. If elements contain pointers that need to be freed |
47 | /* This frees the list. If elements contain pointers that need to be freed |
39 | separately, call list_free_el below. */ |
48 | separately, call list_free_el below. */ |
40 | extern void psiconv_list_free(psiconv_list l); |
49 | extern void psiconv_list_free(psiconv_list l); |
41 | |
50 | |
… | |
… | |
43 | Note that you should *not* do 'free(el)' at any time; that is taken care of |
52 | Note that you should *not* do 'free(el)' at any time; that is taken care of |
44 | automatically. */ |
53 | automatically. */ |
45 | extern void psiconv_list_free_el(psiconv_list l, void free_el(void *el)); |
54 | extern void psiconv_list_free_el(psiconv_list l, void free_el(void *el)); |
46 | |
55 | |
47 | /* Return the number of allocated elements */ |
56 | /* Return the number of allocated elements */ |
48 | extern int psiconv_list_length(const psiconv_list l); |
57 | extern psiconv_u32 psiconv_list_length(const psiconv_list l); |
49 | |
58 | |
50 | /* Return 1 if the list is empty, 0 if not */ |
59 | /* Return 1 if the list is empty, 0 if not */ |
51 | extern int psiconv_list_is_empty(const psiconv_list l); |
60 | extern int psiconv_list_is_empty(const psiconv_list l); |
52 | |
61 | |
|
|
62 | /* Empty a list. Note this does not reclaim any memory space! */ |
|
|
63 | extern void psiconv_list_empty(psiconv_list l); |
|
|
64 | |
53 | /* Get an element from the list, and return a pointer to it. Note: you can |
65 | /* Get an element from the list, and return a pointer to it. Note: you can |
54 | directly modify this element, but be careful not to write beyond the |
66 | directly modify this element, but be careful not to write beyond the |
55 | element memory space. */ |
67 | element memory space. |
|
|
68 | If indx is out of range, NULL is returned. */ |
56 | extern void * psiconv_list_get(const psiconv_list l, unsigned int indx); |
69 | extern void * psiconv_list_get(const psiconv_list l, psiconv_u32 indx); |
57 | |
70 | |
58 | /* Add an element at the end of the list. The element is copied from the |
71 | /* Add an element at the end of the list. The element is copied from the |
59 | supplied element. Of course, this does not help if the element contains |
72 | supplied element. Of course, this does not help if the element contains |
60 | pointers. */ |
73 | pointers. |
|
|
74 | As the lists extends itself, it may be necessary to allocate new |
|
|
75 | memory. If this fails, a negative error-code is returned. If everything, |
|
|
76 | succeeds, 0 is returned. */ |
61 | extern void psiconv_list_add(psiconv_list l, void *el); |
77 | extern int psiconv_list_add(psiconv_list l, const void *el); |
|
|
78 | |
|
|
79 | /* Remove the last element from the list, and copy it to el. Note that |
|
|
80 | this will not reduce the amount of space reserved for the list. |
|
|
81 | An error code is returned, which will be 0 zero if everything |
|
|
82 | succeeded. It is your own responsibility to make sure enough |
|
|
83 | space is allocated to el. */ |
|
|
84 | extern int psiconv_list_pop(psiconv_list l, void *el); |
|
|
85 | |
|
|
86 | /* Replace an element within the list. The element is copied from the |
|
|
87 | supplied element. Fails if you try to write at or after the end of |
|
|
88 | the list. */ |
|
|
89 | extern int psiconv_list_replace(psiconv_list l, psiconv_u32 indx, |
|
|
90 | const void *el); |
62 | |
91 | |
63 | /* Do some action for each element. Note: you can directly modify the |
92 | /* Do some action for each element. Note: you can directly modify the |
64 | elements supplied to action, and they will be changed in the list, |
93 | elements supplied to action, and they will be changed in the list, |
65 | but never try a free(el)! */ |
94 | but never try a free(el)! */ |
66 | extern void psiconv_list_foreach_el(psiconv_list l, void action(void *el)); |
95 | extern void psiconv_list_foreach_el(psiconv_list l, void action(void *el)); |
67 | |
96 | |
68 | /* Clone the list, that is, copy it. If elements contain pointers, you |
97 | /* Clone the list, that is, copy it. If elements contain pointers, you |
69 | should call the next routine. */ |
98 | should call the next routine. If not enough memory is available, |
|
|
99 | NULL is returned. */ |
70 | extern psiconv_list psiconv_list_clone(const psiconv_list l); |
100 | extern psiconv_list psiconv_list_clone(const psiconv_list l); |
71 | |
|
|
72 | /* Clone the list. For each element, clone_el is called. The elements which |
|
|
73 | are given to clone_el must be modified in place, as needed. */ |
|
|
74 | extern psiconv_list psiconv_list_clone_el(const psiconv_list l, |
|
|
75 | void clone_el(void *el)); |
|
|
76 | |
101 | |
77 | /* Read upto size_t elements from file f, and put them at the end of list l. |
102 | /* Read upto size_t elements from file f, and put them at the end of list l. |
78 | Returned is the actual number of elements added. This assumes the file |
103 | Returned is the actual number of elements added. This assumes the file |
79 | layout and the memory layout of elements is the same. */ |
104 | layout and the memory layout of elements is the same. Note that if |
|
|
105 | not enough memory could be allocated, 0 is simply returned. */ |
80 | extern size_t psiconv_list_fread(psiconv_list l,size_t size, FILE *f); |
106 | extern size_t psiconv_list_fread(psiconv_list l,size_t size, FILE *f); |
81 | |
107 | |
|
|
108 | /* Read the whole file f to list l. Returns 0 on succes, and an errorcode |
|
|
109 | on failure. */ |
|
|
110 | extern int psiconv_list_fread_all(psiconv_list l, FILE *f); |
|
|
111 | |
|
|
112 | /* Write the whole list l to the opened file f. Returns 0 on succes, and |
|
|
113 | an errorcode on failure. */ |
|
|
114 | extern int psiconv_list_fwrite_all(const psiconv_list l, FILE *f); |
|
|
115 | |
|
|
116 | /* Concatenate two lists. The element sized does not have to be the same, |
|
|
117 | but the result may be quite unexpected if it is not. */ |
|
|
118 | int psiconv_list_concat(psiconv_list l, const psiconv_list extra); |
|
|
119 | |
|
|
120 | |
|
|
121 | #ifdef __cplusplus |
|
|
122 | } |
|
|
123 | #endif /* __cplusplus */ |
|
|
124 | |
82 | #endif |
125 | #endif |