1 /*
2 copyright: Steve Dekorte, 2006. All rights reserved.
3 license: See _BSDLicense.txt.
4 */
5
6 #include "Base.h"
7
8 #define UArray_C
9 #include "UArray.h"
10 #undef UArray_C
11
12 #include <string.h>
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <limits.h>
16
CTYPE_size(CTYPE type)17 size_t CTYPE_size(CTYPE type)
18 {
19 switch (type)
20 {
21 case CTYPE_uint8_t: return sizeof(uint8_t);
22 case CTYPE_uint16_t: return sizeof(uint16_t);
23 case CTYPE_uint32_t: return sizeof(uint32_t);
24 case CTYPE_uint64_t: return sizeof(uint64_t);
25
26 case CTYPE_int8_t: return sizeof(int8_t);
27 case CTYPE_int16_t: return sizeof(int16_t);
28 case CTYPE_int32_t: return sizeof(int32_t);
29 case CTYPE_int64_t: return sizeof(int64_t);
30
31 case CTYPE_float32_t: return sizeof(float32_t);
32 case CTYPE_float64_t: return sizeof(float64_t);
33
34 case CTYPE_uintptr_t: return sizeof(uintptr_t);
35 }
36 return 0;
37 }
38
CTYPE_name(CTYPE type)39 const char *CTYPE_name(CTYPE type)
40 {
41 switch (type)
42 {
43 case CTYPE_uint8_t: return "uint8";
44 case CTYPE_uint16_t: return "uint16";
45 case CTYPE_uint32_t: return "uint32";
46 case CTYPE_uint64_t: return "uint64";
47
48 case CTYPE_int8_t: return "int8";
49 case CTYPE_int16_t: return "int16";
50 case CTYPE_int32_t: return "int32";
51 case CTYPE_int64_t: return "int64";
52
53 case CTYPE_float32_t: return "float32";
54 case CTYPE_float64_t: return "float64";
55
56 case CTYPE_uintptr_t: return "intptr";
57 }
58 return "unknown";
59 }
60
CTYPE_forName(const char * name)61 int CTYPE_forName(const char *name)
62 {
63 if(!strcmp(name, "uint8")) return CTYPE_uint8_t;
64 if(!strcmp(name, "uint16")) return CTYPE_uint16_t;
65 if(!strcmp(name, "uint32")) return CTYPE_uint32_t;
66 if(!strcmp(name, "uint64")) return CTYPE_uint64_t;
67 if(!strcmp(name, "int8")) return CTYPE_int8_t;
68 if(!strcmp(name, "int16")) return CTYPE_int16_t;
69 if(!strcmp(name, "int32")) return CTYPE_int32_t;
70 if(!strcmp(name, "int64")) return CTYPE_int64_t;
71 if(!strcmp(name, "float32")) return CTYPE_float32_t;
72 if(!strcmp(name, "float64")) return CTYPE_float64_t;
73 return -1;
74 }
75
CTYPE_fixedWidthTextEncodingForType(CTYPE type)76 int CTYPE_fixedWidthTextEncodingForType(CTYPE type)
77 {
78 if(type == CTYPE_int8_t) return CENCODING_ASCII;
79 if(type == CTYPE_uint16_t) return CENCODING_UCS2;
80 if(type == CTYPE_uint32_t) return CENCODING_UCS4;
81 return -1;
82 }
83
CENCODING_forName(const char * name)84 int CENCODING_forName(const char *name)
85 {
86 if(!strcmp(name, "ascii")) return CENCODING_ASCII;
87 if(!strcmp(name, "utf8")) return CENCODING_UTF8;
88 if(!strcmp(name, "ucs2")) return CENCODING_UCS2;
89 if(!strcmp(name, "ucs4")) return CENCODING_UCS4;
90 if(!strcmp(name, "number")) return CENCODING_NUMBER;
91 return -1;
92 }
93
CENCODING_isText(CENCODING encoding)94 int CENCODING_isText(CENCODING encoding)
95 {
96 return encoding != CENCODING_NUMBER;
97 }
98
CENCODING_name(CENCODING encoding)99 const char *CENCODING_name(CENCODING encoding)
100 {
101 switch (encoding)
102 {
103 case CENCODING_ASCII: return "ascii";
104 case CENCODING_UTF8: return "utf8";
105 case CENCODING_UCS2: return "ucs2";
106 case CENCODING_UCS4: return "ucs4";
107 case CENCODING_NUMBER: return "number";
108 }
109 return "unknown";
110 }
111
112 // error
113
UArray_unsupported_with_(const UArray * self,const char * methodName,const UArray * other)114 void UArray_unsupported_with_(const UArray *self, const char *methodName, const UArray *other)
115 {
116 //UArray_error_(self, "Error: '%s' not supported between '%s' and '%s'\n");
117 printf("Error: '%s' not supported between '%s' and '%s'\n",
118 methodName, CTYPE_name(self->itemType), CTYPE_name(other->itemType));
119 exit(-1);
120 }
121
UArray_error_(const UArray * self,char * e)122 void UArray_error_(const UArray *self, char *e)
123 {
124 printf("%s\n", e);
125 exit(-1);
126 }
127
128 // new
129
UArray_itemType(const UArray * self)130 CTYPE UArray_itemType(const UArray *self)
131 {
132 return self->itemType;
133 }
134
UArray_itemSize(const UArray * self)135 size_t UArray_itemSize(const UArray *self)
136 {
137 return self->itemSize;
138 }
139
140 //inline
UArray_sizeRequiredToContain_(const UArray * self,const UArray * other)141 size_t UArray_sizeRequiredToContain_(const UArray *self, const UArray *other)
142 {
143 return (UArray_sizeInBytes(other) + self->itemSize - 1) / self->itemSize;
144 }
145
UArray_rawSetItemType_(UArray * self,CTYPE type)146 void UArray_rawSetItemType_(UArray *self, CTYPE type)
147 {
148 int itemSize = (int)CTYPE_size(type);
149 self->itemType = type;
150 self->itemSize = itemSize;
151 }
152
UArray_setItemType_(UArray * self,CTYPE type)153 void UArray_setItemType_(UArray *self, CTYPE type)
154 {
155 int itemSize = (int)CTYPE_size(type);
156 div_t q = div((int)UArray_sizeInBytes(self), (int)itemSize);
157
158 if (q.rem != 0)
159 {
160 q.quot += 1;
161 UArray_setSize_(self, (q.quot * itemSize) / self->itemSize);
162 }
163
164 self->itemType = type;
165
166 self->itemSize = itemSize;
167 self->size = q.quot;
168
169 // ensure encoding is sane for type
170
171 if (UArray_isFloatType(self))
172 {
173 self->encoding = CENCODING_NUMBER;
174 }
175 else if (self->encoding == CENCODING_ASCII)
176 {
177 switch(self->itemSize)
178 {
179 case 2: self->encoding = CENCODING_UCS2; break;
180 case 4: self->encoding = CENCODING_UCS4; break;
181 case 8: self->encoding = CENCODING_NUMBER; break;
182 }
183 }
184 }
185
UArray_encoding(const UArray * self)186 CENCODING UArray_encoding(const UArray *self)
187 {
188 return self->encoding;
189 }
190
UArray_setEncoding_(UArray * self,CENCODING encoding)191 void UArray_setEncoding_(UArray *self, CENCODING encoding)
192 {
193 // ensure that size matches new encoding
194
195 switch(encoding)
196 {
197 case CENCODING_ASCII:
198 case CENCODING_UTF8:
199 UArray_setItemType_(self, CTYPE_uint8_t);
200 break;
201 case CENCODING_UCS2:
202 UArray_setItemType_(self, CTYPE_uint16_t);
203 break;
204 case CENCODING_UCS4:
205 UArray_setItemType_(self, CTYPE_uint32_t);
206 break;
207 case CENCODING_NUMBER:
208 // Don't change itemType when setting raw encoding. Raw encoding
209 // used for vectors and numbers and the item type may have been set
210 // before this call.
211 break;
212 }
213
214 self->encoding = encoding;
215 }
216
UArray_convertToEncoding_(UArray * self,CENCODING encoding)217 void UArray_convertToEncoding_(UArray *self, CENCODING encoding)
218 {
219 switch(encoding)
220 {
221 case CENCODING_ASCII:
222 case CENCODING_UTF8:
223 UArray_convertToUTF8(self);
224 break;
225 case CENCODING_UCS2:
226 UArray_convertToUCS2(self);
227 break;
228 case CENCODING_UCS4:
229 UArray_convertToUCS4(self);
230 break;
231 case CENCODING_NUMBER:
232 UArray_setItemType_(self, CTYPE_uint8_t);
233 break;
234 }
235
236 self->encoding = encoding;
237 UArray_changed(self);
238 }
239
UArray_newWithData_type_encoding_size_copy_(void * bytes,CTYPE type,CENCODING encoding,size_t size,int copy)240 UArray *UArray_newWithData_type_encoding_size_copy_(void *bytes, CTYPE type, CENCODING encoding, size_t size, int copy)
241 {
242 UArray *self = (UArray *)io_calloc(1, sizeof(UArray));
243 UArray_setData_type_size_copy_(self, bytes, type, size, copy);
244 self->encoding = encoding;
245 return self;
246 }
247
UArray_newWithData_type_size_copy_(void * bytes,CTYPE type,size_t size,int copy)248 UArray *UArray_newWithData_type_size_copy_(void *bytes, CTYPE type, size_t size, int copy)
249 {
250 UArray *self = (UArray *)io_calloc(1, sizeof(UArray));
251 UArray_setData_type_size_copy_(self, bytes, type, size, copy);
252 self->encoding = CENCODING_ASCII;
253 return self;
254 }
255
UArray_new(void)256 UArray *UArray_new(void)
257 {
258 return UArray_newWithData_type_size_copy_("", CTYPE_uint8_t, 0, 1);
259 }
260
UArray_clone(const UArray * self)261 UArray *UArray_clone(const UArray *self)
262 {
263 UArray *out = UArray_new();
264 UArray_copy_(out, self);
265 return out;
266 }
267
UArray_show(const UArray * self)268 void UArray_show(const UArray *self)
269 {
270 printf("UArray_%p %s\t", (void *)self, CTYPE_name(self->itemType));
271 printf("size: %i ", (int)self->size);
272 printf("itemSize: %i ", (int)self->itemSize);
273 printf("data: ");
274 UArray_print(self);
275 printf("\n");
276 }
277
UArray_print(const UArray * self)278 void UArray_print(const UArray *self)
279 {
280 if(self->encoding == CENCODING_ASCII || self->encoding == CENCODING_UTF8)
281 {
282 fwrite(self->data, self->itemSize, self->size, stdout);
283 }
284 else if(self->encoding != CENCODING_NUMBER)
285 {
286 UARRAY_FOREACH(self, i, v, printf("%c", (int)v); );
287 }
288 else if(UArray_isFloatType(self))
289 {
290 printf("[");
291 UARRAY_FOREACH(self, i, v,
292 printf("%f", (float)v);
293 if(i != self->size - 1) printf(", ");
294 );
295 printf("]");
296 }
297 else
298 {
299 printf("[");
300 UARRAY_FOREACH(self, i, v,
301 printf("%i", (int)v);
302 if(i != self->size - 1) printf(", ");
303 );
304 printf("]");
305 }
306 }
307
UArray_stackAllocedWithData_type_size_(void * data,CTYPE type,size_t size)308 UArray UArray_stackAllocedWithData_type_size_(void *data, CTYPE type, size_t size)
309 {
310 UArray self;
311 memset(&self, 0, sizeof(UArray));
312
313 #ifdef UARRAY_DEBUG
314 self.stackAllocated = 1;
315 #endif
316
317 self.itemType = type;
318 self.itemSize = (int)CTYPE_size(type);
319 self.size = size;
320 self.data = data;
321 return self;
322 }
323
UArray_stackAllocedEmptyUArray(void)324 BASEKIT_API UArray UArray_stackAllocedEmptyUArray(void)
325 {
326 UArray self;
327 memset(&self, 0, sizeof(UArray));
328
329 #ifdef UARRAY_DEBUG
330 self.stackAllocated = 1;
331 #endif
332
333 self.itemType = CTYPE_int32_t;
334 self.itemSize = 4;
335 self.size = 0;
336 self.data = 0x0;
337 return self;
338 }
339
UArray_newWithCString_copy_(char * s,int copy)340 UArray *UArray_newWithCString_copy_(char *s, int copy)
341 {
342 return UArray_newWithData_type_size_copy_(s, CTYPE_uint8_t, strlen(s), copy);
343 }
344
UArray_newWithCString_(const char * s)345 UArray *UArray_newWithCString_(const char *s)
346 {
347 return UArray_newWithData_type_size_copy_((uint8_t *)s, CTYPE_uint8_t, strlen(s), 1);
348 }
349
UArray_empty(UArray * self)350 void UArray_empty(UArray *self)
351 {
352 UArray_setSize_(self, 0);
353 }
354
UArray_setCString_(UArray * self,const char * s)355 void UArray_setCString_(UArray *self, const char *s)
356 {
357 UArray_empty(self);
358 UArray_setItemType_(self, CTYPE_uint8_t);
359 UArray_appendCString_(self, s);
360 }
361
362 #ifdef UARRAY_DEBUG
UArray_checkIfOkToRelloc(UArray * self)363 void UArray_checkIfOkToRelloc(UArray *self)
364 {
365 if(self->stackAllocated)
366 {
367 printf("UArray debug error: attempt to io_realloc UArray data that this UArray does not own");
368 exit(-1);
369 }
370 }
371 #endif
372
UArray_setData_type_size_copy_(UArray * self,void * data,CTYPE type,size_t size,int copy)373 void UArray_setData_type_size_copy_(UArray *self, void *data, CTYPE type, size_t size, int copy)
374 {
375 size_t sizeInBytes;
376
377 UArray_rawSetItemType_(self, type);
378 self->size = size;
379
380 sizeInBytes = self->size * self->itemSize;
381
382 #ifdef UARRAY_DEBUG
383 UArray_checkIfOkToRelloc(self);
384 #endif
385
386 if (copy)
387 {
388 self->data = io_realloc(self->data, sizeInBytes + 1);
389 memmove(self->data, data, sizeInBytes);
390 self->data[sizeInBytes] = 0x0;
391 }
392 else
393 {
394 if(self->data) free(self->data);
395 self->data = data;
396 }
397
398 }
399
UArray_stackAllocedWithCString_(char * s)400 UArray UArray_stackAllocedWithCString_(char *s)
401 {
402 return UArray_stackAllocedWithData_type_size_(s, CTYPE_uint8_t, strlen(s));
403 }
404
UArray_data(const UArray * self)405 const void *UArray_data(const UArray *self)
406 {
407 return self->data;
408 }
409
UArray_bytes(const UArray * self)410 const uint8_t *UArray_bytes(const UArray *self)
411 {
412 return self->data;
413 }
414
UArray_mutableBytes(UArray * self)415 uint8_t *UArray_mutableBytes(UArray *self)
416 {
417 UArray_changed(self);
418 return self->data;
419 }
420
UArray_asCString(const UArray * self)421 const char *UArray_asCString(const UArray *self)
422 {
423 return (const char *)(self->data);
424 }
425
UArray_stackFree(UArray * self)426 void UArray_stackFree(UArray *self)
427 {
428 if(self->data) io_free(self->data);
429 }
430
UArray_free(UArray * self)431 void UArray_free(UArray *self)
432 {
433 if(self->data) io_free(self->data);
434 io_free(self);
435 }
436
437 // size
438
UArray_setSize_(UArray * self,size_t size)439 void UArray_setSize_(UArray *self, size_t size)
440 {
441 if (size != self->size)
442 {
443 size_t oldSizeInBytes = UArray_sizeInBytes(self);
444 size_t newSizeInBytes = self->itemSize * size;
445
446 #ifdef UARRAY_DEBUG
447 UArray_checkIfOkToRelloc(self);
448 #endif
449 self->data = io_realloc(self->data, newSizeInBytes + 1);
450
451
452 self->data[newSizeInBytes] = 0x0;
453 self->size = size;
454
455 if (newSizeInBytes > oldSizeInBytes)
456 {
457 memset(self->data + oldSizeInBytes, 0, newSizeInBytes - oldSizeInBytes);
458 }
459
460 UArray_changed(self);
461 }
462 }
463
UArray_size(const UArray * self)464 size_t UArray_size(const UArray *self)
465 {
466 return self->size;
467 }
468
UArray_sizeInBytes(const UArray * self)469 size_t UArray_sizeInBytes(const UArray *self)
470 {
471 return self->size * self->itemSize;
472 }
473
UArray_sizeTo_(UArray * self,size_t size)474 void UArray_sizeTo_(UArray *self, size_t size)
475 {
476 UArray_setSize_(self, size);
477 }
478
479 // copy
480
UArray_copy_(UArray * self,const UArray * other)481 void UArray_copy_(UArray *self, const UArray *other)
482 {
483 UArray_setItemType_(self, UArray_itemType(other));
484 UArray_setEncoding_(self, UArray_encoding(other));
485 UArray_setSize_(self, UArray_size(other));
486 UArray_copyItems_(self, other);
487 }
488
UArray_copyItems_(UArray * self,const UArray * other)489 void UArray_copyItems_(UArray *self, const UArray *other)
490 {
491 if(self->size != other->size)
492 {
493 printf("UArray_copyItems_ error - arrays not of same size\n");
494 exit(-1);
495 }
496
497 if(self->itemType == other->itemType)
498 {
499 UArray_copyData_(self, other);
500 }
501 else
502 {
503 DUARRAY_OP(UARRAY_BASICOP_TYPES, =, self, other);
504 }
505
506 UArray_changed(self);
507 }
508
UArray_copyData_(UArray * self,const UArray * other)509 void UArray_copyData_(UArray *self, const UArray *other)
510 {
511 UArray_setSize_(self, UArray_sizeRequiredToContain_(self, other));
512 memmove(self->data, other->data, UArray_sizeInBytes(other));
513 }
514
UArray_convertToItemType_(UArray * self,CTYPE newItemType)515 void UArray_convertToItemType_(UArray *self, CTYPE newItemType)
516 {
517 if (self->itemType != newItemType)
518 {
519 UArray *tmp = UArray_new();
520 CENCODING encoding = UArray_encoding(self);
521 UArray_setItemType_(tmp, newItemType);
522
523 if(CENCODING_isText(self->encoding))
524 {
525 encoding = CTYPE_fixedWidthTextEncodingForType(newItemType);
526 }
527
528 UArray_setEncoding_(tmp, encoding);
529 UArray_setSize_(tmp, self->size);
530 UArray_copyItems_(tmp, self);
531 UArray_copy_(self, tmp);
532 UArray_free(tmp);
533 UArray_changed(self);
534 }
535 }
536
537 // slice
538
UArray_stackRange(const UArray * self,size_t start,size_t size)539 UArray UArray_stackRange(const UArray *self, size_t start, size_t size)
540 {
541 UArray s;
542
543 memcpy(&s, self, sizeof(UArray));
544 UArray_changed(&s);
545
546 #ifdef UARRAY_DEBUG
547 s.stackAllocated = 1;
548 #endif
549
550 if(start < self->size || start == 0)
551 {
552 s.data = self->data + self->itemSize * start;
553 }
554 else
555 {
556 s.data = 0x0;
557 }
558
559 if(start + size <= self->size)
560 {
561 s.size = size;
562 }
563 else
564 {
565 s.size = 0;
566 }
567
568 return s;
569 }
570
UArray_range(const UArray * self,size_t start,size_t size)571 UArray *UArray_range(const UArray *self, size_t start, size_t size)
572 {
573 UArray out = UArray_stackRange(self, start, size);
574 return UArray_clone(&out);
575 }
576
UArray_stackSlice(const UArray * self,long start,long end)577 UArray UArray_stackSlice(const UArray *self, long start, long end)
578 {
579 start = UArray_wrapPos_(self, start);
580 end = UArray_wrapPos_(self, end);
581 if (end < start) end = start;
582 return UArray_stackRange(self, start, end - start);
583 }
584
UArray_slice(const UArray * self,long start,long end)585 BASEKIT_API UArray *UArray_slice(const UArray *self, long start, long end)
586 {
587 UArray out = UArray_stackSlice(self, start, end);
588 return UArray_clone(&out);
589 }
590
591 // at, without bounds check
592
UArray_rawPointerAt_(const UArray * self,size_t i)593 void *UArray_rawPointerAt_(const UArray *self, size_t i)
594 {
595 if (self->itemType == CTYPE_uintptr_t)
596 {
597 return ((void **)self->data)[i];
598 }
599
600 UArray_error_(self, "UArray_rawPointerAt_ not supported on this type");
601 return NULL;
602 }
603
UArray_rawLongAt_(const UArray * self,size_t i)604 long UArray_rawLongAt_(const UArray *self, size_t i)
605 {
606 UARRAY_RAWAT_(self, i);
607 UArray_error_(self, "UArray_rawLongAt_ not supported on this type");
608 return 0;
609 }
610
UArray_rawDoubleAt_(const UArray * self,size_t i)611 double UArray_rawDoubleAt_(const UArray *self, size_t i)
612 {
613 UARRAY_RAWAT_(self, i);
614 UArray_error_(self, "UArray_doubleAt_ not supported on this type");
615 return 0;
616 }
617
618 // at, with bounds check
619
UArray_pointerAt_(const UArray * self,size_t i)620 void *UArray_pointerAt_(const UArray *self, size_t i)
621 {
622 if (i >= self->size) { return NULL; }
623 return UArray_rawPointerAt_(self, i);
624 }
625
UArray_longAt_(const UArray * self,size_t i)626 long UArray_longAt_(const UArray *self, size_t i)
627 {
628 if (i >= self->size) { return 0; }
629 return UArray_rawLongAt_(self, i);
630 }
631
UArray_doubleAt_(const UArray * self,size_t i)632 double UArray_doubleAt_(const UArray *self, size_t i)
633 {
634 if (i >= self->size) { return 0.0; }
635 return UArray_rawDoubleAt_(self, i);
636 }
637
638 // at, extras
639
UArray_firstLong(const UArray * self)640 long UArray_firstLong(const UArray *self)
641 {
642 return UArray_rawLongAt_(self, 0);
643 }
644
UArray_lastLong(const UArray * self)645 long UArray_lastLong(const UArray *self)
646 {
647 if (!self->size)
648 {
649 return 0;
650 }
651
652 return UArray_rawLongAt_(self, self->size - 1);
653 }
654
655 // remove
656
UArray_removeRange(UArray * self,size_t start,size_t removeSize)657 void UArray_removeRange(UArray *self, size_t start, size_t removeSize)
658 {
659 if (start < self->size)
660 {
661 if (start + removeSize > self->size)
662 {
663 removeSize = self->size - start;
664 }
665 else if (start + removeSize < self->size)
666 {
667 // need to copy end
668 size_t remainder = start + removeSize;
669 size_t remainderSize = self->size - remainder;
670 memmove(UARRAY_BYTESAT_(self, start), UARRAY_BYTESAT_(self, remainder), self -> itemSize * remainderSize);
671 }
672
673 UArray_setSize_(self, self->size - removeSize);
674 }
675 UArray_changed(self);
676 }
677
UArray_leave_thenRemove_(UArray * self,size_t itemsToLeave,size_t itemsToRemove)678 void UArray_leave_thenRemove_(UArray *self, size_t itemsToLeave, size_t itemsToRemove)
679 {
680 if (itemsToLeave <= 0)
681 {
682 UArray_clear(self);
683 UArray_setSize_(self, 0);
684 return;
685 }
686
687 if (itemsToRemove <= 0)
688 {
689 return;
690 }
691
692 {
693 size_t tailChunkSizeInBytes;
694
695 size_t period = itemsToLeave + itemsToRemove;
696 size_t tailItemCount = UArray_size(self) % period;
697 size_t itemSize = self->itemSize;
698 size_t chunkSizeInBytes = itemSize * itemsToLeave;
699
700 if (tailItemCount == 0)
701 {
702 tailChunkSizeInBytes = 0;
703 }
704 else if (tailItemCount <= itemsToLeave)
705 {
706 tailChunkSizeInBytes = tailItemCount * itemSize;
707 }
708 else
709 {
710 tailChunkSizeInBytes = chunkSizeInBytes;
711 }
712
713 {
714 size_t chunkCount = UArray_size(self) / period;
715 size_t newItemCount = chunkCount * itemsToLeave + tailChunkSizeInBytes / itemSize;
716 uint8_t *newData = malloc(newItemCount * itemSize);
717
718 {
719 size_t chunkPos;
720
721 for (chunkPos = 0; chunkPos < chunkCount; chunkPos++)
722 {
723 memmove(newData + chunkPos * chunkSizeInBytes, UARRAY_BYTESAT_(self, chunkPos * period), chunkSizeInBytes);
724 }
725
726 if (tailChunkSizeInBytes)
727 {
728 memmove(newData + chunkPos * chunkSizeInBytes, UARRAY_BYTESAT_(self, chunkPos * period), tailChunkSizeInBytes);
729 }
730
731 UArray_setData_type_size_copy_(self, newData, UArray_itemType(self), newItemCount, 0);
732 UArray_changed(self);
733 }
734 }
735 }
736 }
737
UArray_removeFirst(UArray * self)738 BASEKIT_API void UArray_removeFirst(UArray *self)
739 {
740 UArray_removeRange(self, 0, 1);
741 }
742
UArray_removeLast(UArray * self)743 BASEKIT_API void UArray_removeLast(UArray *self)
744 {
745 if (self->size > 0)
746 {
747 UArray_setSize_(self, self->size - 1);
748 }
749 }
750
751 // insert
752
753 #define UARRAY_RAWAT_PUT_(self, pos, v) \
754 switch (self->itemType)\
755 {\
756 case CTYPE_uint8_t: ((uint8_t *)self->data)[pos] = v; return;\
757 case CTYPE_uint16_t: ((uint16_t *)self->data)[pos] = v; return;\
758 case CTYPE_uint32_t: ((uint32_t *)self->data)[pos] = v; return;\
759 case CTYPE_uint64_t: ((uint64_t *)self->data)[pos] = v; return;\
760 case CTYPE_int8_t: ((int8_t *)self->data)[pos] = v; return;\
761 case CTYPE_int16_t: ((int16_t *)self->data)[pos] = v; return;\
762 case CTYPE_int32_t: ((int32_t *)self->data)[pos] = v; return;\
763 case CTYPE_int64_t: ((int64_t *)self->data)[pos] = v; return;\
764 case CTYPE_float32_t: ((float32_t *)self->data)[pos] = v; return;\
765 case CTYPE_float64_t: ((float64_t *)self->data)[pos] = v; return;\
766 case CTYPE_uintptr_t: ((uintptr_t *)self->data)[pos] = v; return;\
767 }
768
UArray_at_putLong_(UArray * self,size_t pos,long v)769 void UArray_at_putLong_(UArray *self, size_t pos, long v)
770 {
771 if (pos >= self->size)
772 {
773 UArray_setSize_(self, pos + 1);
774 }
775
776 //if(UArray_longAt_(self, pos) != v)
777 {
778 UARRAY_RAWAT_PUT_(self, pos, (uint32_t)v);
779 UArray_changed(self);
780 }
781 }
782
UArray_at_putDouble_(UArray * self,size_t pos,double v)783 void UArray_at_putDouble_(UArray *self, size_t pos, double v)
784 {
785 if(pos >= self->size) UArray_setSize_(self, pos + 1);
786
787 //if(UArray_doubleAt_(self, pos) != v)
788 {
789 UARRAY_RAWAT_PUT_(self, pos, v);
790 UArray_changed(self);
791 }
792 }
793
UArray_at_putPointer_(UArray * self,size_t pos,void * v)794 void UArray_at_putPointer_(UArray *self, size_t pos, void *v)
795 {
796 if (pos >= self->size) UArray_setSize_(self, pos + 1);
797
798 switch (self->itemType)
799 {
800 case CTYPE_uintptr_t:
801 if(((void **)self->data)[pos] != v)
802 {
803 ((void **)self->data)[pos] = v;
804 UArray_changed(self);
805 }
806 return;
807 default:
808 UArray_error_(self, "UArray_at_putPointer_ not supported with this type");
809 }
810
811 //UArray_error_(self, "UArray_at_putPointer_ not supported with this type");
812 }
813
UArray_appendLong_(UArray * self,long v)814 void UArray_appendLong_(UArray *self, long v)
815 {
816 UArray_at_putLong_(self, self->size, v);
817 }
818
UArray_appendDouble_(UArray * self,double v)819 void UArray_appendDouble_(UArray *self, double v)
820 {
821 UArray_at_putDouble_(self, self->size, v);
822 }
823
UArray_appendPointer_(UArray * self,void * v)824 void UArray_appendPointer_(UArray *self, void *v)
825 {
826 UArray_at_putPointer_(self, self->size, v);
827 }
828
UArray_appendBytes_size_(UArray * self,const uint8_t * bytes,size_t size)829 void UArray_appendBytes_size_(UArray *self, const uint8_t *bytes, size_t size)
830 {
831 UArray a = UArray_stackAllocedWithData_type_size_((uint8_t *)bytes, CTYPE_uint8_t, size);
832 UArray_append_(self, &a);
833 }
834
835 /*
836 void UArray_appendByte_(UArray *self, uint8_t byte)
837 {
838 UArray a = UArray_stackAllocedWithData_type_size_(&byte, CTYPE_uint8_t, 1);
839 UArray_append_(self, &a);
840 }
841 */
842
UArray_insert_every_(UArray * self,UArray * other,size_t itemCount)843 void UArray_insert_every_(UArray *self, UArray *other, size_t itemCount)
844 {
845 UArray *out = UArray_new();
846 UArray *convertedOther = other;
847
848 if (itemCount == 0)
849 {
850 UArray_error_(self, "UArray_insert_every_: itemCount must be > 0");
851 return;
852 }
853
854 if(UArray_itemType(self) != UArray_itemType(other))
855 {
856 UArray *convertedOther = UArray_clone(other);
857 UArray_convertToItemType_(convertedOther, UArray_itemType(self));
858 }
859
860 {
861 size_t selfSizeInBytes = UArray_sizeInBytes(self);
862 size_t otherSize = UArray_size(convertedOther);
863 size_t chunkSize = itemCount * UArray_itemSize(self);
864 size_t i;
865
866 for(i = 0; i < selfSizeInBytes; i += chunkSize)
867 {
868 if (i + chunkSize > selfSizeInBytes)
869 {
870 UArray_appendBytes_size_(out, self->data + i, selfSizeInBytes - i);
871 }
872 else
873 {
874 UArray_appendBytes_size_(out, self->data + i, chunkSize);
875 UArray_appendBytes_size_(out, convertedOther->data, otherSize);
876 }
877 }
878 }
879
880 if(UArray_itemType(self) != UArray_itemType(other))
881 {
882 UArray_free(convertedOther);
883 }
884
885 UArray_copy_(self, out);
886 UArray_free(out);
887 }
888
UArray_at_putAll_(UArray * self,size_t pos,const UArray * other)889 void UArray_at_putAll_(UArray *self, size_t pos, const UArray *other)
890 {
891 if (other->size == 0) return;
892
893 if (pos > self->size)
894 {
895 UArray_setSize_(self, pos);
896 }
897
898 {
899 size_t chunkSize = self->size - pos;
900 size_t originalSelfSize = self->size;
901
902 UArray_setSize_(self, self->size + other->size);
903
904 {
905 UArray oldChunk = UArray_stackRange(self, pos, chunkSize);
906 UArray newChunk = UArray_stackRange(self, pos + other->size, chunkSize);
907 UArray insertChunk = UArray_stackRange(self, pos, other->size);
908
909 if (
910 //(&newChunk)->data == 0x0 ||
911 (&insertChunk)->data == 0x0)
912 {
913 printf("oldChunk.data %p size %i\n", (void *)(&oldChunk)->data, (int)oldChunk.size);
914 printf("newChunk.data %p size %i\n", (void *)(&newChunk)->data, (int)newChunk.size);
915 printf("insertChunk.data %p size %i\n", (void *)(&insertChunk)->data, (int)insertChunk.size);
916 printf("originalSelfSize = %i\n", (int)originalSelfSize);
917 printf("self->size = %i\n", (int)self->size);
918 printf("other->size = %i\n", (int)other->size);
919 printf("pos = %i\n", (int)pos);
920 //exit(-1);
921
922 oldChunk = UArray_stackRange(self, pos, chunkSize);
923 newChunk = UArray_stackRange(self, pos + other->size, chunkSize);
924 insertChunk = UArray_stackRange(self, pos, other->size);
925 return;
926 }
927
928 if (newChunk.size) //UArray_copy_(&newChunk, &oldChunk); // copy chunk to end
929 UArray_copyItems_(&newChunk, &oldChunk);
930 //UArray_copy_(&insertChunk, other); // insert other
931 UArray_copyItems_(&insertChunk, other);
932 }
933
934 UArray_changed(self);
935 }
936 }
937
938 // compare
939
940 #define UARRAY_COMPARE_TYPES(OP2, TYPE1, self, TYPE2, other)\
941 {\
942 size_t i, minSize = self->size < other->size ? self->size : other->size;\
943 for(i = 0; i < minSize; i ++)\
944 {\
945 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
946 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
947 if (v1 > v2) return 1;\
948 if (v1 < v2) return -1;\
949 }\
950 if(self->size != other->size)\
951 {\
952 return self->size < other->size ? -1 : 1;\
953 }\
954 return 0;\
955 }
956
957 #define UARRAY_EQ_TYPES(OP2, TYPE1, self, TYPE2, other)\
958 {\
959 size_t i, minSize = self->size < other->size ? self->size : other->size;\
960 for(i = 0; i < minSize; i ++)\
961 {\
962 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
963 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
964 if (v1 != v2) return 0;\
965 }\
966 return 1;\
967 }
968
969 #define UARRAY_GT_TYPES(OP2, TYPE1, self, TYPE2, other)\
970 {\
971 size_t i, minSize = self->size < other->size ? self->size : other->size;\
972 for(i = 0; i < minSize; i ++)\
973 {\
974 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
975 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
976 if (v1 < v2) return 0;\
977 }\
978 return 1;\
979 }
980
981 #define UARRAY_LT_TYPES(OP2, TYPE1, self, TYPE2, other)\
982 {\
983 size_t i, minSize = self->size < other->size ? self->size : other->size;\
984 for(i = 0; i < minSize; i ++)\
985 {\
986 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
987 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
988 if (v1 > v2) return 0;\
989 }\
990 return 1;\
991 }
992
UArray_compare_(const UArray * self,const UArray * other)993 int UArray_compare_(const UArray *self, const UArray *other)
994 {
995 if(self->itemType == CTYPE_uint32_t && other->itemType == CTYPE_uint8_t)
996 {
997 size_t i, minSize = self->size < other->size ? self->size : other->size;
998 for(i = 0; i < minSize; i ++)
999 {
1000 uint32_t v1 = ((uint32_t *)self->data)[i];
1001 uint8_t v2 = ((uint8_t *)other->data)[i];
1002 if (v1 > v2) return 1;
1003 if (v1 < v2) return -1;
1004 }
1005 if(self->size != other->size)
1006 {
1007 return self->size < other->size ? -1 : 1;
1008 }
1009 }
1010 else
1011 {
1012 DUARRAY_OP(UARRAY_COMPARE_TYPES, NULL, self, other);
1013 }
1014
1015 return 0;
1016 }
1017
UArray_equals_(const UArray * self,const UArray * other)1018 int UArray_equals_(const UArray *self, const UArray *other)
1019 {
1020 if (self->size != other->size) return 0;
1021 DUARRAY_OP(UARRAY_EQ_TYPES, NULL, self, other);
1022 return 0;
1023 }
1024
UArray_greaterThan_(const UArray * self,const UArray * other)1025 int UArray_greaterThan_(const UArray *self, const UArray *other)
1026 {
1027 if(self->encoding == CENCODING_NUMBER)
1028 { DUARRAY_OP(UARRAY_GT_TYPES, NULL, self, other); }
1029
1030 return UArray_compare_(self, other) > 0;
1031 }
1032
UArray_lessThan_(const UArray * self,const UArray * other)1033 int UArray_lessThan_(const UArray *self, const UArray *other)
1034 {
1035 if(self->encoding == CENCODING_NUMBER)
1036 { DUARRAY_OP(UARRAY_LT_TYPES, NULL, self, other); }
1037
1038 return UArray_compare_(self, other) < 0;
1039 }
1040
UArray_greaterThanOrEqualTo_(const UArray * self,const UArray * other)1041 int UArray_greaterThanOrEqualTo_(const UArray *self, const UArray *other)
1042 {
1043 if(self->encoding == CENCODING_NUMBER)
1044 {
1045 if (UArray_greaterThan_(self, other) | UArray_equals_(self, other))
1046 { return 1; } else { return 0; }
1047 }
1048
1049 return UArray_compare_(self, other) >= 0;
1050 }
1051
UArray_lessThanOrEqualTo_(const UArray * self,const UArray * other)1052 int UArray_lessThanOrEqualTo_(const UArray *self, const UArray *other)
1053 {
1054 if(self->encoding == CENCODING_NUMBER)
1055 {
1056 if (UArray_lessThan_(self, other) | UArray_equals_(self, other))
1057 { return 1; } else { return 0; }
1058 }
1059
1060 return UArray_compare_(self, other) <= 0;
1061 }
1062
UArray_isZero(const UArray * self)1063 int UArray_isZero(const UArray *self)
1064 {
1065 UARRAY_FOREACH(self, i, v, if (v) return 0;)
1066 return 1;
1067 }
1068
1069 // find
1070
1071 // printf("i %i %c j %i %c\n", i, v1, j, v2);\
1072 // printf("j%i == %i\n", i, other->size);\
1073
1074 #define UARRAY_FIND_TYPES(OP2, TYPE1, self, TYPE2, other)\
1075 {\
1076 size_t i;\
1077 if((self->size < other->size) || (self->size == 0)) return -1;\
1078 for(i = 0; i < self->size - other->size + 1; i ++)\
1079 {\
1080 size_t j;\
1081 int match = 1;\
1082 for(j = 0; j < other->size; j ++)\
1083 {\
1084 TYPE1 v1 = ((TYPE1 *)self->data)[i + j];\
1085 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
1086 if (v1 != v2) { match = 0; break; }\
1087 }\
1088 if (match) return i;\
1089 }\
1090 return -1;\
1091 }
1092
UArray_find_(const UArray * self,const UArray * other)1093 long UArray_find_(const UArray *self, const UArray *other)
1094 {
1095 DUARRAY_OP(UARRAY_FIND_TYPES, NULL, self, other);
1096 return -1;
1097 }
1098
UArray_contains_(const UArray * self,const UArray * other)1099 int UArray_contains_(const UArray *self, const UArray *other)
1100 {
1101 return UArray_find_(self, other) != -1;
1102 }
1103
UArray_find_from_(const UArray * self,const UArray * other,size_t from)1104 long UArray_find_from_(const UArray *self, const UArray *other, size_t from)
1105 {
1106 UArray s;
1107 long i;
1108 if (self->size < from) return -1;
1109 s = UArray_stackRange(self, from, self->size - from);
1110 i = UArray_find_(&s, other);
1111 return i == -1 ? -1 : from + i;
1112 }
1113
1114 #define UARRAY_FINDANYCASE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1115 {\
1116 size_t i;\
1117 if(self->size < other->size) return -1;\
1118 for(i = 0; i < self->size - other->size + 1; i ++)\
1119 {\
1120 size_t j;\
1121 int match = 1;\
1122 for(j = 0; j < other->size; j ++)\
1123 {\
1124 TYPE1 v1 = ((TYPE1 *)self->data)[i + j];\
1125 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
1126 if (tolower((int)v1) != tolower((int)v2)) { match = 0; break; }\
1127 }\
1128 if(match) { return i; }\
1129 }\
1130 return -1;\
1131 }
1132
UArray_findAnyCase_(const UArray * self,const UArray * other)1133 long UArray_findAnyCase_(const UArray *self, const UArray *other)
1134 {
1135 DUARRAY_OP(UARRAY_FINDANYCASE_TYPES, NULL, self, other);
1136 return -1;
1137 }
1138
UArray_containsAnyCase_(const UArray * self,const UArray * other)1139 int UArray_containsAnyCase_(const UArray *self, const UArray *other)
1140 {
1141 long i = UArray_findAnyCase_(self, other);
1142 return i != -1;
1143 }
1144
UArray_findLongValue_(const UArray * self,long value)1145 long UArray_findLongValue_(const UArray *self, long value)
1146 {
1147 UARRAY_FOREACH(self, i, v, if(v == value) return i);
1148 return -1;
1149 }
1150
UArray_containsLong_(const UArray * self,long value)1151 int UArray_containsLong_(const UArray *self, long value)
1152 {
1153 return UArray_findLongValue_(self, value) != -1;
1154 }
1155
UArray_findDoubleValue_(const UArray * self,double value)1156 long UArray_findDoubleValue_(const UArray *self, double value)
1157 {
1158 UARRAY_FOREACH(self, i, v, if(v == value) return i);
1159 return -1;
1160 }
1161
UArray_containsDouble_(const UArray * self,double value)1162 int UArray_containsDouble_(const UArray *self, double value)
1163 {
1164 return UArray_findDoubleValue_(self, value) != -1;
1165 }
1166
1167 #define UARRAY_RFIND_TYPES(OP2, TYPE1, self, TYPE2, other)\
1168 {\
1169 long i, j;\
1170 if(self->size < other->size) return -1;\
1171 for(i = self->size - other->size + 1; i > -1; i --)\
1172 {\
1173 int match = 1;\
1174 for(j = 0; j < other->size; j ++)\
1175 {\
1176 TYPE1 v1 = ((TYPE1 *)self->data)[i+j];\
1177 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
1178 if (v1 != v2) { match = 0; break; }\
1179 }\
1180 if(match) { return i;}\
1181 }\
1182 return -1;\
1183 }
1184
UArray_rFind_(const UArray * self,const UArray * other)1185 long UArray_rFind_(const UArray *self, const UArray *other)
1186 {
1187 DUARRAY_OP(UARRAY_RFIND_TYPES, NULL, self, other);
1188 return -1;
1189 }
1190
UArray_rFind_from_(const UArray * self,const UArray * other,size_t from)1191 BASEKIT_API long UArray_rFind_from_(const UArray *self, const UArray *other, size_t from)
1192 {
1193 UArray s = UArray_stackRange(self, 0, from);
1194 long i = UArray_rFind_(&s, other);
1195 return i;
1196 }
1197
1198 #define UARRAY_RFINDANYCASE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1199 {\
1200 size_t i, j;\
1201 if(self->size < other->size) return -1;\
1202 for(i = self->size - other->size + 1; i > -1; i --)\
1203 {\
1204 int match = 1;\
1205 for(j = 0; j < other->size; j ++)\
1206 {\
1207 int v1 = (int)((TYPE1 *)self->data)[i+j];\
1208 int v2 = (int)((TYPE2 *)other->data)[j];\
1209 if (tolower(v1) != tolower(v2)) { match = 0; break; }\
1210 }\
1211 if(match) return i;\
1212 }\
1213 return -1;\
1214 }
1215
UArray_rFindAnyCase_(const UArray * self,const UArray * other)1216 long UArray_rFindAnyCase_(const UArray *self, const UArray *other)
1217 {
1218 DUARRAY_OP(UARRAY_RFINDANYCASE_TYPES, NULL, self, other);
1219 return -1;
1220 }
1221
1222 #define UARRAY_RFINDANYVALUE_TYPES(OP2, TYPE1, self, TYPE2, other)\
1223 {\
1224 long i, j;\
1225 if(self->size < other->size) return -1;\
1226 for(i = self->size - 1; i > -1; i --)\
1227 {\
1228 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
1229 for(j = 0; j < other->size; j ++)\
1230 {\
1231 TYPE2 v2 = ((TYPE2 *)other->data)[j];\
1232 if (v1 == v2) { return i; }\
1233 }\
1234 }\
1235 return -1;\
1236 }
1237
UArray_rFindAnyValue_(const UArray * self,const UArray * other)1238 long UArray_rFindAnyValue_(const UArray *self, const UArray *other)
1239 {
1240 DUARRAY_OP(UARRAY_RFINDANYVALUE_TYPES, NULL, self, other);
1241 return -1;
1242 }
1243
1244 // types
1245
UArray_isFloatType(const UArray * self)1246 int UArray_isFloatType(const UArray *self)
1247 {
1248 return self->itemType == CTYPE_float32_t || self->itemType == CTYPE_float64_t;
1249 }
1250
UArray_isSignedType(const UArray * self)1251 int UArray_isSignedType(const UArray *self)
1252 {
1253 switch (self->itemType)
1254 {
1255 case CTYPE_uint8_t: return 0;
1256 case CTYPE_uint16_t: return 0;
1257 case CTYPE_uint32_t: return 0;
1258 case CTYPE_uint64_t: return 0;
1259 case CTYPE_int8_t: return 1;
1260 case CTYPE_int16_t: return 1;
1261 case CTYPE_int32_t: return 1;
1262 case CTYPE_int64_t: return 1;
1263 case CTYPE_float32_t: return 1;
1264 case CTYPE_float64_t: return 1;
1265 case CTYPE_uintptr_t: return 0;
1266 }
1267 return 0;
1268 }
1269
UArray_wrapPos_(const UArray * self,long pos)1270 size_t UArray_wrapPos_(const UArray *self, long pos)
1271 {
1272 long size = self->size;
1273
1274 if (pos > size - 1)
1275 {
1276 return size;
1277 }
1278
1279 if (pos < 0)
1280 {
1281 pos = size + pos;
1282
1283 if (pos < 0)
1284 {
1285 pos = 0;
1286 }
1287 }
1288
1289 return pos;
1290 }
1291
cmp_uint8_t(const uint8_t * a,const uint8_t * b)1292 int cmp_uint8_t (const uint8_t *a, const uint8_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_uint16_t(const uint16_t * a,const uint16_t * b)1293 int cmp_uint16_t(const uint16_t *a, const uint16_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_uint32_t(const uint32_t * a,const uint32_t * b)1294 int cmp_uint32_t(const uint32_t *a, const uint32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_uint64_t(const uint64_t * a,const uint64_t * b)1295 int cmp_uint64_t(const uint64_t *a, const uint64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1296
cmp_int8_t(const int8_t * a,const int8_t * b)1297 int cmp_int8_t (const int8_t *a, const int8_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_int16_t(const int16_t * a,const int16_t * b)1298 int cmp_int16_t(const int16_t *a, const int16_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_int32_t(const int32_t * a,const int32_t * b)1299 int cmp_int32_t(const int32_t *a, const int32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_int64_t(const int64_t * a,const int64_t * b)1300 int cmp_int64_t(const int64_t *a, const int64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1301
cmp_float32_t(const float32_t * a,const float32_t * b)1302 int cmp_float32_t(const float32_t *a, const float32_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_float64_t(const float64_t * a,const float64_t * b)1303 int cmp_float64_t(const float64_t *a, const float64_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
cmp_uintptr_t(const uintptr_t * a,const uintptr_t * b)1304 int cmp_uintptr_t(const uintptr_t *a, const uintptr_t *b) { return *a == *b ? 0 : (*a < *b ? -1 : 1); }
1305
UArray_sort(UArray * self)1306 void UArray_sort(UArray *self)
1307 {
1308 void *base = self->data;
1309 size_t size = self->size;
1310
1311 UArray_changed(self);
1312
1313 switch(self->itemType)
1314 {
1315 case CTYPE_uint8_t: qsort(base, size, sizeof(uint8_t), (UArraySortCallback *)cmp_uint8_t); return;
1316 case CTYPE_uint16_t: qsort(base, size, sizeof(uint16_t), (UArraySortCallback *)cmp_uint16_t); return;
1317 case CTYPE_uint32_t: qsort(base, size, sizeof(uint32_t), (UArraySortCallback *)cmp_uint32_t); return;
1318 case CTYPE_uint64_t: qsort(base, size, sizeof(uint64_t), (UArraySortCallback *)cmp_uint64_t); return;
1319
1320 case CTYPE_int8_t: qsort(base, size, sizeof(int8_t), (UArraySortCallback *)cmp_int8_t); return;
1321 case CTYPE_int16_t: qsort(base, size, sizeof(int16_t), (UArraySortCallback *)cmp_int16_t); return;
1322 case CTYPE_int32_t: qsort(base, size, sizeof(int32_t), (UArraySortCallback *)cmp_int32_t); return;
1323 case CTYPE_int64_t: qsort(base, size, sizeof(int64_t), (UArraySortCallback *)cmp_int64_t); return;
1324
1325 case CTYPE_float32_t: qsort(base, size, sizeof(float32_t), (UArraySortCallback *)cmp_float32_t); return;
1326 case CTYPE_float64_t: qsort(base, size, sizeof(float64_t), (UArraySortCallback *)cmp_float64_t); return;
1327 case CTYPE_uintptr_t: qsort(base, size, sizeof(uintptr_t), (UArraySortCallback *)cmp_uintptr_t); return;
1328 }
1329 }
1330
UArray_sortBy_(UArray * self,UArraySortCallback * cmp)1331 void UArray_sortBy_(UArray *self, UArraySortCallback *cmp)
1332 {
1333 void *base = self->data;
1334 size_t size = self->size;
1335
1336 UArray_changed(self);
1337
1338 switch(self->itemType)
1339 {
1340 case CTYPE_uint8_t: qsort(base, size, sizeof(uint8_t), cmp); return;
1341 case CTYPE_uint16_t: qsort(base, size, sizeof(uint16_t), cmp); return;
1342 case CTYPE_uint32_t: qsort(base, size, sizeof(uint32_t), cmp); return;
1343 case CTYPE_uint64_t: qsort(base, size, sizeof(uint64_t), cmp); return;
1344
1345 case CTYPE_int8_t: qsort(base, size, sizeof(int8_t), cmp); return;
1346 case CTYPE_int16_t: qsort(base, size, sizeof(int16_t), cmp); return;
1347 case CTYPE_int32_t: qsort(base, size, sizeof(int32_t), cmp); return;
1348 case CTYPE_int64_t: qsort(base, size, sizeof(int64_t), cmp); return;
1349
1350 case CTYPE_float32_t: qsort(base, size, sizeof(float32_t), cmp); return;
1351 case CTYPE_float64_t: qsort(base, size, sizeof(float64_t), cmp); return;
1352 case CTYPE_uintptr_t: qsort(base, size, sizeof(uintptr_t), cmp); return;
1353 }
1354 }
1355
1356
1357