1 #include "comps_objlist.h"
2 #include "comps_utils.h"
3 
comps_objlist_it_next(const COMPS_ObjListIt * it)4 inline const COMPS_ObjListIt *comps_objlist_it_next(const COMPS_ObjListIt *it) {
5     return (const COMPS_ObjListIt*)it->next;
6 }
7 
comps_objlist_it_create(COMPS_Object * obj)8 COMPS_ObjListIt* comps_objlist_it_create(COMPS_Object *obj) {
9     COMPS_ObjListIt *objit;
10     objit = malloc(sizeof(COMPS_ObjListIt));
11     if (!objit) return NULL;
12 
13     objit->comps_obj = comps_object_incref(obj);
14     objit->next = NULL;
15     return objit;
16 }
17 
comps_objlist_it_create_x(COMPS_Object * obj)18 COMPS_ObjListIt* comps_objlist_it_create_x(COMPS_Object *obj) {
19     COMPS_ObjListIt *objit;
20     objit = malloc(sizeof(COMPS_ObjListIt));
21     if (!objit) return NULL;
22 
23     objit->comps_obj = obj;
24     objit->next = NULL;
25     return objit;
26 }
27 
comps_objlist_it_destroy(COMPS_ObjListIt * objit)28 void comps_objlist_it_destroy(COMPS_ObjListIt *objit) {
29     //objit = malloc(sizeof(COMPS_ObjListIt));
30     comps_object_destroy(objit->comps_obj);
31     free(objit);
32 }
33 
comps_objlist_create(COMPS_ObjList * objlist,COMPS_Object ** args)34 void comps_objlist_create(COMPS_ObjList *objlist, COMPS_Object **args) {
35     (void)args;
36     objlist->first = NULL;
37     objlist->last = NULL;
38     objlist->len = 0;
39 }
COMPS_CREATE_u(objlist,COMPS_ObjList)40 COMPS_CREATE_u(objlist, COMPS_ObjList)
41 
42 void comps_objlist_copy(COMPS_ObjList *objlist_dst,
43                         COMPS_ObjList *objlist_src) {
44     COMPS_ObjListIt *it;
45 
46     objlist_dst->first = NULL;
47     objlist_dst->last = NULL;
48     objlist_dst->len = 0;
49 
50     for (it = objlist_src->first; it != NULL; it = it->next) {
51         comps_objlist_append_x(objlist_dst, comps_object_copy(it->comps_obj));
52     }
53 }
COMPS_COPY_u(objlist,COMPS_ObjList)54 COMPS_COPY_u(objlist, COMPS_ObjList)
55 
56 
57 void comps_objlist_destroy(COMPS_ObjList *objlist) {
58     COMPS_ObjListIt *oldit, *it = objlist->first;
59     COMPS_Object **obj= NULL;
60 
61     for (oldit = it; comps_objlist_walk(&it, obj); oldit = it) {
62         comps_objlist_it_destroy(oldit);
63     }
64     if (oldit)
65         comps_objlist_it_destroy(oldit);
66 }
COMPS_DESTROY_u(objlist,COMPS_ObjList)67 COMPS_DESTROY_u(objlist, COMPS_ObjList)
68 
69 void comps_objlist_clear(COMPS_ObjList *objlist) {
70     comps_objlist_destroy(objlist);
71     objlist->first = NULL;
72     objlist->last = NULL;
73     objlist->len = 0;
74 }
75 
76 
comps_objlist_get(COMPS_ObjList * objlist,unsigned int atpos)77 COMPS_Object* comps_objlist_get(COMPS_ObjList *objlist, unsigned int atpos) {
78     unsigned int pos;
79     COMPS_ObjListIt *it;
80     if (!objlist) return NULL;
81 
82     for (it = objlist->first, pos=0;
83          it != NULL && pos != atpos;
84          it = it->next, pos++);
85 
86     if (pos != atpos)
87         return NULL;
88 
89     return (it)?comps_object_incref(it->comps_obj):NULL;
90 }
91 
comps_objlist_get_x(COMPS_ObjList * objlist,unsigned int atpos)92 COMPS_Object* comps_objlist_get_x(COMPS_ObjList *objlist, unsigned int atpos) {
93     unsigned int pos;
94     COMPS_ObjListIt *it;
95     if (!objlist) return NULL;
96 
97     for (it = objlist->first, pos=0;
98          it != NULL && pos != atpos;
99          it = it->next, pos++);
100 
101     if (pos != atpos)
102         return NULL;
103 
104     return (it)?it->comps_obj:NULL;
105 }
106 
comps_objlist_get_it(COMPS_ObjList * objlist,unsigned int atpos)107 COMPS_ObjListIt* comps_objlist_get_it(COMPS_ObjList *objlist,
108                               unsigned int atpos) {
109     unsigned int pos;
110     COMPS_ObjListIt *it;
111     if (!objlist) return NULL;
112 
113     for (it = objlist->first, pos=0;
114          it != NULL && pos != atpos;
115          it = it->next, pos++);
116 
117     if (pos+1 != atpos)
118         return NULL;
119 
120     return (it)?it:NULL;
121 }
122 
123 
comps_objlist_walk(COMPS_ObjListIt ** walker,COMPS_Object ** result)124 int comps_objlist_walk(COMPS_ObjListIt **walker, COMPS_Object **result) {
125     if (!walker || !*walker) return 0;
126     if (result)
127         *result = (*walker)->comps_obj;
128     *walker = (*walker)->next;
129     return 1;
130 }
131 
comps_objlist_walk_r(COMPS_ObjListIt * start,COMPS_ObjListIt * mantinel,COMPS_Object ** result)132 int comps_objlist_walk_r(COMPS_ObjListIt *start,
133                             COMPS_ObjListIt *mantinel,
134                             COMPS_Object **result) {
135     if (!start->next) return 0;
136     if (start == mantinel)
137         return 0;
138     start = start->next;
139     *result = start->comps_obj;
140     return 1;
141 }
142 
__comps_objlist_append(COMPS_ObjList * objlist,COMPS_ObjListIt * objit)143 static int __comps_objlist_append(COMPS_ObjList *objlist, COMPS_ObjListIt *objit) {
144     if (!objlist || !objit) return 0;
145     if (objlist->first == NULL) {
146         objlist->first = objit;
147         objlist->last = objit;
148     } else {
149         objlist->last->next = objit;
150         objlist->last = objlist->last->next;
151     }
152     objlist->len++;
153     return 1;
154 }
155 
comps_objlist_append_x(COMPS_ObjList * objlist,COMPS_Object * obj)156 int comps_objlist_append_x(COMPS_ObjList *objlist, COMPS_Object *obj) {
157     COMPS_ObjListIt *new_it = comps_objlist_it_create_x(obj);
158     return __comps_objlist_append(objlist, new_it);
159 }
comps_objlist_append(COMPS_ObjList * objlist,COMPS_Object * obj)160 int comps_objlist_append(COMPS_ObjList *objlist, COMPS_Object *obj) {
161     COMPS_ObjListIt *new_it = comps_objlist_it_create(obj);
162     return __comps_objlist_append(objlist, new_it);
163 }
164 
comps_objlist_insert_after(COMPS_ObjList * objlist,COMPS_ObjListIt * it,COMPS_Object * obj)165 int comps_objlist_insert_after(COMPS_ObjList *objlist,
166                               COMPS_ObjListIt *it,
167                               COMPS_Object *obj) {
168     if (!objlist) return -1;
169     if (!it) return -1;
170 
171     COMPS_ObjListIt *new_it = comps_objlist_it_create(obj);
172 
173     new_it->next = it->next;
174     it->next = new_it;
175     if (it == objlist->last) {
176         objlist->last = new_it;
177     }
178     objlist->len++;
179     return 1;
180 }
181 
comps_objlist_insert_before(COMPS_ObjList * objlist,COMPS_ObjListIt * it,COMPS_Object * obj)182 int comps_objlist_insert_before(COMPS_ObjList *objlist,
183                                COMPS_ObjListIt *it,
184                                COMPS_Object *obj) {
185     if (!objlist) return -1;
186     if (!it) return -1;
187 
188     COMPS_ObjListIt *new_it = comps_objlist_it_create(obj);
189     COMPS_ObjListIt *tmpit;
190     for (tmpit = objlist->first; tmpit->next != it; tmpit = tmpit->next);
191 
192     if (tmpit == objlist->first) {
193         new_it->next = objlist->first;
194         objlist->first = new_it;
195         if (objlist->last == NULL)
196             objlist->last = new_it;
197     } else {
198         new_it->next = tmpit->next;
199         tmpit->next = new_it;
200     }
201     objlist->len++;
202     return 1;
203 }
204 
__comps_objlist_insert_at(COMPS_ObjList * objlist,unsigned int pos,COMPS_ObjListIt * newit)205 int __comps_objlist_insert_at(COMPS_ObjList *objlist,
206                            unsigned int pos,
207                            COMPS_ObjListIt *newit) {
208     COMPS_ObjListIt *tmpit, *oldit;
209     unsigned int i;
210     if (pos == 0) {
211         newit->next = objlist->first;
212         objlist->first = newit;
213         if (!objlist->last) {
214             objlist->last = newit;
215         }
216     } else if (pos == objlist->len){
217         newit->next = NULL;
218         objlist->last->next = newit;
219         objlist->last = newit;
220     } else {
221         i = 0;
222         oldit = NULL;
223         for (tmpit = objlist->first; tmpit != NULL && i != pos;
224              i++, tmpit = tmpit->next) {
225             oldit = tmpit;
226         }
227         newit->next = oldit->next;
228         oldit->next = newit;
229     }
230     objlist->len++;
231     return 1;
232 }
comps_objlist_insert_at_x(COMPS_ObjList * objlist,unsigned int pos,COMPS_Object * obj)233 int comps_objlist_insert_at_x(COMPS_ObjList *objlist,
234                            unsigned int pos,
235                            COMPS_Object *obj) {
236     if (!objlist) return -1;
237     if (pos > objlist->len) return -1;
238     COMPS_ObjListIt *newit = comps_objlist_it_create_x(obj);
239     return __comps_objlist_insert_at(objlist, pos, newit);
240 }
comps_objlist_insert_at(COMPS_ObjList * objlist,unsigned int pos,COMPS_Object * obj)241 int comps_objlist_insert_at(COMPS_ObjList *objlist,
242                            unsigned int pos,
243                            COMPS_Object *obj) {
244     if (!objlist) return -1;
245     if (pos > objlist->len) return -1;
246     COMPS_ObjListIt *newit = comps_objlist_it_create(obj);
247     return __comps_objlist_insert_at(objlist, pos, newit);
248 }
249 
comps_objlist_remove_at(COMPS_ObjList * objlist,unsigned int atpos)250 int comps_objlist_remove_at(COMPS_ObjList *objlist, unsigned int atpos) {
251     int pos;
252     COMPS_ObjListIt *it, *itprev = NULL;
253     if (!objlist) return 0;
254 
255     for (it = objlist->first, pos=0;
256          it != NULL && pos != (int)atpos;
257          it = it->next, pos++) {
258         itprev = it;
259     }
260     if (!it)
261         return 0;
262     if (itprev)
263         itprev->next = it->next;
264     else
265         objlist->first = it->next;
266     if (it == objlist->last)
267         objlist->last = itprev;
268     comps_objlist_it_destroy(it);
269     objlist->len--;
270     return 1;
271 }
272 
comps_objlist_remove(COMPS_ObjList * objlist,COMPS_Object * obj)273 int comps_objlist_remove(COMPS_ObjList *objlist, COMPS_Object *obj) {
274     COMPS_ObjListIt *it, *itprev = NULL;
275     if (!objlist) return 0;
276 
277     for (it = objlist->first; it != NULL && it->comps_obj != obj;
278          it = it->next) {
279         itprev = it;
280     }
281     if (!it)
282         return 0;
283     if (itprev)
284         itprev->next = it->next;
285     else
286         objlist->first = it->next;
287     if (it == objlist->last)
288         objlist->last = itprev;
289     comps_objlist_it_destroy(it);
290     objlist->len--;
291     return 1;
292 }
293 
comps_objlist_index(COMPS_ObjList * objlist,COMPS_Object * obj)294 int comps_objlist_index(COMPS_ObjList *objlist, COMPS_Object *obj) {
295     int x;
296     COMPS_ObjListIt *it;
297 
298     for (it = objlist->first, x=0; it != NULL && it->comps_obj != obj;
299          it = it->next, x++) {
300     };
301     if (it == NULL) return -1;
302     return x;
303 }
304 
comps_objlist_sublist_it(COMPS_ObjListIt * startit,COMPS_ObjListIt * end)305 COMPS_ObjList* comps_objlist_sublist_it(COMPS_ObjListIt *startit,
306                                       COMPS_ObjListIt *end) {
307     COMPS_ObjList *ret;
308     COMPS_ObjListIt *it;
309     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
310 
311     for (it = startit; it != end; it = it->next) {
312         comps_objlist_append(ret, it->comps_obj);
313     }
314     return ret;
315 }
316 
comps_objlist_sublist_it_step(COMPS_ObjListIt * startit,COMPS_ObjListIt * end,unsigned int step)317 COMPS_ObjList* comps_objlist_sublist_it_step(COMPS_ObjListIt *startit,
318                                            COMPS_ObjListIt *end,
319                                            unsigned int step) {
320     unsigned int stepc;
321     COMPS_ObjList *ret;
322     COMPS_ObjListIt *it;
323 
324     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
325     stepc = step;
326     for (it = startit; it->next != end; it = it->next, stepc++) {
327         if (step == stepc) {
328             stepc = 0;
329             comps_objlist_append(ret, it->comps_obj);
330         }
331     }
332     return ret;
333 }
334 
comps_objlist_sublist_indexed(COMPS_ObjList * objlist,unsigned int start,unsigned int end)335 COMPS_ObjList* comps_objlist_sublist_indexed(COMPS_ObjList *objlist,
336                                            unsigned int start,
337                                            unsigned int end) {
338     unsigned int pos;
339     COMPS_ObjList *ret;
340     COMPS_ObjListIt *it;
341     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
342 
343     for (it = objlist->first, pos=0;
344          it != NULL && pos != start;
345          it = it->next, pos++);
346     if (!it)
347         return ret;
348     for (; it->next != NULL && pos != end; it = it->next, pos++) {
349         comps_objlist_append(ret, it->comps_obj);
350     }
351     return ret;
352 }
353 
comps_objlist_sublist_indexed_step(COMPS_ObjList * objlist,unsigned int start,unsigned int end,unsigned int step)354 COMPS_ObjList* comps_objlist_sublist_indexed_step(COMPS_ObjList *objlist,
355                                                unsigned int start,
356                                                unsigned int end,
357                                                unsigned int step) {
358     unsigned int pos;
359     unsigned int stepc;
360     COMPS_ObjList *ret;
361     COMPS_ObjListIt *it;
362     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
363 
364     pos = 0;
365     stepc = 0;
366     for (it = objlist->first;
367          it != NULL && pos != start;
368          it = it->next, pos++);
369     if (!it)
370         return ret;
371     for (; it->next != NULL && pos != end; it = it->next, pos++, stepc++) {
372         if (stepc == step) {
373             step = 0;
374             comps_objlist_append(ret, it->comps_obj);
375         }
376     }
377     return ret;
378 }
379 
comps_objlist_filter(COMPS_ObjList * list,char (* filter_func)(COMPS_Object *))380 COMPS_ObjList* comps_objlist_filter(COMPS_ObjList *list,
381                                   char (*filter_func)(COMPS_Object*)) {
382     COMPS_ObjList *ret;
383     unsigned int i = 0;
384     COMPS_ObjListIt *it;
385 
386     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
387 
388     for (i=0, it = list->first; i < list->len; it = it->next, i++) {
389         if (filter_func(it->comps_obj))
390             comps_objlist_append(ret, it->comps_obj);
391     }
392     return ret;
393 }
394 
comps_objlist_concat(COMPS_ObjList * list1,COMPS_ObjList * list2)395 COMPS_ObjList* comps_objlist_concat(COMPS_ObjList *list1, COMPS_ObjList *list2) {
396     COMPS_ObjList *ret;
397     COMPS_ObjListIt *it;
398 
399     ret = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
400     for (it = list1->first; it != NULL; it = it->next) {
401         comps_objlist_append(ret, it->comps_obj);
402     }
403     for (it = list2->first; it != NULL; it = it->next) {
404         comps_objlist_append(ret, it->comps_obj);
405     }
406     return ret;
407 }
408 
comps_objlist_concat_in(COMPS_ObjList * list1,COMPS_ObjList * list2)409 void comps_objlist_concat_in(COMPS_ObjList *list1, COMPS_ObjList *list2) {
410     COMPS_ObjListIt *it;
411     for (it = list2->first; it != NULL; it = it->next) {
412         comps_objlist_append(list1, it->comps_obj);
413     }
414 }
415 
comps_objlist_cmp(COMPS_Object * list1,COMPS_Object * list2)416 signed char comps_objlist_cmp(COMPS_Object *list1, COMPS_Object *list2) {
417     COMPS_ObjListIt *it, *it2;
418     if (!list1 || !list2) return -1;
419     it =  ((COMPS_ObjList*)list1)->first;
420     it2 =  ((COMPS_ObjList*)list2)->first;
421 
422     for (; it != NULL && it2 != NULL; it = it->next, it2 = it2->next) {
423         if (!comps_object_cmp(it->comps_obj, it2->comps_obj))
424             return 0;
425     }
426     if (!it && !it2)
427         return 1;
428     else
429         return 0;
430 }
431 
comps_objlist_set(COMPS_ObjList * objlist,unsigned int atpos,COMPS_Object * obj)432 int comps_objlist_set(COMPS_ObjList *objlist, unsigned int atpos,
433                       COMPS_Object *obj) {
434     COMPS_ObjListIt *it;
435     unsigned int i = 0;
436 
437     if (!objlist) return -1;
438     it =  ((COMPS_ObjList*)objlist)->first;
439 
440     for (; it != NULL && i != atpos; it = it->next, i++);
441     if (!it)
442         return -1;
443     COMPS_OBJECT_DESTROY(it->comps_obj);
444     it->comps_obj = comps_object_incref(obj);
445     return 0;
446 }
447 
comps_objlist_tostr_u(COMPS_Object * list)448 char* comps_objlist_tostr_u(COMPS_Object* list) {
449     char *items[((COMPS_ObjList*)list)->len];
450     char *tmps, *ret;
451     int i=0, total_strlen = 10;//, total2;
452     const int sep_len = strlen(", ");
453 
454     COMPS_ObjListIt *it = ((COMPS_ObjList*)list)->first;
455     if (it) {
456         for (; it != ((COMPS_ObjList*)list)->last; it = it->next, i++) {
457             tmps = comps_object_tostr(it->comps_obj);
458             items[i] = tmps;
459             total_strlen += sep_len + strlen(tmps);
460         }
461         tmps = comps_object_tostr(it->comps_obj);
462         items[i] = tmps;
463         total_strlen += strlen(tmps);
464     }
465     //printf("total len:%d", total_strlen);
466     //printf("list len:%d\n", ((COMPS_ObjList*)list)->len);
467     //total2=0;
468     ret = malloc(sizeof(char) * (total_strlen));
469     ret[0]=0;
470     strcat(ret, "[");
471     //total2 += strlen("[");
472     if (((COMPS_ObjList*)list)->len) {
473         for (i = 0; i < (int)(((COMPS_ObjList*)list)->len-1); i++) {
474             strcat(ret, items[i]);
475             //total2 += strlen(items[i]);
476             strcat(ret, ", ");
477             //total2 += strlen(", ");
478             free(items[i]);
479         }
480         strcat(ret, items[i]);
481         //total2 += strlen(items[i]);
482         free(items[i]);
483     }
484     strcat(ret, "]");
485     //total2 += strlen("]");
486     //printf("total len2:%d\n", total2);
487     return ret;
488 }
489 
490 
491 COMPS_ObjectInfo COMPS_ObjList_ObjInfo = {
492     .obj_size = sizeof(COMPS_ObjList),
493     .constructor = &comps_objlist_create_u,
494     .destructor = &comps_objlist_destroy_u,
495     .copy = &comps_objlist_copy_u,
496     .obj_cmp = &comps_objlist_cmp,
497     .to_str = &comps_objlist_tostr_u
498 };
499