Objectively 1.0.0
Ultra-lightweight object oriented framework for GNU C.
String.c
Go to the documentation of this file.
1/*
2 * Objectively: Ultra-lightweight object oriented framework for GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include "Config.h"
25
26#include <assert.h>
27#include <iconv.h>
28#include <stdarg.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <string.h>
32#include <wchar.h>
33
34#include "Hash.h"
35#include "MutableArray.h"
36#include "MutableString.h"
37#include "String.h"
38
39#if defined(__MINGW32__)
40#define towlower_l _towlower_l
41#define towupper_l _towupper_l
42#endif
43
44#define _Class _String
45
46#pragma mark - Object
47
51static Object *copy(const Object *self) {
52
53 String *this = (String *) self;
54 String *that = $$(String, stringWithCharacters, this->chars);
55
56 return (Object *) that;
57}
58
62static void dealloc(Object *self) {
63
64 String *this = (String *) self;
65
66 free(this->chars);
67
68 super(Object, self, dealloc);
69}
70
74static String *description(const Object *self) {
75
76 return (String *) $(self, copy);
77}
78
82static int hash(const Object *self) {
83
84 String *this = (String *) self;
85
86 return HashForCString(HASH_SEED, this->chars);
87}
88
92static _Bool isEqual(const Object *self, const Object *other) {
93
94 if (super(Object, self, isEqual, other)) {
95 return true;
96 }
97
98 if (other && $(other, isKindOfClass, _String())) {
99
100 const String *this = (String *) self;
101 const String *that = (String *) other;
102
103 if (this->length == that->length) {
104
105 const Range range = { 0, this->length };
106 return $(this, compareTo, that, range) == OrderSame;
107 }
108 }
109
110 return false;
111}
112
113#pragma mark - String
114
119typedef struct {
122 char *in;
123 size_t length;
124 char *out;
125 size_t size;
126} Transcode;
127
133static size_t transcode(Transcode *trans) {
134
135 assert(trans);
136 assert(trans->to);
137 assert(trans->from);
138 assert(trans->out);
139 assert(trans->size);
140
141 iconv_t cd = iconv_open(NameForStringEncoding(trans->to), NameForStringEncoding(trans->from));
142 assert(cd != (iconv_t ) -1);
143
144 char *in = trans->in;
145 char *out = trans->out;
146
147 size_t inBytesRemaining = trans->length;
148 size_t outBytesRemaining = trans->size;
149
150 const size_t ret = iconv(cd, &in, &inBytesRemaining, &out, &outBytesRemaining);
151 assert(ret != (size_t ) -1);
152
153 int err = iconv_close(cd);
154 assert(err == 0);
155
156 return trans->size - outBytesRemaining;
157}
158
163static Order compareTo(const String *self, const String *other, const Range range) {
164
165 assert(range.location + range.length <= self->length);
166
167 if (other) {
168 const int i = strncmp(self->chars + range.location, other->chars, range.length);
169 if (i == 0) {
170 return OrderSame;
171 }
172 if (i > 0) {
173 return OrderDescending;
174 }
175 }
176
177 return OrderAscending;
178}
179
184static Array *componentsSeparatedByCharacters(const String *self, const char *chars) {
185
186 assert(chars);
187
188 MutableArray *components = $(alloc(MutableArray), init);
189
190 Range search = { 0, self->length };
191 Range result = $(self, rangeOfCharacters, chars, search);
192
193 while (result.length) {
194 search.length = result.location - search.location;
195
196 String *component = $(self, substring, search);
197 $(components, addObject, component);
198 release(component);
199
200 search.location = result.location + result.length;
201 search.length = self->length - search.location;
202
203 result = $(self, rangeOfCharacters, chars, search);
204 }
205
206 String *component = $(self, substring, search);
207 $(components, addObject, component);
208 release(component);
209
210 return (Array *) components;
211}
212
217static Array *componentsSeparatedByString(const String *self, const String *string) {
218
219 assert(string);
220
222}
223
228static Data *getData(const String *self, StringEncoding encoding) {
229
230 Transcode trans = {
231 .to = encoding,
232 .from = STRING_ENCODING_UTF8,
233 .in = self->chars,
234 .length = self->length,
235 .out = calloc(self->length, sizeof(Unicode) / sizeof(char)),
236 .size = self->length * sizeof(Unicode)
237 };
238
239 assert(trans.out);
240
241 const size_t size = transcode(&trans);
242 assert(size <= trans.size);
243
244 return $$(Data, dataWithMemory, trans.out, size);
245}
246
251static _Bool hasPrefix(const String *self, const String *prefix) {
252
253 if (prefix->length > self->length) {
254 return false;
255 }
256
257 Range range = { 0, prefix->length };
258 return $(self, compareTo, prefix, range) == OrderSame;
259}
260
265static _Bool hasSuffix(const String *self, const String *suffix) {
266
267 if (suffix->length > self->length) {
268 return false;
269 }
270
271 Range range = { self->length - suffix->length, suffix->length };
272 return $(self, compareTo, suffix, range) == OrderSame;
273}
274
279static String *initWithBytes(String *self, const uint8_t *bytes, size_t length, StringEncoding encoding) {
280
281 if (bytes) {
282
283 Transcode trans = {
285 .from = encoding,
286 .in = (char *) bytes,
287 .length = length,
288 .out = calloc(length * sizeof(Unicode) + 1, sizeof(char)),
289 .size = length * sizeof(Unicode) + 1
290 };
291
292 assert(trans.out);
293
294 const size_t size = transcode(&trans);
295 assert(size < trans.size);
296
297 ident mem = realloc(trans.out, size + 1);
298 assert(mem);
299
300 return $(self, initWithMemory, mem, size);
301 }
302
303 return $(self, initWithMemory, NULL, 0);
304}
305
310static String *initWithCharacters(String *self, const char *chars) {
311
312 if (chars) {
313
314 ident mem = strdup(chars);
315 assert(mem);
316
317 const size_t length = strlen(chars);
318 return $(self, initWithMemory, mem, length);
319 }
320
321 return $(self, initWithMemory, NULL, 0);
322}
323
328static String *initWithContentsOfFile(String *self, const char *path, StringEncoding encoding) {
329
330 Data *data = $$(Data, dataWithContentsOfFile, path);
331 if (data) {
332 self = $(self, initWithData, data, encoding);
333 } else {
334 self = $(self, initWithMemory, NULL, 0);
335 }
336 release(data);
337
338 return self;
339}
340
345static String *initWithData(String *self, const Data *data, StringEncoding encoding) {
346
347 assert(data);
348
349 return $(self, initWithBytes, data->bytes, data->length, encoding);
350}
351
356static String *initWithFormat(String *self, const char *fmt, ...) {
357
358 va_list args;
359 va_start(args, fmt);
360
361 self = $(self, initWithVaList, fmt, args);
362
363 va_end(args);
364
365 return self;
366}
367
372static String *initWithMemory(String *self, const ident mem, size_t length) {
373
374 self = (String *) super(Object, self, init);
375 if (self) {
376
377 if (mem) {
378 self->chars = (char *) mem;
379 self->length = length;
380 }
381 }
382
383 return self;
384}
385
390static String *initWithVaList(String *self, const char *fmt, va_list args) {
391
392 self = (String *) super(Object, self, init);
393 if (self) {
394
395 if (fmt) {
396 const int len = vasprintf(&self->chars, fmt, args);
397 assert(len >= 0);
398
399 self->length = len;
400 }
401 }
402
403 return self;
404}
405
410static String *lowercaseString(const String *self) {
411
413 assert(data);
414
415 const size_t codepoints = data->length / sizeof(Unicode);
416 Unicode *unicode = (Unicode *) data->bytes;
417
418 for (size_t i = 0; i < codepoints; i++, unicode++) {
419 *unicode = towlower(*unicode);
420 }
421
423
424 release(data);
425 return lowercase;
426}
427
432static MutableString *mutableCopy(const String *self) {
433
434 return $(alloc(MutableString), initWithString, self);
435}
436
441static Range rangeOfCharacters(const String *self, const char *chars, const Range range) {
442
443 assert(chars);
444 assert(range.location > -1);
445 assert(range.length > 0);
446 assert(range.location + range.length <= self->length);
447
448 Range match = { -1, 0 };
449 const size_t len = strlen(chars);
450
451 const char *str = self->chars + range.location;
452 for (size_t i = 0; i < range.length; i++, str++) {
453 if (strncmp(str, chars, len) == 0) {
454 match.location = range.location + i;
455 match.length = len;
456 break;
457 }
458 }
459
460 return match;
461}
462
467static Range rangeOfString(const String *self, const String *string, const Range range) {
468
469 assert(string);
470
471 return $(self, rangeOfCharacters, string->chars, range);
472}
473
478static String *stringWithBytes(const uint8_t *bytes, size_t length, StringEncoding encoding) {
479
480 return $(alloc(String), initWithBytes, bytes, length, encoding);
481}
482
487static String *stringWithCharacters(const char *chars) {
488
489 return $(alloc(String), initWithCharacters, chars);
490}
491
496static String *stringWithContentsOfFile(const char *path, StringEncoding encoding) {
497
498 return $(alloc(String), initWithContentsOfFile, path, encoding);
499}
500
505static String *stringWithData(const Data *data, StringEncoding encoding) {
506
507 return $(alloc(String), initWithData, data, encoding);
508}
509
514static String *stringWithFormat(const char *fmt, ...) {
515
516 va_list args;
517 va_start(args, fmt);
518
519 String *string = $(alloc(String), initWithVaList, fmt, args);
520
521 va_end(args);
522
523 return string;
524}
525
530static String *stringWithMemory(const ident mem, size_t length) {
531
532 return $(alloc(String), initWithMemory, mem, length);
533}
534
539static String *substring(const String *self, const Range range) {
540
541 assert(range.location + range.length <= self->length);
542
543 ident mem = calloc(range.length + 1, sizeof(char));
544 assert(mem);
545
546 strncpy(mem, self->chars + range.location, range.length);
547
548 return $(alloc(String), initWithMemory, mem, range.length);
549}
550
555static String *trimmedString(const String *self) {
556
557 Range range = { .location = 0, .length = self->length };
558
559 while (isspace(self->chars[range.location])) {
560 range.location++;
561 range.length--;
562 }
563
564 while (isspace(self->chars[range.length])) {
565 range.length--;
566 }
567
568 return $(self, substring, range);
569}
570
575static String *uppercaseString(const String *self) {
576
578 assert(data);
579
580 const size_t codepoints = data->length / sizeof(Unicode);
581 Unicode *unicode = (Unicode *) data->bytes;
582
583 for (size_t i = 0; i < codepoints; i++, unicode++) {
584 *unicode = towupper(*unicode);
585 }
586
588
589 release(data);
590 return uppercase;
591}
592
597static _Bool writeToFile(const String *self, const char *path, StringEncoding encoding) {
598
599 Data *data = $(self, getData, encoding);
600 assert(data);
601
602 const _Bool success = $(data, writeToFile, path);
603
604 release(data);
605 return success;
606}
607
608#pragma mark - Class lifecycle
609
613static void initialize(Class *clazz) {
614
615 ((ObjectInterface *) clazz->interface)->copy = copy;
616 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
617 ((ObjectInterface *) clazz->interface)->description = description;
618 ((ObjectInterface *) clazz->interface)->hash = hash;
619 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
620
621 ((StringInterface *) clazz->interface)->compareTo = compareTo;
622 ((StringInterface *) clazz->interface)->componentsSeparatedByCharacters = componentsSeparatedByCharacters;
623 ((StringInterface *) clazz->interface)->componentsSeparatedByString = componentsSeparatedByString;
624 ((StringInterface *) clazz->interface)->getData = getData;
625 ((StringInterface *) clazz->interface)->hasPrefix = hasPrefix;
626 ((StringInterface *) clazz->interface)->hasSuffix = hasSuffix;
627 ((StringInterface *) clazz->interface)->initWithBytes = initWithBytes;
628 ((StringInterface *) clazz->interface)->initWithCharacters = initWithCharacters;
629 ((StringInterface *) clazz->interface)->initWithContentsOfFile = initWithContentsOfFile;
630 ((StringInterface *) clazz->interface)->initWithData = initWithData;
631 ((StringInterface *) clazz->interface)->initWithFormat = initWithFormat;
632 ((StringInterface *) clazz->interface)->initWithMemory = initWithMemory;
633 ((StringInterface *) clazz->interface)->initWithVaList = initWithVaList;
634 ((StringInterface *) clazz->interface)->lowercaseString = lowercaseString;
635 ((StringInterface *) clazz->interface)->mutableCopy = mutableCopy;
636 ((StringInterface *) clazz->interface)->rangeOfCharacters = rangeOfCharacters;
637 ((StringInterface *) clazz->interface)->rangeOfString = rangeOfString;
638 ((StringInterface *) clazz->interface)->stringWithBytes = stringWithBytes;
639 ((StringInterface *) clazz->interface)->stringWithCharacters = stringWithCharacters;
640 ((StringInterface *) clazz->interface)->stringWithContentsOfFile = stringWithContentsOfFile;
641 ((StringInterface *) clazz->interface)->stringWithData = stringWithData;
642 ((StringInterface *) clazz->interface)->stringWithFormat = stringWithFormat;
643 ((StringInterface *) clazz->interface)->stringWithMemory = stringWithMemory;
644 ((StringInterface *) clazz->interface)->substring = substring;
645 ((StringInterface *) clazz->interface)->trimmedString = trimmedString;
646 ((StringInterface *) clazz->interface)->uppercaseString = uppercaseString;
647 ((StringInterface *) clazz->interface)->writeToFile = writeToFile;
648}
649
655 static Class *clazz;
656 static Once once;
657
658 do_once(&once, {
659 clazz = _initialize(&(const ClassDef) {
660 .name = "String",
661 .superclass = _Object(),
662 .instanceSize = sizeof(String),
663 .interfaceOffset = offsetof(String, interface),
664 .interfaceSize = sizeof(StringInterface),
666 });
667 });
668
669 return clazz;
670}
671
672#undef _Class
673
675
676 switch (encoding) {
678 return "ASCII";
680 return "ISO-8859-1";
682 return "ISO-8859-2";
684 return "MacRoman";
686 return "UTF-16";
688 return "UTF-32";
690 return "UTF-8";
692 return "WCHAR_T";
693 }
694
695 return "ASCII";
696}
697
699
700 if (strcasecmp("ASCII", name) == 0) {
702 } else if (strcasecmp("ISO-8859-1", name) == 0) {
704 } else if (strcasecmp("ISO-8859-2", name) == 0) {
706 } else if (strcasecmp("MacRoman", name) == 0) {
708 } else if (strcasecmp("UTF-16", name) == 0) {
710 } else if (strcasecmp("UTF-32", name) == 0) {
712 } else if (strcasecmp("UTF-8", name) == 0) {
714 } else if (strcasecmp("WCHAR", name) == 0) {
716 }
717
719}
720
721Order StringCompare(const ident a, const ident b) {
722
723 if (a) {
724 if (b) {
725 const int i = strcmp(((String *) a)->chars, ((String *) b)->chars);
726 if (i == 0) {
727 return OrderSame;
728 }
729 if (i > 0) {
730 return OrderDescending;
731 }
732 } else {
733 return OrderDescending;
734 }
735 }
736 return OrderAscending;
737}
738
739String *str(const char *fmt, ...) {
740
741 va_list args;
742 va_start(args, fmt);
743
744 String *string = $(alloc(String), initWithVaList, fmt, args);
745 assert(string);
746
747 va_end(args);
748
749 return string;
750}
751
752char *strtrim(const char *s) {
753
754 assert(s);
755 while (isspace(*s)) {
756 s++;
757 }
758
759 char *trimmed = strdup(s);
760 assert(trimmed);
761
762 char *end = trimmed + strlen(trimmed);
763 if (end > trimmed) {
764 while (isspace(*(--end))) {
765 *end = '\0';
766 }
767 }
768
769 return trimmed;
770}
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition: Class.c:196
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition: Class.c:91
#define alloc(type)
Allocate and initialize and instance of type.
Definition: Class.h:159
#define super(type, obj, method,...)
int HashForCString(int hash, const char *string)
Accumulates the hash value of the null-terminated string into hash.
Definition: Hash.c:49
Utilities for calculating hash values.
#define HASH_SEED
The hash seed value.
Definition: Hash.h:37
Mutable arrays.
Mutable UTF-8 strings.
static size_t transcode(Transcode *trans)
Transcodes input from one character encoding to another via iconv.
Definition: String.c:133
char * strtrim(const char *s)
Copies the given null-terminated C string, trimming leading and trailing whitespace.
Definition: String.c:752
static void initialize(Class *clazz)
Definition: String.c:613
Immutable UTF-8 strings.
StringEncoding
Character encodings for Strings.
Definition: String.h:46
@ STRING_ENCODING_LATIN1
Definition: String.h:48
@ STRING_ENCODING_WCHAR
Definition: String.h:54
@ STRING_ENCODING_UTF32
Definition: String.h:52
@ STRING_ENCODING_MACROMAN
Definition: String.h:50
@ STRING_ENCODING_UTF16
Definition: String.h:51
@ STRING_ENCODING_ASCII
Definition: String.h:47
@ STRING_ENCODING_LATIN2
Definition: String.h:49
@ STRING_ENCODING_UTF8
Definition: String.h:53
wchar_t Unicode
The Unicode type.
Definition: String.h:41
void * ident
The identity type, similar to Objective-C id.
Definition: Types.h:49
Order
Comparison constants.
Definition: Types.h:70
@ OrderSame
Definition: Types.h:72
@ OrderDescending
Definition: Types.h:73
@ OrderAscending
Definition: Types.h:71
long Once
The Once type.
Definition: Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition: Once.h:43
Immutable arrays.
Definition: Array.h:56
MutableArray * mutableCopy(const Array *self)
Definition: Array.c:381
Array * initWithVaList(Array *self, va_list args)
Initializes this Array to contain the Objects in the NULL-terminated va_list.
Definition: Array.c:327
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition: Class.h:41
The runtime representation of a Class.
Definition: Class.h:95
ident interface
The interface of the Class.
Definition: Class.h:105
Condition * init(Condition *self)
Initializes this Condition.
Definition: Condition.c:67
Immutable data buffers.
Definition: Data.h:50
Data * initWithContentsOfFile(Data *self, const char *path)
Initializes this Data with the contents of the file at path.
Definition: Data.c:174
Data * initWithMemory(Data *self, ident mem, size_t length)
Initializes this Data, taking ownership of the specified memory.
Definition: Data.c:209
Data * dataWithMemory(ident mem, size_t length)
Returns a new Data, taking ownership of the specified memory.
Definition: Data.c:136
Data * dataWithContentsOfFile(const char *path)
Returns a new Data with the contents of the file at path.
Definition: Data.c:127
size_t length
The length of bytes.
Definition: Data.h:76
uint8_t * bytes
The bytes.
Definition: Data.h:66
_Bool writeToFile(const Data *self, const char *path)
Writes this Data to path.
Definition: Data.c:232
Data * initWithBytes(Data *self, const uint8_t *bytes, size_t length)
Initializes this Data by copying length of bytes.
Definition: Data.c:145
DateFormatter * initWithFormat(DateFormatter *self, const char *fmt)
Initializes a DateFormatter with the specified format string.
Definition: DateFormatter.c:76
Order compareTo(const Date *self, const Date *other)
Compares this Date to another.
Definition: Date.c:74
Mutable arrays.
Definition: MutableArray.h:40
void addObject(MutableArray *self, const ident obj)
Adds the specified Object to this MutableArray.
Definition: MutableArray.c:99
MutableData * initWithData(MutableData *self, const Data *data)
Initializes this Data with the contents of data.
Definition: MutableData.c:124
MutableData * data(void)
Returns a new MutableData.
Definition: MutableData.c:75
Mutable UTF-8 strings.
Definition: MutableString.h:40
MutableString * initWithString(MutableString *self, const String *string)
Initializes this MutableString with the contents of string.
MutableString * string(void)
Returns a new MutableString.
Object is the root Class of The Objectively Class hierarchy.
Definition: Object.h:46
Class * _Object(void)
The Object archetype.
Definition: Object.c:136
Object * copy(const Object *self)
Creates a shallow copy of this Object.
Definition: Array.c:40
_Bool isKindOfClass(const Object *self, const Class *clazz)
Tests for Class hierarchy membership.
Definition: Object.c:101
String * description(const Object *self)
Definition: Array.c:66
_Bool isEqual(const Object *self, const Object *other)
Tests equality of the other Object.
Definition: Array.c:96
int hash(const Object *self)
Definition: Array.c:80
void dealloc(Object *self)
Frees all resources held by this Object.
Definition: Array.c:50
A location and length into contiguous collections.
Definition: Types.h:54
ssize_t location
The location.
Definition: Types.h:59
size_t length
The length.
Definition: Types.h:64
Immutable UTF-8 strings.
Definition: String.h:69
String * uppercaseString(const String *self)
Definition: String.c:575
char * chars
The backing null-terminated UTF-8 encoded character array.
Definition: String.h:85
Array * componentsSeparatedByCharacters(const String *self, const char *chars)
Returns the components of this String that were separated by chars.
Definition: String.c:184
_Bool writeToFile(const String *self, const char *path, StringEncoding encoding)
Writes this String to path.
Definition: String.c:597
String * stringWithMemory(const ident mem, size_t length)
Returns a new String with the given buffer.
Definition: String.c:530
Range rangeOfString(const String *self, const String *string, const Range range)
Finds and returns the first occurrence of string in this String.
Definition: String.c:467
size_t length
The length of the String in bytes.
Definition: String.h:90
String * lowercaseString(const String *self)
Definition: String.c:410
String * initWithCharacters(String *self, const char *chars)
Initializes this String by copying chars.
Definition: String.c:310
String * stringWithBytes(const uint8_t *bytes, size_t length, StringEncoding encoding)
Returns a new String by decoding length of bytes to UTF-8.
Definition: String.c:478
OBJECTIVELY_EXPORT StringEncoding StringEncodingForName(const char *name)
Definition: String.c:698
String * trimmedString(const String *self)
Creates a copy of this String with leading and trailing whitespace removed.
Definition: String.c:555
String * stringWithData(const Data *data, StringEncoding encoding)
Returns a new String with the the given Data.
Definition: String.c:505
String * stringWithFormat(const char *fmt)
Returns a new String with the given format string.
OBJECTIVELY_EXPORT const char * NameForStringEncoding(StringEncoding encoding)
Definition: String.c:674
Data * getData(const String *self, StringEncoding encoding)
Returns a Data with this String's contents in the given encoding.
Definition: String.c:228
String * substring(const String *string, const Range range)
Creates a new String from a subset of this one.
Definition: String.c:539
_Bool hasSuffix(const String *self, const String *suffix)
Checks this String for the given suffix.
Definition: String.c:265
String * initWithContentsOfFile(String *self, const char *path, StringEncoding encoding)
Initializes this String with the contents of the FILE at path.
Definition: String.c:328
Range rangeOfCharacters(const String *self, const char *chars, const Range range)
Finds and returns the first occurrence of chars in this String.
Definition: String.c:441
MutableString * mutableCopy(const String *self)
Definition: String.c:432
Class * _String(void)
The String archetype.
Definition: String.c:654
OBJECTIVELY_EXPORT String * str(const char *fmt,...)
A convenience function for instantiating Strings.
Definition: String.c:739
String * stringWithContentsOfFile(const char *path, StringEncoding encoding)
Returns a new String with the contents of the FILE at path.
Definition: String.c:496
String * stringWithCharacters(const char *chars)
Returns a new String by copying chars.
Definition: String.c:487
OBJECTIVELY_EXPORT Order StringCompare(const ident a, const ident b)
A Comparator for sorting Strings.
Definition: String.c:721
Array * componentsSeparatedByString(const String *self, const String *string)
Returns the components of this String that were separated by string.
Definition: String.c:217
_Bool hasPrefix(const String *self, const String *prefix)
Checks this String for the given prefix.
Definition: String.c:251
Character transcoding context for iconv.
Definition: String.c:119
char * out
Definition: String.c:124
char * in
Definition: String.c:122
size_t length
Definition: String.c:123
StringEncoding from
Definition: String.c:121
size_t size
Definition: String.c:125
StringEncoding to
Definition: String.c:120