Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
String.c File Reference
#include "Config.h"
#include <assert.h>
#include <iconv.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "Hash.h"

Go to the source code of this file.

Data Structures

struct  Transcode
 Character transcoding context for iconv. More...
 

Macros

#define _Class   _String
 

Functions

Class_String (void)
 
static void appendBytes (String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
 
static void appendCharacters (String *self, const char *chars)
 
static void appendFormat (String *self, const char *fmt,...)
 
static void appendString (String *self, const String *string)
 
static void appendVaList (String *self, const char *fmt, va_list args)
 
static Order compareTo (const String *self, const String *other, const Range range)
 
static ArraycomponentsSeparatedByCharacters (const String *self, const char *chars)
 
static ArraycomponentsSeparatedByString (const String *self, const String *string)
 
static Objectcopy (const Object *self)
 
static void dealloc (Object *self)
 
static void deleteCharactersInRange (String *self, const Range range)
 
static Stringdescription (const Object *self)
 
static DatagetData (const String *self, StringEncoding encoding)
 
static int hash (const Object *self)
 
static bool hasPrefix (const String *self, const String *prefix)
 
static bool hasSuffix (const String *self, const String *suffix)
 
static Stringinit (String *self)
 
static void initialize (Class *clazz)
 
static StringinitWithBytes (String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
 
static StringinitWithCapacity (String *self, size_t capacity)
 
static StringinitWithCharacters (String *self, const char *chars)
 
static StringinitWithContentsOfFile (String *self, const char *path, StringEncoding encoding)
 
static StringinitWithData (String *self, const Data *data, StringEncoding encoding)
 
static StringinitWithFormat (String *self, const char *fmt,...)
 
static StringinitWithMemory (String *self, const ident mem, size_t length)
 
static StringinitWithString (String *self, const String *string)
 
static StringinitWithVaList (String *self, const char *fmt, va_list args)
 
static void insertCharactersAtIndex (String *self, const char *chars, size_t index)
 
static void insertStringAtIndex (String *self, const String *string, size_t index)
 
static bool isEqual (const Object *self, const Object *other)
 
static StringlowercaseString (const String *self)
 
const char * NameForStringEncoding (StringEncoding encoding)
 
static Range rangeOfCharacters (const String *self, const char *chars, const Range range)
 
static Range rangeOfString (const String *self, const String *string, const Range range)
 
static void replaceCharactersInRange (String *self, const Range range, const char *chars)
 
static void replaceOccurrencesOfCharacters (String *self, const char *chars, const char *replacement)
 
static void replaceOccurrencesOfCharactersInRange (String *self, const char *chars, const Range range, const char *replacement)
 
static void replaceOccurrencesOfString (String *self, const String *string, const String *replacement)
 
static void replaceOccurrencesOfStringInRange (String *self, const String *string, const Range range, const String *replacement)
 
static void replaceStringInRange (String *self, const Range range, const String *string)
 
static void setCharacters (String *self, const char *chars)
 
static void setFormat (String *self, const char *fmt,...)
 
static void setLength (String *self, size_t length)
 
static void setString (String *self, const String *string)
 
Stringstr (const char *fmt,...)
 
static Stringstring (void)
 
Order StringCompare (const ident a, const ident b)
 
StringEncoding StringEncodingForName (const char *name)
 
static StringstringWithBytes (const uint8_t *bytes, size_t length, StringEncoding encoding)
 
static StringstringWithCapacity (size_t capacity)
 
static StringstringWithCharacters (const char *chars)
 
static StringstringWithContentsOfFile (const char *path, StringEncoding encoding)
 
static StringstringWithData (const Data *data, StringEncoding encoding)
 
static StringstringWithFormat (const char *fmt,...)
 
static StringstringWithMemory (const ident mem, size_t length)
 
char * strtrim (const char *s)
 Copies the given null-terminated C string, trimming leading and trailing whitespace.
 
static Stringsubstring (const String *self, const Range range)
 
static size_t transcode (Transcode *trans)
 Transcodes input from one character encoding to another via iconv.
 
static void trim (String *self)
 
static StringtrimmedString (const String *self)
 
static StringuppercaseString (const String *self)
 
static bool writeToFile (const String *self, const char *path, StringEncoding encoding)
 

Macro Definition Documentation

◆ _Class

#define _Class   _String

Definition at line 42 of file String.c.

Function Documentation

◆ _String()

Class * _String ( void  )

Definition at line 999 of file String.c.

999 {
1000 static Class *clazz;
1001 static Once once;
1002
1003 do_once(&once, {
1004 clazz = _initialize(&(const ClassDef) {
1005 .name = "String",
1006 .superclass = _Object(),
1007 .instanceSize = sizeof(String),
1008 .interfaceOffset = offsetof(String, interface),
1009 .interfaceSize = sizeof(StringInterface),
1011 });
1012 });
1013
1014 return clazz;
1015}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
Class * _Object(void)
Definition Object.c:136
static void initialize(Class *clazz)
Definition String.c:935
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
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
UTF-8 strings.
Definition String.h:69

◆ appendBytes()

static void appendBytes ( String self,
const uint8_t *  bytes,
size_t  length,
StringEncoding  encoding 
)
static

Definition at line 476 of file String.c.

476 {
477
478 if (bytes) {
479
480 Transcode trans = {
482 .from = encoding,
483 .in = (char *) bytes,
484 .length = length,
485 .out = calloc(length * sizeof(Unicode) + 1, sizeof(char)),
486 .size = length * sizeof(Unicode) + 1
487 };
488
489 assert(trans.out);
490
491 const size_t size = transcode(&trans);
492 assert(size < trans.size);
493
494 trans.out[size] = '\0';
495
496 $(self, appendCharacters, trans.out);
497
498 free(trans.out);
499 }
500}
static size_t transcode(Transcode *trans)
Transcodes input from one character encoding to another via iconv.
Definition String.c:131
static void appendCharacters(String *self, const char *chars)
Definition String.c:506
@ STRING_ENCODING_UTF8
Definition String.h:53
wchar_t Unicode
The Unicode type.
Definition String.h:41
Character transcoding context for iconv.
Definition String.c:117
char * out
Definition String.c:122
size_t size
Definition String.c:123
StringEncoding to
Definition String.c:118

◆ appendCharacters()

static void appendCharacters ( String self,
const char *  chars 
)
static

Definition at line 506 of file String.c.

506 {
507
508 if (chars) {
509
510 const size_t len = strlen(chars);
511 if (len) {
512
513 const size_t newSize = self->length + strlen(chars) + 1;
514 const size_t newCapacity = (newSize / _pageSize + 1) * _pageSize;
515
516 if (newCapacity > self->capacity) {
517
518 if (self->length) {
519 self->chars = realloc(self->chars, newCapacity);
520 } else {
521 self->chars = malloc(newCapacity);
522 }
523
524 assert(self->chars);
525 self->capacity = newCapacity;
526 }
527
528 ident ptr = self->chars + self->length;
529 memmove(ptr, chars, len);
530
531 self->chars[newSize - 1] = '\0';
532 self->length += len;
533 }
534 }
535}
size_t _pageSize
Definition Class.c:39
Pointer * ptr(ident pointer, Consumer destroy)
Definition Pointer.c:157
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
char * chars
The backing null-terminated UTF-8 encoded character array.
Definition String.h:85
size_t length
The length of the String in bytes.
Definition String.h:90

◆ appendFormat()

static void appendFormat ( String self,
const char *  fmt,
  ... 
)
static

Definition at line 541 of file String.c.

541 {
542
543 va_list args;
544 va_start(args, fmt);
545
546 $(self, appendVaList, fmt, args);
547
548 va_end(args);
549}
static void appendVaList(String *self, const char *fmt, va_list args)
Definition String.c:566

◆ appendString()

static void appendString ( String self,
const String string 
)
static

Definition at line 555 of file String.c.

555 {
556
557 if (string) {
558 $(self, appendCharacters, string->chars);
559 }
560}
static String * string(void)
Definition String.c:905

◆ appendVaList()

static void appendVaList ( String self,
const char *  fmt,
va_list  args 
)
static

Definition at line 566 of file String.c.

566 {
567 char *chars;
568
569 const int len = vasprintf(&chars, fmt, args);
570 if (len > 0) {
571 $(self, appendCharacters, chars);
572 }
573
574 free(chars);
575}

◆ compareTo()

static Order compareTo ( const String self,
const String other,
const Range  range 
)
static

Definition at line 161 of file String.c.

161 {
162
163 assert(range.location + range.length <= self->length);
164
165 if (other) {
166 const int i = strncmp(self->chars + range.location, other->chars, range.length);
167 if (i == 0) {
168 return OrderSame;
169 }
170 if (i > 0) {
171 return OrderDescending;
172 }
173 }
174
175 return OrderAscending;
176}
@ OrderSame
Definition Types.h:72
@ OrderDescending
Definition Types.h:73
@ OrderAscending
Definition Types.h:71
ssize_t location
The location.
Definition Types.h:59
size_t length
The length.
Definition Types.h:64

◆ componentsSeparatedByCharacters()

static Array * componentsSeparatedByCharacters ( const String self,
const char *  chars 
)
static

Definition at line 182 of file String.c.

182 {
183
184 assert(chars);
185
186 Array *components = $(alloc(Array), init);
187
188 Range search = { 0, self->length };
189 Range result = $(self, rangeOfCharacters, chars, search);
190
191 while (result.length) {
192 search.length = result.location - search.location;
193
194 String *component = $(self, substring, search);
195 $(components, addObject, component);
196 release(component);
197
198 search.location = result.location + result.length;
199 search.length = self->length - search.location;
200
201 result = $(self, rangeOfCharacters, chars, search);
202 }
203
204 String *component = $(self, substring, search);
205 $(components, addObject, component);
206 release(component);
207
208 return components;
209}
static void addObject(Array *self, const ident obj)
Definition Array.c:181
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:195
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
static String * init(String *self)
Definition String.c:598
static Range rangeOfCharacters(const String *self, const char *chars, const Range range)
Definition String.c:303
static String * substring(const String *self, const Range range)
Definition String.c:401
Arrays.
Definition Array.h:56
A location and length into contiguous collections.
Definition Types.h:54

◆ componentsSeparatedByString()

static Array * componentsSeparatedByString ( const String self,
const String string 
)
static

Definition at line 215 of file String.c.

215 {
216
217 assert(string);
218
220}
static Array * componentsSeparatedByCharacters(const String *self, const char *chars)
Definition String.c:182

◆ copy()

static Object * copy ( const Object self)
static
See also
Object::copy(const Object *)

Definition at line 49 of file String.c.

49 {
50
51 const String *this = (const String *) self;
52 String *that = $(alloc(String), initWithString, this);
53
54 return (Object *) that;
55}
static String * initWithString(String *self, const String *string)
Definition String.c:716
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ dealloc()

static void dealloc ( Object self)
static
See also
Object::dealloc(Object *)

Definition at line 60 of file String.c.

60 {
61
62 String *this = (String *) self;
63
64 free(this->chars);
65
66 super(Object, self, dealloc);
67}
#define super(type, obj, method,...)
static void dealloc(Object *self)
Definition String.c:60

◆ deleteCharactersInRange()

static void deleteCharactersInRange ( String self,
const Range  range 
)
static

Definition at line 581 of file String.c.

581 {
582
583 assert(range.location >= 0);
584 assert(range.length <= self->length);
585
586 ident ptr = self->chars + range.location;
587 const size_t length = self->length - range.location - range.length + 1;
588
589 memmove(ptr, ptr + range.length, length);
590
591 self->length -= range.length;
592}

◆ description()

static String * description ( const Object self)
static
See also
Object::description(const Object *)

Definition at line 72 of file String.c.

72 {
73
74 return (String *) $((Object *) self, copy);
75}
static Object * copy(const Object *self)
Definition String.c:49

◆ getData()

static Data * getData ( const String self,
StringEncoding  encoding 
)
static

Definition at line 226 of file String.c.

226 {
227
228 Transcode trans = {
229 .to = encoding,
230 .from = STRING_ENCODING_UTF8,
231 .in = self->chars,
232 .length = self->length,
233 .out = calloc(self->length, sizeof(Unicode) / sizeof(char)),
234 .size = self->length * sizeof(Unicode)
235 };
236
237 assert(trans.out);
238
239 const size_t size = transcode(&trans);
240 assert(size <= trans.size);
241
242 return $$(Data, dataWithMemory, trans.out, size);
243}
static Data * dataWithMemory(ident mem, size_t length)
Definition Data.c:142
Data buffers.
Definition Data.h:50

◆ hash()

static int hash ( const Object self)
static
See also
Object::hash(const Object *)

Definition at line 80 of file String.c.

80 {
81
82 String *this = (String *) self;
83
84 return HashForCString(HASH_SEED, this->chars);
85}
int HashForCString(int hash, const char *string)
Accumulates the hash value of the null-terminated string into hash.
Definition Hash.c:51
#define HASH_SEED
The hash seed value.
Definition Hash.h:37

◆ hasPrefix()

static bool hasPrefix ( const String self,
const String prefix 
)
static

Definition at line 249 of file String.c.

249 {
250
251 if (prefix->length > self->length) {
252 return false;
253 }
254
255 Range range = { 0, prefix->length };
256 return $(self, compareTo, prefix, range) == OrderSame;
257}
static Order compareTo(const String *self, const String *other, const Range range)
Definition String.c:161

◆ hasSuffix()

static bool hasSuffix ( const String self,
const String suffix 
)
static

Definition at line 263 of file String.c.

263 {
264
265 if (suffix->length > self->length) {
266 return false;
267 }
268
269 Range range = { self->length - suffix->length, suffix->length };
270 return $(self, compareTo, suffix, range) == OrderSame;
271}

◆ init()

static String * init ( String self)
static

Definition at line 598 of file String.c.

598 {
599 return $(self, initWithCapacity, 0);
600}
static String * initWithCapacity(String *self, size_t capacity)
Definition String.c:620

◆ initialize()

static void initialize ( Class clazz)
static
See also
Class::initialize(Class *)

Definition at line 935 of file String.c.

935 {
936
937 ((ObjectInterface *) clazz->interface)->copy = copy;
938 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
939 ((ObjectInterface *) clazz->interface)->description = description;
940 ((ObjectInterface *) clazz->interface)->hash = hash;
941 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
942
943 ((StringInterface *) clazz->interface)->compareTo = compareTo;
944 ((StringInterface *) clazz->interface)->componentsSeparatedByCharacters = componentsSeparatedByCharacters;
945 ((StringInterface *) clazz->interface)->componentsSeparatedByString = componentsSeparatedByString;
946 ((StringInterface *) clazz->interface)->getData = getData;
947 ((StringInterface *) clazz->interface)->hasPrefix = hasPrefix;
948 ((StringInterface *) clazz->interface)->hasSuffix = hasSuffix;
949 ((StringInterface *) clazz->interface)->initWithBytes = initWithBytes;
950 ((StringInterface *) clazz->interface)->initWithCharacters = initWithCharacters;
951 ((StringInterface *) clazz->interface)->initWithContentsOfFile = initWithContentsOfFile;
952 ((StringInterface *) clazz->interface)->initWithData = initWithData;
953 ((StringInterface *) clazz->interface)->initWithFormat = initWithFormat;
954 ((StringInterface *) clazz->interface)->initWithMemory = initWithMemory;
955 ((StringInterface *) clazz->interface)->initWithVaList = initWithVaList;
956 ((StringInterface *) clazz->interface)->lowercaseString = lowercaseString;
957 ((StringInterface *) clazz->interface)->appendBytes = appendBytes;
958 ((StringInterface *) clazz->interface)->appendCharacters = appendCharacters;
959 ((StringInterface *) clazz->interface)->appendFormat = appendFormat;
960 ((StringInterface *) clazz->interface)->appendString = appendString;
961 ((StringInterface *) clazz->interface)->appendVaList = appendVaList;
962 ((StringInterface *) clazz->interface)->deleteCharactersInRange = deleteCharactersInRange;
963 ((StringInterface *) clazz->interface)->init = init;
964 ((StringInterface *) clazz->interface)->initWithCapacity = initWithCapacity;
965 ((StringInterface *) clazz->interface)->initWithString = initWithString;
966 ((StringInterface *) clazz->interface)->insertCharactersAtIndex = insertCharactersAtIndex;
967 ((StringInterface *) clazz->interface)->insertStringAtIndex = insertStringAtIndex;
968 ((StringInterface *) clazz->interface)->replaceCharactersInRange = replaceCharactersInRange;
969 ((StringInterface *) clazz->interface)->replaceOccurrencesOfCharacters = replaceOccurrencesOfCharacters;
970 ((StringInterface *) clazz->interface)->replaceOccurrencesOfCharactersInRange = replaceOccurrencesOfCharactersInRange;
971 ((StringInterface *) clazz->interface)->replaceOccurrencesOfString = replaceOccurrencesOfString;
972 ((StringInterface *) clazz->interface)->replaceOccurrencesOfStringInRange = replaceOccurrencesOfStringInRange;
973 ((StringInterface *) clazz->interface)->replaceStringInRange = replaceStringInRange;
974 ((StringInterface *) clazz->interface)->setCharacters = setCharacters;
975 ((StringInterface *) clazz->interface)->setFormat = setFormat;
976 ((StringInterface *) clazz->interface)->setLength = setLength;
977 ((StringInterface *) clazz->interface)->setString = setString;
978 ((StringInterface *) clazz->interface)->string = string;
979 ((StringInterface *) clazz->interface)->stringWithCapacity = stringWithCapacity;
980 ((StringInterface *) clazz->interface)->trim = trim;
981 ((StringInterface *) clazz->interface)->rangeOfCharacters = rangeOfCharacters;
982 ((StringInterface *) clazz->interface)->rangeOfString = rangeOfString;
983 ((StringInterface *) clazz->interface)->stringWithBytes = stringWithBytes;
984 ((StringInterface *) clazz->interface)->stringWithCharacters = stringWithCharacters;
985 ((StringInterface *) clazz->interface)->stringWithContentsOfFile = stringWithContentsOfFile;
986 ((StringInterface *) clazz->interface)->stringWithData = stringWithData;
987 ((StringInterface *) clazz->interface)->stringWithFormat = stringWithFormat;
988 ((StringInterface *) clazz->interface)->stringWithMemory = stringWithMemory;
989 ((StringInterface *) clazz->interface)->substring = substring;
990 ((StringInterface *) clazz->interface)->trimmedString = trimmedString;
991 ((StringInterface *) clazz->interface)->uppercaseString = uppercaseString;
992 ((StringInterface *) clazz->interface)->writeToFile = writeToFile;
993}
static Range rangeOfString(const String *self, const String *string, const Range range)
Definition String.c:329
static String * initWithData(String *self, const Data *data, StringEncoding encoding)
Definition String.c:669
static void insertCharactersAtIndex(String *self, const char *chars, size_t index)
Definition String.c:744
static String * stringWithData(const Data *data, StringEncoding encoding)
Definition String.c:367
static void replaceOccurrencesOfCharactersInRange(String *self, const char *chars, const Range range, const char *replacement)
Definition String.c:796
static String * initWithContentsOfFile(String *self, const char *path, StringEncoding encoding)
Definition String.c:652
static String * stringWithCapacity(size_t capacity)
Definition String.c:913
static bool writeToFile(const String *self, const char *path, StringEncoding encoding)
Definition String.c:459
static String * stringWithFormat(const char *fmt,...)
Definition String.c:376
static bool isEqual(const Object *self, const Object *other)
Definition String.c:90
static bool hasSuffix(const String *self, const String *suffix)
Definition String.c:263
static void deleteCharactersInRange(String *self, const Range range)
Definition String.c:581
static void setString(String *self, const String *string)
Definition String.c:894
static String * description(const Object *self)
Definition String.c:72
static String * initWithMemory(String *self, const ident mem, size_t length)
Definition String.c:700
static String * initWithFormat(String *self, const char *fmt,...)
Definition String.c:680
static bool hasPrefix(const String *self, const String *prefix)
Definition String.c:249
static String * uppercaseString(const String *self)
Definition String.c:437
static void replaceCharactersInRange(String *self, const Range range, const char *chars)
Definition String.c:764
static String * stringWithContentsOfFile(const char *path, StringEncoding encoding)
Definition String.c:358
static Array * componentsSeparatedByString(const String *self, const String *string)
Definition String.c:215
static void setLength(String *self, size_t length)
Definition String.c:882
static void setFormat(String *self, const char *fmt,...)
Definition String.c:866
static void trim(String *self)
Definition String.c:921
static String * lowercaseString(const String *self)
Definition String.c:281
static void replaceOccurrencesOfCharacters(String *self, const char *chars, const char *replacement)
Definition String.c:788
static String * initWithBytes(String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
Definition String.c:606
static String * trimmedString(const String *self)
Definition String.c:417
static void appendFormat(String *self, const char *fmt,...)
Definition String.c:541
static String * stringWithCharacters(const char *chars)
Definition String.c:349
static void replaceOccurrencesOfString(String *self, const String *string, const String *replacement)
Definition String.c:826
static void appendBytes(String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
Definition String.c:476
static String * initWithVaList(String *self, const char *fmt, va_list args)
Definition String.c:730
static void appendString(String *self, const String *string)
Definition String.c:555
static Data * getData(const String *self, StringEncoding encoding)
Definition String.c:226
static String * stringWithMemory(const ident mem, size_t length)
Definition String.c:392
static void setCharacters(String *self, const char *chars)
Definition String.c:855
static void insertStringAtIndex(String *self, const String *string, size_t index)
Definition String.c:755
static void replaceOccurrencesOfStringInRange(String *self, const String *string, const Range range, const String *replacement)
Definition String.c:834
static String * initWithCharacters(String *self, const char *chars)
Definition String.c:638
static void replaceStringInRange(String *self, const Range range, const String *string)
Definition String.c:846
static int hash(const Object *self)
Definition String.c:80
static String * stringWithBytes(const uint8_t *bytes, size_t length, StringEncoding encoding)
Definition String.c:340
ident interface
The interface of the Class.
Definition Class.h:105
Data * initWithBytes(Data *self, const uint8_t *bytes, size_t length)
Initializes this Data by copying length of bytes.
Definition Data.c:151
int hash(const Object *self)
Definition Array.c:129
void dealloc(Object *self)
Frees all resources held by this Object.
Definition Array.c:99
String * uppercaseString(const String *self)
Definition String.c:437
void appendBytes(String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
Appends the decoded contents of bytes.
Definition String.c:476
bool writeToFile(const String *self, const char *path, StringEncoding encoding)
Writes this String to path.
Definition String.c:459
String * initWithVaList(String *self, const char *fmt, va_list args)
Initializes this String with the specified arguments list.
Definition String.c:730
String * stringWithMemory(const ident mem, size_t length)
Returns a new String with the given buffer.
Definition String.c:392
String * lowercaseString(const String *self)
Definition String.c:281
String * initWithCharacters(String *self, const char *chars)
Initializes this String by copying chars.
Definition String.c:638
String * trimmedString(const String *self)
Creates a copy of this String with leading and trailing whitespace removed.
Definition String.c:417
String * stringWithData(const Data *data, StringEncoding encoding)
Returns a new String with the the given Data.
Definition String.c:367
String * stringWithFormat(const char *fmt)
Returns a new String with the given format string.
String * initWithMemory(String *self, const ident mem, size_t length)
Initializes this String with the specified buffer.
Definition String.c:700
void insertCharactersAtIndex(String *self, const char *chars, size_t index)
Inserts the specified String at the given index.
Definition String.c:744
String * stringWithCapacity(size_t capacity)
Returns a new String with the given capacity.
Definition String.c:913
String * substring(const String *string, const Range range)
Creates a new String from a subset of this one.
Definition String.c:401
String * initWithData(String *self, const Data *data, StringEncoding encoding)
Initializes this String with the given Data.
Definition String.c:669
String * initWithContentsOfFile(String *self, const char *path, StringEncoding encoding)
Initializes this String with the contents of the FILE at path.
Definition String.c:652
void trim(String *self)
Trims leading and trailing whitespace from this String.
Definition String.c:921
String * initWithString(String *self, const String *string)
Initializes this String with the contents of string.
Definition String.c:716
String * initWithCapacity(String *self, size_t capacity)
Initializes this String with the given capacity.
Definition String.c:620
String * initWithFormat(String *self, const char *fmt,...)
Initializes this String with the specified format string.
Definition String.c:680
String * stringWithContentsOfFile(const char *path, StringEncoding encoding)
Returns a new String with the contents of the FILE at path.
Definition String.c:358
String * stringWithCharacters(const char *chars)
Returns a new String by copying chars.
Definition String.c:349

◆ initWithBytes()

static String * initWithBytes ( String self,
const uint8_t *  bytes,
size_t  length,
StringEncoding  encoding 
)
static

Definition at line 606 of file String.c.

606 {
607
608 self = $(self, init);
609 if (self) {
610 $(self, appendBytes, bytes, length, encoding);
611 }
612
613 return self;
614}

◆ initWithCapacity()

static String * initWithCapacity ( String self,
size_t  capacity 
)
static

Definition at line 620 of file String.c.

620 {
621
622 self = $(self, initWithMemory, NULL, 0);
623 if (self) {
624 self->capacity = capacity;
625 if (self->capacity) {
626 self->chars = calloc(self->capacity, sizeof(char));
627 assert(self->chars);
628 }
629 }
630
631 return self;
632}

◆ initWithCharacters()

static String * initWithCharacters ( String self,
const char *  chars 
)
static

Definition at line 638 of file String.c.

638 {
639
640 self = $(self, init);
641 if (self) {
642 $(self, appendCharacters, chars);
643 }
644
645 return self;
646}

◆ initWithContentsOfFile()

static String * initWithContentsOfFile ( String self,
const char *  path,
StringEncoding  encoding 
)
static

Definition at line 652 of file String.c.

652 {
653
654 Data *data = $$(Data, dataWithContentsOfFile, path);
655 if (data) {
656 self = $(self, initWithData, data, encoding);
657 } else {
658 self = $(self, init);
659 }
660
661 release(data);
662 return self;
663}
static Data * data(void)
Definition Data.c:286
static Data * dataWithContentsOfFile(const char *path)
Definition Data.c:133

◆ initWithData()

static String * initWithData ( String self,
const Data data,
StringEncoding  encoding 
)
static

Definition at line 669 of file String.c.

669 {
670
671 assert(data);
672
673 return $(self, initWithBytes, data->bytes, data->length, encoding);
674}
size_t length
The length of bytes.
Definition Data.h:76
uint8_t * bytes
The bytes.
Definition Data.h:66

◆ initWithFormat()

static String * initWithFormat ( String self,
const char *  fmt,
  ... 
)
static

Definition at line 680 of file String.c.

680 {
681
682 self = $(self, init);
683 if (self) {
684
685 va_list args;
686 va_start(args, fmt);
687
688 $(self, appendVaList, fmt, args);
689
690 va_end(args);
691 }
692
693 return self;
694}

◆ initWithMemory()

static String * initWithMemory ( String self,
const ident  mem,
size_t  length 
)
static

Definition at line 700 of file String.c.

700 {
701
702 self = (String *) super(Object, self, init);
703 if (self) {
704 self->chars = (char *) mem;
705 self->length = length;
706 self->capacity = self->chars ? length + 1 : 0;
707 }
708
709 return self;
710}

◆ initWithString()

static String * initWithString ( String self,
const String string 
)
static

Definition at line 716 of file String.c.

716 {
717
718 self = $(self, init);
719 if (self) {
720 $(self, appendString, string);
721 }
722
723 return self;
724}

◆ initWithVaList()

static String * initWithVaList ( String self,
const char *  fmt,
va_list  args 
)
static

Definition at line 730 of file String.c.

730 {
731
732 self = $(self, init);
733 if (self) {
734 $(self, appendVaList, fmt, args);
735 }
736
737 return self;
738}

◆ insertCharactersAtIndex()

static void insertCharactersAtIndex ( String self,
const char *  chars,
size_t  index 
)
static

Definition at line 744 of file String.c.

744 {
745
746 const Range range = { .location = index };
747
748 $(self, replaceCharactersInRange, range, chars);
749}

◆ insertStringAtIndex()

static void insertStringAtIndex ( String self,
const String string,
size_t  index 
)
static

Definition at line 755 of file String.c.

755 {
756
757 $(self, insertCharactersAtIndex, string->chars, index);
758}

◆ isEqual()

static bool isEqual ( const Object self,
const Object other 
)
static
See also
Object::isEqual(const Object *, const Object *)

Definition at line 90 of file String.c.

90 {
91
92 if (super(Object, self, isEqual, other)) {
93 return true;
94 }
95
96 if (other && $(other, isKindOfClass, _String())) {
97
98 const String *this = (String *) self;
99 const String *that = (String *) other;
100
101 if (this->length == that->length) {
102
103 const Range range = { 0, this->length };
104 return $(this, compareTo, that, range) == OrderSame;
105 }
106 }
107
108 return false;
109}
static bool isKindOfClass(const Object *self, const Class *clazz)
Definition Object.c:101
Class * _String(void)
Definition String.c:999

◆ lowercaseString()

static String * lowercaseString ( const String self)
static

Definition at line 281 of file String.c.

281 {
282
284 assert(data);
285
286 const size_t codepoints = data->length / sizeof(Unicode);
287 Unicode *unicode = (Unicode *) data->bytes;
288
289 for (size_t i = 0; i < codepoints; i++, unicode++) {
290 *unicode = towlower(*unicode);
291 }
292
294
295 release(data);
296 return lowercase;
297}
@ STRING_ENCODING_WCHAR
Definition String.h:54

◆ NameForStringEncoding()

const char * NameForStringEncoding ( StringEncoding  encoding)
related

Definition at line 1019 of file String.c.

1019 {
1020
1021 switch (encoding) {
1023 return "ASCII";
1025 return "ISO-8859-1";
1027 return "ISO-8859-2";
1029 return "MacRoman";
1031 return "UTF-16";
1033 return "UTF-32";
1035 return "UTF-8";
1037 return "WCHAR_T";
1038 }
1039
1040 return "ASCII";
1041}
@ STRING_ENCODING_LATIN1
Definition String.h:48
@ 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

◆ rangeOfCharacters()

static Range rangeOfCharacters ( const String self,
const char *  chars,
const Range  range 
)
static

Definition at line 303 of file String.c.

303 {
304
305 assert(chars);
306 assert(range.location > -1);
307 assert(range.length > 0);
308 assert(range.location + range.length <= self->length);
309
310 Range match = { -1, 0 };
311 const size_t len = strlen(chars);
312
313 const char *str = self->chars + range.location;
314 for (size_t i = 0; i < range.length; i++, str++) {
315 if (strncmp(str, chars, len) == 0) {
316 match.location = range.location + i;
317 match.length = len;
318 break;
319 }
320 }
321
322 return match;
323}
String * str(const char *fmt,...)
Definition String.c:1084

◆ rangeOfString()

static Range rangeOfString ( const String self,
const String string,
const Range  range 
)
static

Definition at line 329 of file String.c.

329 {
330
331 assert(string);
332
333 return $(self, rangeOfCharacters, string->chars, range);
334}

◆ replaceCharactersInRange()

static void replaceCharactersInRange ( String self,
const Range  range,
const char *  chars 
)
static

Definition at line 764 of file String.c.

764 {
765
766 assert(range.location >= 0);
767 assert(range.location + range.length <= self->length);
768
769 if (self->capacity == 0) {
770 $(self, appendCharacters, chars);
771 } else {
772 char *remainder = strdup(self->chars + range.location + range.length);
773
774 self->length = range.location;
775 self->chars[range.location + 1] = '\0';
776
777 $(self, appendCharacters, chars);
778 $(self, appendCharacters, remainder);
779
780 free(remainder);
781 }
782}

◆ replaceOccurrencesOfCharacters()

static void replaceOccurrencesOfCharacters ( String self,
const char *  chars,
const char *  replacement 
)
static

Definition at line 788 of file String.c.

788 {
789 $(self, replaceOccurrencesOfCharactersInRange, chars, (Range) { .length = self->length }, replacement);
790}

◆ replaceOccurrencesOfCharactersInRange()

static void replaceOccurrencesOfCharactersInRange ( String self,
const char *  chars,
const Range  range,
const char *  replacement 
)
static

Definition at line 796 of file String.c.

796 {
797
798 assert(chars);
799 assert(replacement);
800
801 assert(range.location >= 0);
802 assert(range.location + range.length <= self->length);
803
804 Range search = range;
805 while (true) {
806
807 const Range result = $((String *) self, rangeOfCharacters, chars, search);
808 if (result.location == -1) {
809 break;
810 }
811
812 $(self, replaceCharactersInRange, result, replacement);
813
814 search.length -= (result.location - search.location);
815 search.length -= strlen(replacement);
816 search.length += ((int) strlen(replacement) - (int) strlen(chars));
817
818 search.location = result.location + strlen(replacement);
819 }
820}

◆ replaceOccurrencesOfString()

static void replaceOccurrencesOfString ( String self,
const String string,
const String replacement 
)
static

Definition at line 826 of file String.c.

826 {
827 $(self, replaceOccurrencesOfStringInRange, string, (Range) { .length = self->length }, replacement);
828}

◆ replaceOccurrencesOfStringInRange()

static void replaceOccurrencesOfStringInRange ( String self,
const String string,
const Range  range,
const String replacement 
)
static

Definition at line 834 of file String.c.

834 {
835
836 assert(string);
837 assert(replacement);
838
839 $(self, replaceOccurrencesOfCharactersInRange, string->chars, range, replacement->chars);
840}

◆ replaceStringInRange()

static void replaceStringInRange ( String self,
const Range  range,
const String string 
)
static

Definition at line 846 of file String.c.

846 {
847
848 $(self, replaceCharactersInRange, range, string->chars);
849}

◆ setCharacters()

static void setCharacters ( String self,
const char *  chars 
)
static

Definition at line 855 of file String.c.

855 {
856
857 $(self, setLength, 0);
858
859 $(self, appendCharacters, chars);
860}

◆ setFormat()

static void setFormat ( String self,
const char *  fmt,
  ... 
)
static

Definition at line 866 of file String.c.

866 {
867
868 $(self, setLength, 0);
869
870 va_list args;
871 va_start(args, fmt);
872
873 $(self, appendVaList, fmt, args);
874
875 va_end(args);
876}

◆ setLength()

static void setLength ( String self,
size_t  length 
)
static

Definition at line 882 of file String.c.

882 {
883
884 if (length < self->length) {
885 self->length = length;
886 self->chars[length] = '\0';
887 }
888}

◆ setString()

static void setString ( String self,
const String string 
)
static

Definition at line 894 of file String.c.

894 {
895
896 $(self, setLength, 0);
897
898 $(self, appendString, string);
899}

◆ str()

String * str ( const char *  fmt,
  ... 
)
related

Definition at line 1084 of file String.c.

1084 {
1085
1086 va_list args;
1087 va_start(args, fmt);
1088
1089 String *string = $(alloc(String), initWithVaList, fmt, args);
1090 assert(string);
1091
1092 va_end(args);
1093
1094 return string;
1095}

◆ string()

static String * string ( void  )
static

Definition at line 905 of file String.c.

905 {
906 return $(alloc(String), init);
907}

◆ StringCompare()

Order StringCompare ( const ident  a,
const ident  b 
)
related

Definition at line 1066 of file String.c.

1066 {
1067
1068 if (a) {
1069 if (b) {
1070 const int i = strcmp(((String *) a)->chars, ((String *) b)->chars);
1071 if (i == 0) {
1072 return OrderSame;
1073 }
1074 if (i > 0) {
1075 return OrderDescending;
1076 }
1077 } else {
1078 return OrderDescending;
1079 }
1080 }
1081 return OrderAscending;
1082}

◆ StringEncodingForName()

StringEncoding StringEncodingForName ( const char *  name)
related

Definition at line 1043 of file String.c.

1043 {
1044
1045 if (strcasecmp("ASCII", name) == 0) {
1046 return STRING_ENCODING_ASCII;
1047 } else if (strcasecmp("ISO-8859-1", name) == 0) {
1049 } else if (strcasecmp("ISO-8859-2", name) == 0) {
1051 } else if (strcasecmp("MacRoman", name) == 0) {
1053 } else if (strcasecmp("UTF-16", name) == 0) {
1054 return STRING_ENCODING_UTF16;
1055 } else if (strcasecmp("UTF-32", name) == 0) {
1056 return STRING_ENCODING_UTF32;
1057 } else if (strcasecmp("UTF-8", name) == 0) {
1058 return STRING_ENCODING_UTF8;
1059 } else if (strcasecmp("WCHAR", name) == 0) {
1060 return STRING_ENCODING_WCHAR;
1061 }
1062
1063 return STRING_ENCODING_ASCII;
1064}

◆ stringWithBytes()

static String * stringWithBytes ( const uint8_t *  bytes,
size_t  length,
StringEncoding  encoding 
)
static

Definition at line 340 of file String.c.

340 {
341
342 return $(alloc(String), initWithBytes, bytes, length, encoding);
343}

◆ stringWithCapacity()

static String * stringWithCapacity ( size_t  capacity)
static

Definition at line 913 of file String.c.

913 {
914 return $(alloc(String), initWithCapacity, capacity);
915}

◆ stringWithCharacters()

static String * stringWithCharacters ( const char *  chars)
static

Definition at line 349 of file String.c.

349 {
350
351 return $(alloc(String), initWithCharacters, chars);
352}

◆ stringWithContentsOfFile()

static String * stringWithContentsOfFile ( const char *  path,
StringEncoding  encoding 
)
static

Definition at line 358 of file String.c.

358 {
359
360 return $(alloc(String), initWithContentsOfFile, path, encoding);
361}

◆ stringWithData()

static String * stringWithData ( const Data data,
StringEncoding  encoding 
)
static

Definition at line 367 of file String.c.

367 {
368
369 return $(alloc(String), initWithData, data, encoding);
370}

◆ stringWithFormat()

static String * stringWithFormat ( const char *  fmt,
  ... 
)
static

Definition at line 376 of file String.c.

376 {
377
378 va_list args;
379 va_start(args, fmt);
380
381 String *string = $(alloc(String), initWithVaList, fmt, args);
382
383 va_end(args);
384
385 return string;
386}

◆ stringWithMemory()

static String * stringWithMemory ( const ident  mem,
size_t  length 
)
static

Definition at line 392 of file String.c.

392 {
393
394 return $(alloc(String), initWithMemory, mem, length);
395}

◆ strtrim()

char * strtrim ( const char *  s)

Copies the given null-terminated C string, trimming leading and trailing whitespace.

Parameters
sA null-terminated C string.
Returns
A trimmed copy of str which must be freed by the caller.

Definition at line 1097 of file String.c.

1097 {
1098
1099 assert(s);
1100 while (isspace(*s)) {
1101 s++;
1102 }
1103
1104 char *trimmed = strdup(s);
1105 assert(trimmed);
1106
1107 char *end = trimmed + strlen(trimmed);
1108 if (end > trimmed) {
1109 while (isspace(*(--end))) {
1110 *end = '\0';
1111 }
1112 }
1113
1114 return trimmed;
1115}

◆ substring()

static String * substring ( const String self,
const Range  range 
)
static

Definition at line 401 of file String.c.

401 {
402
403 assert(range.location + range.length <= self->length);
404
405 ident mem = calloc(range.length + 1, sizeof(char));
406 assert(mem);
407
408 strncpy(mem, self->chars + range.location, range.length);
409
410 return $(alloc(String), initWithMemory, mem, range.length);
411}

◆ transcode()

static size_t transcode ( Transcode trans)
static

Transcodes input from one character encoding to another via iconv.

Parameters
transA Transcode struct.
Returns
The number of bytes written to trans->out.

Definition at line 131 of file String.c.

131 {
132
133 assert(trans);
134 assert(trans->to);
135 assert(trans->from);
136 assert(trans->out);
137 assert(trans->size);
138
139 iconv_t cd = iconv_open(NameForStringEncoding(trans->to), NameForStringEncoding(trans->from));
140 assert(cd != (iconv_t) -1);
141
142 char *in = trans->in;
143 char *out = trans->out;
144
145 size_t inBytesRemaining = trans->length;
146 size_t outBytesRemaining = trans->size;
147
148 const size_t ret = iconv(cd, &in, &inBytesRemaining, &out, &outBytesRemaining);
149 assert(ret != (size_t) -1);
150
151 int err = iconv_close(cd);
152 assert(err == 0);
153
154 return trans->size - outBytesRemaining;
155}
const char * NameForStringEncoding(StringEncoding encoding)
Definition String.c:1019
char * in
Definition String.c:120
size_t length
Definition String.c:121
StringEncoding from
Definition String.c:119

◆ trim()

static void trim ( String self)
static

Definition at line 921 of file String.c.

921 {
922
923 String *trimmed = $((String *) self, trimmedString);
924
925 $(self, replaceStringInRange, (const Range) { .length = self->length }, trimmed);
926
927 release(trimmed);
928}

◆ trimmedString()

static String * trimmedString ( const String self)
static

Definition at line 417 of file String.c.

417 {
418
419 Range range = { .location = 0, .length = self->length };
420
421 while (isspace(self->chars[range.location])) {
422 range.location++;
423 range.length--;
424 }
425
426 while (range.length > 0 && isspace(self->chars[range.location + range.length - 1])) {
427 range.length--;
428 }
429
430 return $(self, substring, range);
431}

◆ uppercaseString()

static String * uppercaseString ( const String self)
static

Definition at line 437 of file String.c.

437 {
438
440 assert(data);
441
442 const size_t codepoints = data->length / sizeof(Unicode);
443 Unicode *unicode = (Unicode *) data->bytes;
444
445 for (size_t i = 0; i < codepoints; i++, unicode++) {
446 *unicode = towupper(*unicode);
447 }
448
450
451 release(data);
452 return uppercase;
453}

◆ writeToFile()

static bool writeToFile ( const String self,
const char *  path,
StringEncoding  encoding 
)
static

Definition at line 459 of file String.c.

459 {
460
461 Data *data = $(self, getData, encoding);
462 assert(data);
463
464 const bool success = $(data, writeToFile, path);
465
466 release(data);
467 return success;
468}