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