Objectively
Object oriented framework for 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 Array * componentsSeparatedByCharacters (const String *self, const char *chars)
 
static Array * componentsSeparatedByString (const String *self, const String *string)
 
static Object * copy (const Object *self)
 
static void dealloc (Object *self)
 
static void deleteCharactersInRange (String *self, const Range range)
 
static String * description (const Object *self)
 
static Data * getData (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 String * init (String *self)
 
static void initialize (Class *clazz)
 
static String * initWithBytes (String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
 
static String * initWithCapacity (String *self, size_t capacity)
 
static String * initWithCharacters (String *self, const char *chars)
 
static String * initWithContentsOfFile (String *self, const char *path, StringEncoding encoding)
 
static String * initWithData (String *self, const Data *data, StringEncoding encoding)
 
static String * initWithFormat (String *self, const char *fmt,...)
 
static String * initWithMemory (String *self, const ident mem, size_t length)
 
static String * initWithString (String *self, const String *string)
 
static String * initWithVaList (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 String * lowercaseString (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)
 
String * str (const char *fmt,...)
 
static String * string (void)
 
Order StringCompare (const ident a, const ident b)
 
StringEncoding StringEncodingForName (const char *name)
 
static String * stringWithBytes (const uint8_t *bytes, size_t length, StringEncoding encoding)
 
static String * stringWithCapacity (size_t capacity)
 
static String * stringWithCharacters (const char *chars)
 
static String * stringWithContentsOfFile (const char *path, StringEncoding encoding)
 
static String * stringWithData (const Data *data, StringEncoding encoding)
 
static String * stringWithFormat (const char *fmt,...)
 
static String * stringWithMemory (const ident mem, size_t length)
 
char * strtrim (const char *s)
 Copies the given null-terminated C string, trimming leading and trailing whitespace.
 
static String * substring (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 String * trimmedString (const String *self)
 
static String * uppercaseString (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 994 of file String.c.

994 {
995 static Class *clazz;
996 static Once once;
997
998 do_once(&once, {
999 clazz = _initialize(&(const ClassDef) {
1000 .name = "String",
1001 .superclass = _Object(),
1002 .instanceSize = sizeof(String),
1003 .interfaceSize = sizeof(StringInterface),
1004 .initialize = initialize,
1005 });
1006 });
1007
1008 return clazz;
1009}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:151
Class * _Object(void)
Definition Object.c:136
static void initialize(Class *clazz)
Definition String.c:930
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:90
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 self->chars = realloc(self->chars, newCapacity);
519 assert(self->chars);
520 self->capacity = newCapacity;
521 }
522
523 ident ptr = self->chars + self->length;
524 memmove(ptr, chars, len);
525
526 self->chars[newSize - 1] = '\0';
527 self->length += len;
528 }
529 }
530}
size_t _pageSize
Definition Class.c:44
Pointer * ptr(ident pointer, Consumer destroy)
Definition Pointer.c:156
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 536 of file String.c.

536 {
537
538 va_list args;
539 va_start(args, fmt);
540
541 $(self, appendVaList, fmt, args);
542
543 va_end(args);
544}
static void appendVaList(String *self, const char *fmt, va_list args)
Definition String.c:561

◆ appendString()

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

Definition at line 550 of file String.c.

550 {
551
552 if (string) {
553 $(self, appendCharacters, string->chars);
554 }
555}
static String * string(void)
Definition String.c:900

◆ appendVaList()

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

Definition at line 561 of file String.c.

561 {
562 char *chars;
563
564 const int len = vasprintf(&chars, fmt, args);
565 if (len > 0) {
566 $(self, appendCharacters, chars);
567 }
568
569 free(chars);
570}

◆ 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:356
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:226
static String * init(String *self)
Definition String.c:593
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:711
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 576 of file String.c.

576 {
577
578 assert(range.location >= 0);
579 assert(range.length <= self->length);
580
581 ident ptr = self->chars + range.location;
582 const size_t length = self->length - range.location - range.length + 1;
583
584 memmove(ptr, ptr + range.length, length);
585
586 self->length -= range.length;
587}

◆ 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 593 of file String.c.

593 {
594 return $(self, initWithCapacity, 0);
595}
static String * initWithCapacity(String *self, size_t capacity)
Definition String.c:615

◆ initialize()

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

Definition at line 930 of file String.c.

930 {
931
932 ((ObjectInterface *) clazz->interface)->copy = copy;
933 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
934 ((ObjectInterface *) clazz->interface)->description = description;
935 ((ObjectInterface *) clazz->interface)->hash = hash;
936 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
937
938 ((StringInterface *) clazz->interface)->compareTo = compareTo;
939 ((StringInterface *) clazz->interface)->componentsSeparatedByCharacters = componentsSeparatedByCharacters;
940 ((StringInterface *) clazz->interface)->componentsSeparatedByString = componentsSeparatedByString;
941 ((StringInterface *) clazz->interface)->getData = getData;
942 ((StringInterface *) clazz->interface)->hasPrefix = hasPrefix;
943 ((StringInterface *) clazz->interface)->hasSuffix = hasSuffix;
944 ((StringInterface *) clazz->interface)->initWithBytes = initWithBytes;
945 ((StringInterface *) clazz->interface)->initWithCharacters = initWithCharacters;
946 ((StringInterface *) clazz->interface)->initWithContentsOfFile = initWithContentsOfFile;
947 ((StringInterface *) clazz->interface)->initWithData = initWithData;
948 ((StringInterface *) clazz->interface)->initWithFormat = initWithFormat;
949 ((StringInterface *) clazz->interface)->initWithMemory = initWithMemory;
950 ((StringInterface *) clazz->interface)->initWithVaList = initWithVaList;
951 ((StringInterface *) clazz->interface)->lowercaseString = lowercaseString;
952 ((StringInterface *) clazz->interface)->appendBytes = appendBytes;
953 ((StringInterface *) clazz->interface)->appendCharacters = appendCharacters;
954 ((StringInterface *) clazz->interface)->appendFormat = appendFormat;
955 ((StringInterface *) clazz->interface)->appendString = appendString;
956 ((StringInterface *) clazz->interface)->appendVaList = appendVaList;
957 ((StringInterface *) clazz->interface)->deleteCharactersInRange = deleteCharactersInRange;
958 ((StringInterface *) clazz->interface)->init = init;
959 ((StringInterface *) clazz->interface)->initWithCapacity = initWithCapacity;
960 ((StringInterface *) clazz->interface)->initWithString = initWithString;
961 ((StringInterface *) clazz->interface)->insertCharactersAtIndex = insertCharactersAtIndex;
962 ((StringInterface *) clazz->interface)->insertStringAtIndex = insertStringAtIndex;
963 ((StringInterface *) clazz->interface)->replaceCharactersInRange = replaceCharactersInRange;
964 ((StringInterface *) clazz->interface)->replaceOccurrencesOfCharacters = replaceOccurrencesOfCharacters;
965 ((StringInterface *) clazz->interface)->replaceOccurrencesOfCharactersInRange = replaceOccurrencesOfCharactersInRange;
966 ((StringInterface *) clazz->interface)->replaceOccurrencesOfString = replaceOccurrencesOfString;
967 ((StringInterface *) clazz->interface)->replaceOccurrencesOfStringInRange = replaceOccurrencesOfStringInRange;
968 ((StringInterface *) clazz->interface)->replaceStringInRange = replaceStringInRange;
969 ((StringInterface *) clazz->interface)->setCharacters = setCharacters;
970 ((StringInterface *) clazz->interface)->setFormat = setFormat;
971 ((StringInterface *) clazz->interface)->setLength = setLength;
972 ((StringInterface *) clazz->interface)->setString = setString;
973 ((StringInterface *) clazz->interface)->string = string;
974 ((StringInterface *) clazz->interface)->stringWithCapacity = stringWithCapacity;
975 ((StringInterface *) clazz->interface)->trim = trim;
976 ((StringInterface *) clazz->interface)->rangeOfCharacters = rangeOfCharacters;
977 ((StringInterface *) clazz->interface)->rangeOfString = rangeOfString;
978 ((StringInterface *) clazz->interface)->stringWithBytes = stringWithBytes;
979 ((StringInterface *) clazz->interface)->stringWithCharacters = stringWithCharacters;
980 ((StringInterface *) clazz->interface)->stringWithContentsOfFile = stringWithContentsOfFile;
981 ((StringInterface *) clazz->interface)->stringWithData = stringWithData;
982 ((StringInterface *) clazz->interface)->stringWithFormat = stringWithFormat;
983 ((StringInterface *) clazz->interface)->stringWithMemory = stringWithMemory;
984 ((StringInterface *) clazz->interface)->substring = substring;
985 ((StringInterface *) clazz->interface)->trimmedString = trimmedString;
986 ((StringInterface *) clazz->interface)->uppercaseString = uppercaseString;
987 ((StringInterface *) clazz->interface)->writeToFile = writeToFile;
988}
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:664
static void insertCharactersAtIndex(String *self, const char *chars, size_t index)
Definition String.c:739
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:791
static String * initWithContentsOfFile(String *self, const char *path, StringEncoding encoding)
Definition String.c:647
static String * stringWithCapacity(size_t capacity)
Definition String.c:908
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:576
static void setString(String *self, const String *string)
Definition String.c:889
static String * description(const Object *self)
Definition String.c:72
static String * initWithMemory(String *self, const ident mem, size_t length)
Definition String.c:695
static String * initWithFormat(String *self, const char *fmt,...)
Definition String.c:675
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:759
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:877
static void setFormat(String *self, const char *fmt,...)
Definition String.c:861
static void trim(String *self)
Definition String.c:916
static String * lowercaseString(const String *self)
Definition String.c:281
static void replaceOccurrencesOfCharacters(String *self, const char *chars, const char *replacement)
Definition String.c:783
static String * initWithBytes(String *self, const uint8_t *bytes, size_t length, StringEncoding encoding)
Definition String.c:601
static String * trimmedString(const String *self)
Definition String.c:417
static void appendFormat(String *self, const char *fmt,...)
Definition String.c:536
static String * stringWithCharacters(const char *chars)
Definition String.c:349
static void replaceOccurrencesOfString(String *self, const String *string, const String *replacement)
Definition String.c:821
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:725
static void appendString(String *self, const String *string)
Definition String.c:550
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:850
static void insertStringAtIndex(String *self, const String *string, size_t index)
Definition String.c:750
static void replaceOccurrencesOfStringInRange(String *self, const String *string, const Range range, const String *replacement)
Definition String.c:829
static String * initWithCharacters(String *self, const char *chars)
Definition String.c:633
static void replaceStringInRange(String *self, const Range range, const String *string)
Definition String.c:841
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:100
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:725
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:633
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:695
void insertCharactersAtIndex(String *self, const char *chars, size_t index)
Inserts the specified String at the given index.
Definition String.c:739
String * stringWithCapacity(size_t capacity)
Returns a new String with the given capacity.
Definition String.c:908
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:664
String * initWithContentsOfFile(String *self, const char *path, StringEncoding encoding)
Initializes this String with the contents of the FILE at path.
Definition String.c:647
void trim(String *self)
Trims leading and trailing whitespace from this String.
Definition String.c:916
String * initWithString(String *self, const String *string)
Initializes this String with the contents of string.
Definition String.c:711
String * initWithCapacity(String *self, size_t capacity)
Initializes this String with the given capacity.
Definition String.c:615
String * initWithFormat(String *self, const char *fmt,...)
Initializes this String with the specified format string.
Definition String.c:675
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 601 of file String.c.

601 {
602
603 self = $(self, init);
604 if (self) {
605 $(self, appendBytes, bytes, length, encoding);
606 }
607
608 return self;
609}

◆ initWithCapacity()

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

Definition at line 615 of file String.c.

615 {
616
617 self = $(self, initWithMemory, NULL, 0);
618 if (self) {
619 self->capacity = capacity;
620 if (self->capacity) {
621 self->chars = calloc(self->capacity, sizeof(char));
622 assert(self->chars);
623 }
624 }
625
626 return self;
627}

◆ initWithCharacters()

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

Definition at line 633 of file String.c.

633 {
634
635 self = $(self, init);
636 if (self) {
637 $(self, appendCharacters, chars);
638 }
639
640 return self;
641}

◆ initWithContentsOfFile()

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

Definition at line 647 of file String.c.

647 {
648
649 Data *data = $$(Data, dataWithContentsOfFile, path);
650 if (data) {
651 self = $(self, initWithData, data, encoding);
652 } else {
653 self = $(self, init);
654 }
655
656 release(data);
657 return self;
658}
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 664 of file String.c.

664 {
665
666 assert(data);
667
668 return $(self, initWithBytes, data->bytes, data->length, encoding);
669}
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 675 of file String.c.

675 {
676
677 self = $(self, init);
678 if (self) {
679
680 va_list args;
681 va_start(args, fmt);
682
683 $(self, appendVaList, fmt, args);
684
685 va_end(args);
686 }
687
688 return self;
689}

◆ initWithMemory()

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

Definition at line 695 of file String.c.

695 {
696
697 self = (String *) super(Object, self, init);
698 if (self) {
699 self->chars = (char *) mem;
700 self->length = length;
701 self->capacity = self->chars ? length + 1 : 0;
702 }
703
704 return self;
705}

◆ initWithString()

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

Definition at line 711 of file String.c.

711 {
712
713 self = $(self, init);
714 if (self) {
715 $(self, appendString, string);
716 }
717
718 return self;
719}

◆ initWithVaList()

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

Definition at line 725 of file String.c.

725 {
726
727 self = $(self, init);
728 if (self) {
729 $(self, appendVaList, fmt, args);
730 }
731
732 return self;
733}

◆ insertCharactersAtIndex()

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

Definition at line 739 of file String.c.

739 {
740
741 const Range range = { .location = index };
742
743 $(self, replaceCharactersInRange, range, chars);
744}

◆ insertStringAtIndex()

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

Definition at line 750 of file String.c.

750 {
751
752 $(self, insertCharactersAtIndex, string->chars, index);
753}

◆ 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:994

◆ 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 1013 of file String.c.

1013 {
1014
1015 switch (encoding) {
1017 return "ASCII";
1019 return "ISO-8859-1";
1021 return "ISO-8859-2";
1023 return "MacRoman";
1025 return "UTF-16";
1027 return "UTF-32";
1029 return "UTF-8";
1031 return "WCHAR_T";
1032 }
1033
1034 return "ASCII";
1035}
@ 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:1078

◆ 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 759 of file String.c.

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

◆ replaceOccurrencesOfCharacters()

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

Definition at line 783 of file String.c.

783 {
784 $(self, replaceOccurrencesOfCharactersInRange, chars, (Range) { .length = self->length }, replacement);
785}

◆ replaceOccurrencesOfCharactersInRange()

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

Definition at line 791 of file String.c.

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

◆ replaceOccurrencesOfString()

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

Definition at line 821 of file String.c.

821 {
822 $(self, replaceOccurrencesOfStringInRange, string, (Range) { .length = self->length }, replacement);
823}

◆ replaceOccurrencesOfStringInRange()

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

Definition at line 829 of file String.c.

829 {
830
831 assert(string);
832 assert(replacement);
833
834 $(self, replaceOccurrencesOfCharactersInRange, string->chars, range, replacement->chars);
835}

◆ replaceStringInRange()

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

Definition at line 841 of file String.c.

841 {
842
843 $(self, replaceCharactersInRange, range, string->chars);
844}

◆ setCharacters()

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

Definition at line 850 of file String.c.

850 {
851
852 $(self, setLength, 0);
853
854 $(self, appendCharacters, chars);
855}

◆ setFormat()

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

Definition at line 861 of file String.c.

861 {
862
863 $(self, setLength, 0);
864
865 va_list args;
866 va_start(args, fmt);
867
868 $(self, appendVaList, fmt, args);
869
870 va_end(args);
871}

◆ setLength()

static void setLength ( String *  self,
size_t  length 
)
static

Definition at line 877 of file String.c.

877 {
878
879 if (length < self->length) {
880 self->length = length;
881 self->chars[length] = '\0';
882 }
883}

◆ setString()

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

Definition at line 889 of file String.c.

889 {
890
891 $(self, setLength, 0);
892
893 $(self, appendString, string);
894}

◆ str()

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

Definition at line 1078 of file String.c.

1078 {
1079
1080 va_list args;
1081 va_start(args, fmt);
1082
1083 String *string = $(alloc(String), initWithVaList, fmt, args);
1084 assert(string);
1085
1086 va_end(args);
1087
1088 return string;
1089}

◆ string()

static String * string ( void  )
static

Definition at line 900 of file String.c.

900 {
901 return $(alloc(String), init);
902}

◆ StringCompare()

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

Definition at line 1060 of file String.c.

1060 {
1061
1062 if (a) {
1063 if (b) {
1064 const int i = strcmp(((String *) a)->chars, ((String *) b)->chars);
1065 if (i == 0) {
1066 return OrderSame;
1067 }
1068 if (i > 0) {
1069 return OrderDescending;
1070 }
1071 } else {
1072 return OrderDescending;
1073 }
1074 }
1075 return OrderAscending;
1076}

◆ StringEncodingForName()

StringEncoding StringEncodingForName ( const char *  name)
related

Definition at line 1037 of file String.c.

1037 {
1038
1039 if (strcasecmp("ASCII", name) == 0) {
1040 return STRING_ENCODING_ASCII;
1041 } else if (strcasecmp("ISO-8859-1", name) == 0) {
1043 } else if (strcasecmp("ISO-8859-2", name) == 0) {
1045 } else if (strcasecmp("MacRoman", name) == 0) {
1047 } else if (strcasecmp("UTF-16", name) == 0) {
1048 return STRING_ENCODING_UTF16;
1049 } else if (strcasecmp("UTF-32", name) == 0) {
1050 return STRING_ENCODING_UTF32;
1051 } else if (strcasecmp("UTF-8", name) == 0) {
1052 return STRING_ENCODING_UTF8;
1053 } else if (strcasecmp("WCHAR", name) == 0) {
1054 return STRING_ENCODING_WCHAR;
1055 }
1056
1057 return STRING_ENCODING_ASCII;
1058}

◆ 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 908 of file String.c.

908 {
909 return $(alloc(String), initWithCapacity, capacity);
910}

◆ 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 1091 of file String.c.

1091 {
1092
1093 assert(s);
1094 while (isspace(*s)) {
1095 s++;
1096 }
1097
1098 char *trimmed = strdup(s);
1099 assert(trimmed);
1100
1101 char *end = trimmed + strlen(trimmed);
1102 if (end > trimmed) {
1103 while (isspace(*(--end))) {
1104 *end = '\0';
1105 }
1106 }
1107
1108 return trimmed;
1109}

◆ 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:1013
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 916 of file String.c.

916 {
917
918 String *trimmed = $((String *) self, trimmedString);
919
920 $(self, replaceStringInRange, (const Range) { .length = self->length }, trimmed);
921
922 release(trimmed);
923}

◆ 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}