2 copyright: Steve Dekorte, 2006. All rights reserved.
3 license: See _BSDLicense.txt.
12 void UArray_append_(UArray
*self
, const UArray
*other
)
14 UArray_at_putAll_(self
, self
->size
, other
);
17 void UArray_appendCString_(UArray
*self
, const char *s
)
21 UArray_appendLong_(self
, *s
);
26 void UArray_prepend_(UArray
*self
, const UArray
*other
)
28 UArray_at_putAll_(self
, 0, other
);
31 int UArray_equalsAnyCase_(const UArray
*self
, const UArray
*other
)
33 if (self
->size
== other
->size
)
35 return UArray_findAnyCase_(self
, other
) == 0;
41 void UArray_replace_with_(UArray
*self
, const UArray
*a1
, const UArray
*a2
)
45 UArray visible
= UArray_stackRange(self
, start
, self
->size
);
47 while ((i
= UArray_find_(&visible
, a1
)) != -1)
49 size_t index
= start
+ i
;
50 UArray_removeRange(self
, index
, a1
->size
);
51 UArray_at_putAll_(self
, index
, a2
);
52 start
= index
+ a2
->size
;
53 visible
= UArray_stackRange(self
, start
, self
->size
- start
);
58 BASEKIT_API
void UArray_replaceCString_withCString_(UArray
*self
, const char *s1
, const char *s2
)
60 UArray a1
= UArray_stackAllocedWithCString_((char *)s1
);
61 UArray a2
= UArray_stackAllocedWithCString_((char *)s2
);
62 UArray_replace_with_(self
, &a1
, &a2
);
65 void UArray_replaceAnyCase_with_(UArray
*self
, const UArray
*a1
, const UArray
*a2
)
69 UArray visible
= UArray_stackRange(self
, start
, self
->size
);
71 while ((i
= UArray_findAnyCase_(&visible
, a1
)) != -1)
73 size_t index
= start
+ i
;
74 UArray_removeRange(self
, index
, a1
->size
);
75 UArray_at_putAll_(self
, index
, a2
);
76 start
= index
+ a2
->size
;
77 visible
= UArray_stackRange(self
, start
, self
->size
- start
);
83 BASEKIT_API
void UArray_remove_(UArray
*self
, const UArray
*a1
)
85 UArray blank
= UArray_stackAllocedEmptyUArray();
86 UArray_replace_with_(self
, a1
, &blank
);
89 BASEKIT_API
void UArray_removeAnyCase_(UArray
*self
, const UArray
*a1
)
91 UArray blank
= UArray_stackAllocedEmptyUArray();
92 UArray_replaceAnyCase_with_(self
, a1
, &blank
);
97 BASEKIT_API
int UArray_clipBefore_(UArray
*self
, const UArray
*other
)
99 long index
= UArray_find_(self
, other
);
103 UArray_removeRange(self
, 0, index
);
110 BASEKIT_API
int UArray_clipBeforeEndOf_(UArray
*self
, const UArray
*other
)
112 long index
= UArray_find_(self
, other
);
116 UArray_removeRange(self
, 0, index
+ other
->size
);
123 BASEKIT_API
int UArray_clipAfter_(UArray
*self
, const UArray
*other
)
125 long index
= UArray_find_(self
, other
);
129 UArray_removeRange(self
, index
+ other
->size
, self
->size
);
136 BASEKIT_API
int UArray_clipAfterStartOf_(UArray
*self
, const UArray
*other
)
138 long index
= UArray_find_(self
, other
);
142 UArray_removeRange(self
, index
, self
->size
);
151 void UArray_lstrip_(UArray
*self
, const UArray
*other
)
155 if (UArray_isFloatType(self
))
157 UARRAY_FOREACH(self
, i
, v
, index
= i
; if (!UArray_containsDouble_(other
, v
)) break; )
161 UARRAY_FOREACH(self
, i
, v
, index
= i
; if (!UArray_containsLong_(other
, v
)) break; )
164 UArray_removeRange(self
, 0, index
);
167 void UArray_rstrip_(UArray
*self
, const UArray
*other
)
171 size_t index
= self
->size
- 1;
173 if (UArray_isFloatType(self
))
175 UARRAY_RFOREACH(self
, i
, v
, index
= i
; if (!UArray_containsDouble_(other
, v
)) break; )
179 UARRAY_RFOREACH(self
, i
, v
, index
= i
; if (!UArray_containsLong_(other
, v
)) break; )
182 UArray_removeRange(self
, index
+ 1, self
->size
);
186 BASEKIT_API
void UArray_strip_(UArray
*self
, const UArray
*other
)
188 UArray_lstrip_(self
, other
);
189 UArray_rstrip_(self
, other
);
194 BASEKIT_API
void UArray_swapIndex_withIndex_(UArray
*self
, size_t i
, size_t j
)
196 int itemSize
= self
->itemSize
;
197 uint8_t *data
= self
->data
;
198 void *ip
= data
+ i
* itemSize
;
199 void *jp
= data
+ j
* itemSize
;
202 memcpy(&b
, ip
, sizeof(UArray
));
203 memcpy(ip
, jp
, sizeof(UArray
));
204 memcpy(jp
, &b
, sizeof(UArray
));
205 UArray_changed(self
);
210 BASEKIT_API
void UArray_reverse(UArray
*self
)
213 long j
= self
->size
- 1;
215 int itemSize
= self
->itemSize
;
216 uint8_t *data
= self
->data
;
220 void *ip
= data
+ i
* itemSize
;
221 void *jp
= data
+ j
* itemSize
;
223 memcpy(&b
, ip
, itemSize
);
224 memcpy(ip
, jp
, itemSize
);
225 memcpy(jp
, &b
, itemSize
);
231 UArray_changed(self
);
235 #define UARRAY_MATCHPREFIXLENGTH_TYPES(OP2, TYPE1, self, TYPE2, other)\
237 long i, minSize = (self->size < other->size) ? self->size : other->size;\
238 for(i = 0; i < minSize; i ++)\
240 TYPE1 v1 = ((TYPE1 *)self->data)[i];\
241 TYPE2 v2 = ((TYPE2 *)other->data)[i];\
242 if (v1 != v2) break;\
247 BASEKIT_API size_t UArray_matchingPrefixSizeWith_(const UArray *self, const UArray *other)
249 DUARRAY_OP(UARRAY_MATCHPREFIXLENGTH_TYPES, NULL, self, other);
255 PtrUArray
*UArray_split_(const UArray
*self
, const PtrUArray
*delims
)
257 PtrUArray
*results
= UArray_new();
259 UArray_setItemType_(results
, CTYPE_uintptr_t
);
261 for (i
= 0; i
< self
->size
; i
++)
263 UArray slice
= UArray_stackRange(self
, i
, self
->size
- i
);
266 for (j
= 0; j
< delims
->size
; j
++)
268 UArray
*delim
= UArray_rawPointerAt_(delims
, j
);
270 if (UArray_beginsWith_(&slice
, delim
))
272 UArray_appendPointer_(results
, UArray_range(self
, last
, i
- last
));
274 last
= i
+ delim
->size
;
275 i
= last
- 1; // since for() will increment it
281 if (last
!= self
->size
)
283 UArray_appendPointer_(results
, UArray_range(self
, last
, self
->size
- last
));
289 size_t UArray_splitCount_(const UArray
*self
, const PtrUArray
*delims
)
291 PtrUArray
*r
= UArray_split_(self
, delims
);
292 size_t count
= UArray_size(r
);
299 BASEKIT_API
int UArray_beginsWith_(UArray
*self
, const UArray
*other
)
301 if (self
->size
>= other
->size
)
303 UArray tmp
= UArray_stackRange(self
, 0, other
->size
);
304 return UArray_find_(&tmp
, other
) != -1;
310 BASEKIT_API
int UArray_endsWith_(UArray
*self
, const UArray
*other
)
312 if (self
->size
>= other
->size
)
314 UArray tmp
= UArray_stackRange(self
, self
->size
- other
->size
, other
->size
);
315 return UArray_find_(&tmp
, other
) != -1;
323 void UArray_swapWith_(UArray
*self
, UArray
*other
)
326 memcpy(&b
, other
, sizeof(UArray
));
327 memcpy(other
, self
, sizeof(UArray
));
328 memcpy(self
, &b
, sizeof(UArray
));
329 UArray_changed(self
);
332 void UArray_escape(UArray
*self
)
334 UArray
*out
= UArray_new();
335 out
->itemType
= self
->itemType
;
337 UARRAY_FOREACH(self
, i
, v
,
340 case '"': UArray_appendCString_(out
, "\\\""); break;
341 case '\a': UArray_appendCString_(out
, "\\a"); break;
342 case '\b': UArray_appendCString_(out
, "\\b"); break;
343 case '\f': UArray_appendCString_(out
, "\\f"); break;
344 case '\n': UArray_appendCString_(out
, "\\n"); break;
345 case '\r': UArray_appendCString_(out
, "\\r"); break;
346 case '\t': UArray_appendCString_(out
, "\\t"); break;
347 case '\v': UArray_appendCString_(out
, "\\v"); break;
348 case '\\': UArray_appendCString_(out
, "\\\\"); break;
349 default: UArray_appendLong_(out
, v
);
353 UArray_swapWith_(self
, out
);
355 UArray_changed(self
);
358 void UArray_unescape(UArray
*self
)
360 if (self
->itemSize
== 1)
362 int mbskip
= 0; /* multi-byte character size */
365 char *s
= (char *)self
->data
;
367 while (getIndex
< self
->size
)
370 int nextChar
= s
[getIndex
+ 1];
372 if (mbskip
<= 0 && ismbchar(c
))
374 mbskip
= mbcharlen(c
);
377 if (c
!= '\\' || mbskip
> 0)
381 if (getIndex
!= putIndex
)
394 case 'a': c
= '\a'; break;
395 case 'b': c
= '\b'; break;
396 case 'f': c
= '\f'; break;
397 case 'n': c
= '\n'; break;
398 case 'r': c
= '\r'; break;
399 case 't': c
= '\t'; break;
400 case 'v': c
= '\v'; break;
401 case '\0': c
= '\\'; break;
417 UArray_setSize_(self
, putIndex
);
418 UArray_changed(self
);
421 printf("Error: UArray unescape unsupported on type size %i\n", self
->itemSize
);
424 void UArray_quote(UArray
*self
)
426 UArray q
= UArray_stackAllocedWithCString_("\"");
427 UArray_prepend_(self
, &q
);
428 UArray_append_(self
, &q
);
429 UArray_changed(self
);
432 void UArray_unquote(UArray
*self
)
434 UArray q
= UArray_stackAllocedWithCString_("\"");
436 if(UArray_beginsWith_(self
, &q
) && UArray_endsWith_(self
, &q
))
438 UArray_removeFirst(self
);
439 UArray_removeLast(self
);
440 UArray_changed(self
);
444 void UArray_translate(UArray
*self
, UArray
*fromChars
, UArray
*toChars
)
447 long fromMax
= UArray_maxAsDouble(fromChars
);
448 long toMax
= UArray_maxAsDouble(toChars
);
450 if (UArray_size(fromChars
) != UArray_size(toChars
))
452 printf("UArray_translate: translation strings must be of the same length");
456 if ((0 < fromMax
&& fromMax
< max
) && (0 < toMax
&& toMax
< 256))
459 uint8_t *map
= io_calloc(1, fromMax
);
460 memset(map
, 0x0, fromMax
);
462 for(i
= 0; i
< UArray_size(fromChars
); i
++)
464 map
[UArray_longAt_(fromChars
, i
)] = UArray_longAt_(toChars
, i
);
467 for(i
= 0; i
< UArray_size(self
); i
++)
469 self
->data
[i
] = map
[self
->data
[i
]];
477 UARRAY_FOREACH(self, i, currChar,
478 UARRAY_FOREACH(fromChars, j, fromChar,
479 if(currChar == fromChar)
481 UARRAY_RAWAT_PUT_(self, i, UARRAY_RAWAT_(toChars, j));
488 UArray_error_(self
, "UArray_translate unimplemented for this type");
491 size_t UArray_count_(const UArray
*self
, const UArray
*other
)
496 while ((i
= UArray_find_from_(self
, other
, i
)) != -1)
498 i
+= UArray_size(other
);