Added debugging code for dumping data from memory using GUI.
[familia.git] / src / storage / storage.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "storage.h"
5
6 #include "../debug.h"
7
8 struct familia_storage * _familia_storage_current;
9
10 extern void _familia_storage_positions_init();
11 extern void _familia_storage_positions_free();
12
13 struct familia_storage * familia_storage_get_current()
14 {
15         return _familia_storage_current;
16 }
17
18 void familia_storage_set_current(struct familia_storage * storage)
19 {
20         _familia_storage_current = storage;
21 }
22
23 struct familia_storage * familia_storage_new()
24 {
25         struct familia_storage * storage = NULL;
26         storage = malloc(sizeof(struct familia_storage));
27
28         if (!storage) {
29                 debug("["__FILE__ "] There was a problem with allocating memory for storage.\n");
30                 return NULL;
31         }
32
33         storage->individuals = NULL;
34         storage->individuals_no = 0;
35         storage->families = NULL;
36         storage->families_no = 0;
37
38         _familia_storage_positions_init();
39
40         return storage;
41 }
42
43 void familia_storage_free(struct familia_storage * storage)
44 {
45         unsigned int i = 0;
46
47         if (storage->individuals_no) {
48                 for (i = 0; i < storage->individuals_no; i++) {
49                         familia_individual_free(storage->individuals[i]);
50                         storage->individuals[i] = NULL;
51                 }
52                 free(storage->individuals);
53                 storage->individuals = NULL;
54                 storage->individuals_no = 0;
55         }
56
57         if (storage->families_no) {
58                 for (i = 0; i < storage->families_no; i++) {
59                         familia_family_free(storage->families[i]);
60                         storage->families[i] = NULL;
61                 }
62                 free(storage->families);
63                 storage->families = NULL;
64                 storage->families_no = 0;
65         }
66
67         _familia_storage_positions_free();
68 }
69
70 void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual)
71 {
72         struct familia_individual ** tmp = NULL;
73         int size = (storage->individuals_no + 1);
74
75         if (individual) {
76                 tmp = realloc(storage->individuals, size * sizeof(struct familia_individual *));
77                 
78                 if (tmp) {
79                         storage->individuals = tmp;
80                         storage->individuals[storage->individuals_no] = individual;
81                         storage->individuals_no++;
82                 }
83                 else {
84                         debug("["__FILE__ "] There were problems with allocating memory for individual.\n");
85                 }
86         }
87 }
88
89 struct familia_individual * familia_storage_get_individual_by_id(struct familia_storage * storage, unsigned int id)
90 {
91         if (storage->individuals_no < id) {
92                 debug("["__FILE__ "Trying to get not existing individual!\n");
93                 return NULL;
94         }
95         return storage->individuals[id];
96 }
97
98 void familia_storage_remove_individual_by_id(struct familia_storage * storage, unsigned int id)
99 {
100         unsigned int i = 0;
101         int found = 0;
102         struct familia_individual ** tmp = NULL;
103         
104         if (storage->individuals_no < id) {
105                 debug("["__FILE__ "] Trying to remove not existing individual!\n");
106                 return;
107         }
108
109         for (i = 0; i < storage->individuals_no; i++) {
110                 if (storage->individuals[i]->id == id) {
111                         found = 1;
112                         familia_individual_free(storage->individuals[i]);
113                         storage->individuals[i] = NULL;
114                 }
115
116                 /*
117                  * If family has been found, reorder rest of files to avoid
118                  * NULL pointers inside array.
119                  */
120                 if (found && (i < storage->individuals_no - 1)) {
121                         storage->individuals[i] = storage->individuals[i + 1];
122                 }
123         }
124         
125         if (found) {
126                 tmp = realloc(storage->individuals,
127                         (storage->families_no) * sizeof(struct familia_family *));
128
129                 if (tmp) {
130                         storage->individuals = tmp;
131                 }
132                 storage->individuals_no--;
133         }
134 }
135
136 void familia_storage_add_family(struct familia_storage * storage, struct familia_family * family)
137 {
138         struct familia_family ** tmp = NULL;
139         int size = (storage->families_no + 1);
140
141         if (family) {
142                 tmp = realloc(storage->families, size * sizeof(struct familia_family *));
143                 
144                 if (tmp) {
145                         storage->families = tmp;
146                         storage->families[storage->families_no] = family;
147                         storage->families_no++;
148                 }
149                 else {
150                         debug("["__FILE__ "] There were problems with allocating memory for family.\n");
151                 }
152         }
153 }
154
155 struct familia_family * familia_storage_get_family_by_id(struct familia_storage * storage, unsigned int id)
156 {
157         if (storage->families_no < id) {
158                 debug("["__FILE__ "Trying to get not existing family!\n");
159                 return NULL;
160         }
161         return storage->families[id];
162 }
163
164 void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id)
165 {
166         unsigned int i = 0;
167         int found = 0;
168         struct familia_family ** tmp = NULL;
169         
170         if (storage->families_no < id) {
171                 debug("["__FILE__ "] Trying to remove not existing family!\n");
172                 return;
173         }
174
175         for (i = 0; i < storage->families_no; i++) {
176                 if (storage->families[i]->id == id) {
177                         found = 1;
178                         familia_family_free(storage->families[i]);
179                         storage->families[i] = NULL;
180                 }
181
182                 /*
183                  * If family has been found, reorder rest of files to avoid
184                  * NULL pointers inside array.
185                  */
186                 if (found && (i < storage->families_no - 1)) {
187                         storage->families[i] = storage->families[i + 1];
188                 }
189         }
190         
191         if (found) {
192                 tmp = realloc(storage->families,
193                         (storage->families_no) * sizeof(struct familia_family *));
194
195                 if (tmp) {
196                         storage->families = tmp;
197                 }
198                 storage->families_no--;
199         }
200 }
201
202 void familia_storage_dump_all()
203 {
204         int i;
205         struct familia_storage * storage = NULL;
206         struct familia_family * family = NULL;
207         struct familia_individual * individual = NULL;
208         
209         storage = familia_storage_get_current();
210         
211         for (i = 0; i < storage->individuals_no; i++) {
212                 individual = storage->individuals[i];
213                 printf("Individual (%d)\n", individual->id);
214                 printf("\t First name: %s\n", individual->first_name);
215                 printf("\t Last name: %s\n", individual->last_name);
216                 if (individual->families_no > 0) {
217                         int j;
218                         struct familia_family * f = NULL;
219                         struct familia_individual * i1 = NULL;
220                         struct familia_individual * i2 = NULL;
221
222                         printf("\t Families:\n");
223                         for (j = 0; j < individual->families_no; j++) {
224                                 f = individual->families[j];
225                                 i1 = familia_family_get_individual(f, Individual1);
226                                 i2 = familia_family_get_individual(f, Individual2);
227                                 
228                                 printf("\t > %s&%s\n", familia_individual_get_first_name(i1), familia_individual_get_first_name(i2));
229                         }
230                         printf("\t Parents:\n");
231                         f = familia_individual_get_parents(individual);
232                         i1 = familia_family_get_individual(f, Individual1);
233                         i2 = familia_family_get_individual(f, Individual2);
234                         
235                         printf("\t > %s&%s\n", familia_individual_get_first_name(i1), familia_individual_get_first_name(i2));
236                 }
237         }
238
239
240         for (i = 0; i < storage->families_no; i++) {
241                 int j;
242                 struct familia_individual * i1 = NULL;
243                 struct familia_individual * i2 = NULL;
244
245                 family = storage->families[i];
246
247                 printf("Family (%d)\n", family->id);
248                 i1 = familia_family_get_individual(family, Individual1);
249                 i2 = familia_family_get_individual(family, Individual2);
250                 printf("\t First parent: %s\n", familia_individual_get_first_name(i1));
251                 printf("\t Second parent: %s\n", familia_individual_get_first_name(i2));
252
253                 printf("\t Children:\n");
254                 if (family->children_no > 0) {
255                         for (j = 0; j < family->children_no; j++) {
256                                 i1 = family->children[j];
257                                 printf("\t > %s\n", familia_individual_get_first_name(i1));
258                         }
259                 }
260         }
261 }