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

Go to the source code of this file.

Macros

#define _Class   _Data
 
#define DATA_BLOCK_SIZE   4096
 

Functions

Class_Data (void)
 
static void appendBytes (Data *self, const uint8_t *bytes, size_t length)
 
static void appendData (Data *self, const Data *data)
 
static Objectcopy (const Object *self)
 
static Datadata (void)
 
static DatadataWithBytes (const uint8_t *bytes, size_t length)
 
static DatadataWithCapacity (size_t capacity)
 
static DatadataWithConstMemory (const ident mem, size_t length)
 
static DatadataWithContentsOfFile (const char *path)
 
static DatadataWithMemory (ident mem, size_t length)
 
static void dealloc (Object *self)
 
static int hash (const Object *self)
 
static Datainit (Data *self)
 
static void initialize (Class *clazz)
 
static DatainitWithBytes (Data *self, const uint8_t *bytes, size_t length)
 
static DatainitWithCapacity (Data *self, size_t capacity)
 
static DatainitWithConstMemory (Data *self, const ident mem, size_t length)
 
static DatainitWithContentsOfFile (Data *self, const char *path)
 
static DatainitWithData (Data *self, const Data *data)
 
static DatainitWithMemory (Data *self, ident mem, size_t length)
 
static bool isEqual (const Object *self, const Object *other)
 
static void setLength (Data *self, size_t length)
 
static bool writeToFile (const Data *self, const char *path)
 

Macro Definition Documentation

◆ _Class

#define _Class   _Data

Definition at line 32 of file Data.c.

◆ DATA_BLOCK_SIZE

#define DATA_BLOCK_SIZE   4096

Definition at line 34 of file Data.c.

Function Documentation

◆ _Data()

Class * _Data ( void  )

Definition at line 419 of file Data.c.

419 {
420 static Class *clazz;
421 static Once once;
422
423 do_once(&once, {
424 clazz = _initialize(&(const ClassDef) {
425 .name = "Data",
426 .superclass = _Object(),
427 .instanceSize = sizeof(Data),
428 .interfaceOffset = offsetof(Data, interface),
429 .interfaceSize = sizeof(DataInterface),
431 });
432 });
433
434 return clazz;
435}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
static void initialize(Class *clazz)
Definition Data.c:389
Class * _Object(void)
Definition Object.c:136
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
Data buffers.
Definition Data.h:50

◆ appendBytes()

static void appendBytes ( Data self,
const uint8_t *  bytes,
size_t  length 
)
static

Definition at line 262 of file Data.c.

262 {
263
264 const size_t oldLength = self->length;
265
266 $(self, setLength, self->length + length);
267
268 if (length) {
269 memcpy(self->bytes + oldLength, bytes, length);
270 }
271}
static void setLength(Data *self, size_t length)
Definition Data.c:349
size_t length
The length of bytes.
Definition Data.h:76
uint8_t * bytes
The bytes.
Definition Data.h:66

◆ appendData()

static void appendData ( Data self,
const Data data 
)
static

Definition at line 277 of file Data.c.

277 {
278
279 $(self, appendBytes, data->bytes, data->length);
280}
static Data * data(void)
Definition Data.c:286
static void appendBytes(Data *self, const uint8_t *bytes, size_t length)
Definition Data.c:262

◆ copy()

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

Definition at line 41 of file Data.c.

41 {
42
43 const Data *this = (const Data *) self;
44
45 Data *that = $(alloc(Data), initWithCapacity, this->capacity ?: this->length);
46 $(that, appendBytes, this->bytes, this->length);
47
48 return (Object *) that;
49}
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
static Data * initWithCapacity(Data *self, size_t capacity)
Definition Data.c:313
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ data()

static Data * data ( void  )
static

Definition at line 286 of file Data.c.

286 {
287
288 return $(alloc(Data), init);
289}
static Data * init(Data *self)
Definition Data.c:304

◆ dataWithBytes()

static Data * dataWithBytes ( const uint8_t *  bytes,
size_t  length 
)
static

Definition at line 115 of file Data.c.

115 {
116
117 return $(alloc(Data), initWithBytes, bytes, length);
118}
static Data * initWithBytes(Data *self, const uint8_t *bytes, size_t length)
Definition Data.c:151

◆ dataWithCapacity()

static Data * dataWithCapacity ( size_t  capacity)
static

Definition at line 295 of file Data.c.

295 {
296
297 return $(alloc(Data), initWithCapacity, capacity);
298}

◆ dataWithConstMemory()

static Data * dataWithConstMemory ( const ident  mem,
size_t  length 
)
static

Definition at line 124 of file Data.c.

124 {
125
126 return $(alloc(Data), initWithConstMemory, mem, length);
127}
static Data * initWithConstMemory(Data *self, const ident mem, size_t length)
Definition Data.c:168

◆ dataWithContentsOfFile()

static Data * dataWithContentsOfFile ( const char *  path)
static

Definition at line 133 of file Data.c.

133 {
134
135 return $(alloc(Data), initWithContentsOfFile, path);
136}
static Data * initWithContentsOfFile(Data *self, const char *path)
Definition Data.c:184

◆ dataWithMemory()

static Data * dataWithMemory ( ident  mem,
size_t  length 
)
static

Definition at line 142 of file Data.c.

142 {
143
144 return $(alloc(Data), initWithMemory, mem, length);
145}
static Data * initWithMemory(Data *self, ident mem, size_t length)
Definition Data.c:219

◆ dealloc()

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

Definition at line 54 of file Data.c.

54 {
55
56 Data *this = (Data *) self;
57
58 if (this->destroy) {
59 if (this->bytes) {
60 this->destroy(this->bytes);
61 }
62 }
63
64 super(Object, self, dealloc);
65}
static void destroy(Class *clazz)
Definition Boole.c:102
#define super(type, obj, method,...)
static void dealloc(Object *self)
Definition Data.c:54

◆ hash()

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

Definition at line 70 of file Data.c.

70 {
71
72 Data *this = (Data *) self;
73
74 int hash = HASH_SEED;
75 hash = HashForInteger(hash, this->length);
76
77 const Range range = { 0, this->length };
78 hash = HashForBytes(hash, this->bytes, range);
79
80 return hash;
81}
static int hash(const Object *self)
Definition Data.c:70
int HashForInteger(int hash, const long integer)
Accumulates the hash value of integer into hash.
Definition Hash.c:66
int HashForBytes(int hash, const uint8_t *bytes, const Range range)
Accumulates the hash value of bytes into hash.
Definition Hash.c:28
#define HASH_SEED
The hash seed value.
Definition Hash.h:37
A location and length into contiguous collections.
Definition Types.h:54

◆ init()

static Data * init ( Data self)
static

Definition at line 304 of file Data.c.

304 {
305
306 return $(self, initWithCapacity, 0);
307}

◆ initialize()

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

Definition at line 389 of file Data.c.

389 {
390
391 ((ObjectInterface *) clazz->interface)->copy = copy;
392 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
393 ((ObjectInterface *) clazz->interface)->hash = hash;
394 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
395
396 ((DataInterface *) clazz->interface)->dataWithBytes = dataWithBytes;
397 ((DataInterface *) clazz->interface)->dataWithConstMemory = dataWithConstMemory;
398 ((DataInterface *) clazz->interface)->dataWithContentsOfFile = dataWithContentsOfFile;
399 ((DataInterface *) clazz->interface)->dataWithMemory = dataWithMemory;
400 ((DataInterface *) clazz->interface)->initWithBytes = initWithBytes;
401 ((DataInterface *) clazz->interface)->initWithConstMemory = initWithConstMemory;
402 ((DataInterface *) clazz->interface)->initWithContentsOfFile = initWithContentsOfFile;
403 ((DataInterface *) clazz->interface)->initWithMemory = initWithMemory;
404 ((DataInterface *) clazz->interface)->appendBytes = appendBytes;
405 ((DataInterface *) clazz->interface)->appendData = appendData;
406 ((DataInterface *) clazz->interface)->data = data;
407 ((DataInterface *) clazz->interface)->dataWithCapacity = dataWithCapacity;
408 ((DataInterface *) clazz->interface)->init = init;
409 ((DataInterface *) clazz->interface)->initWithCapacity = initWithCapacity;
410 ((DataInterface *) clazz->interface)->initWithData = initWithData;
411 ((DataInterface *) clazz->interface)->setLength = setLength;
412 ((DataInterface *) clazz->interface)->writeToFile = writeToFile;
413}
static bool writeToFile(const Data *self, const char *path)
Definition Data.c:233
static bool isEqual(const Object *self, const Object *other)
Definition Data.c:86
static Data * dataWithConstMemory(const ident mem, size_t length)
Definition Data.c:124
static void appendData(Data *self, const Data *data)
Definition Data.c:277
static Data * dataWithContentsOfFile(const char *path)
Definition Data.c:133
static Object * copy(const Object *self)
Definition Data.c:41
static Data * initWithData(Data *self, const Data *data)
Definition Data.c:335
static Data * dataWithCapacity(size_t capacity)
Definition Data.c:295
static Data * dataWithMemory(ident mem, size_t length)
Definition Data.c:142
static Data * dataWithBytes(const uint8_t *bytes, size_t length)
Definition Data.c:115
ident interface
The interface of the Class.
Definition Class.h:105
Data * initWithContentsOfFile(Data *self, const char *path)
Initializes this Data with the contents of the file at path.
Definition Data.c:184
Data * initWithMemory(Data *self, ident mem, size_t length)
Initializes this Data, taking ownership of the specified memory.
Definition Data.c:219
Data * initWithData(Data *self, const Data *data)
Initializes this Data with the contents of data.
Definition Data.c:335
Data * init(Data *self)
Initializes this Data with length 0.
Definition Data.c:304
Data * dataWithMemory(ident mem, size_t length)
Returns a new Data, taking ownership of the specified memory.
Definition Data.c:142
Data * dataWithContentsOfFile(const char *path)
Returns a new Data with the contents of the file at path.
Definition Data.c:133
void appendBytes(Data *self, const uint8_t *bytes, size_t length)
Appends the given bytes to this Data.
Definition Data.c:262
Data * initWithCapacity(Data *self, size_t capacity)
Initializes this Data with the given capacity.
Definition Data.c:313
void setLength(Data *self, size_t length)
Sets the length of this Data, truncating or expanding it.
Definition Data.c:349
Data * initWithConstMemory(Data *self, const ident mem, size_t length)
Initializes this Data with the given const memory.
Definition Data.c:168
Data * initWithBytes(Data *self, const uint8_t *bytes, size_t length)
Initializes this Data by copying length of bytes.
Definition Data.c:151
Data * dataWithConstMemory(const ident mem, size_t length)
Returns a new Data, backed by the given const memory.
Definition Data.c:124
Data * dataWithCapacity(size_t capacity)
Returns a new Data with the given capacity.
Definition Data.c:295
void dealloc(Object *self)
Frees all resources held by this Object.
Definition Array.c:99

◆ initWithBytes()

static Data * initWithBytes ( Data self,
const uint8_t *  bytes,
size_t  length 
)
static

Definition at line 151 of file Data.c.

151 {
152
153 ident mem = NULL;
154 if (length) {
155 mem = malloc(length);
156 assert(mem);
157
158 memcpy(mem, bytes, length);
159 }
160
161 return $(self, initWithMemory, mem, length);
162}
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49

◆ initWithCapacity()

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

Definition at line 313 of file Data.c.

313 {
314
315 self = (Data *) super(Object, self, init);
316 if (self) {
317
318 self->capacity = capacity;
319 if (self->capacity) {
320
321 self->bytes = calloc(capacity, sizeof(uint8_t));
322 assert(self->bytes);
323 }
324
325 self->destroy = free;
326 }
327
328 return self;
329}
DataDestructor destroy
An optional destructor that, if set, is called on dealloc.
Definition Data.h:71

◆ initWithConstMemory()

static Data * initWithConstMemory ( Data self,
const ident  mem,
size_t  length 
)
static

Definition at line 168 of file Data.c.

168 {
169
170 self = (Data *) super(Object, self, init);
171 if (self) {
172 self->bytes = mem;
173 self->length = length;
174 self->capacity = length;
175 }
176
177 return self;
178}

◆ initWithContentsOfFile()

static Data * initWithContentsOfFile ( Data self,
const char *  path 
)
static

Definition at line 184 of file Data.c.

184 {
185
186 assert(path);
187
188 FILE *file = fopen(path, "rb");
189 if (file) {
190 ident mem = NULL;
191
192 int err = fseek(file, 0, SEEK_END);
193 assert(err == 0);
194
195 const size_t length = ftell(file);
196 if (length) {
197
198 mem = malloc(length);
199 assert(mem);
200
201 err = fseek(file, 0, SEEK_SET);
202 assert(err == 0);
203
204 const size_t read = fread(mem, length, 1, file);
205 assert(read == 1);
206 }
207
208 fclose(file);
209 return $(self, initWithMemory, mem, length);
210 }
211
212 return release(self);
213}
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:195

◆ initWithData()

static Data * initWithData ( Data self,
const Data data 
)
static

Definition at line 335 of file Data.c.

335 {
336
337 self = $(self, initWithCapacity, data->length);
338 if (self) {
339 $(self, appendData, data);
340 }
341
342 return self;
343}

◆ initWithMemory()

static Data * initWithMemory ( Data self,
ident  mem,
size_t  length 
)
static

Definition at line 219 of file Data.c.

219 {
220
221 self = $(self, initWithConstMemory, mem, length);
222 if (self) {
223 self->destroy = free;
224 }
225
226 return self;
227}

◆ isEqual()

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

Definition at line 86 of file Data.c.

86 {
87
88 if (super(Object, self, isEqual, other)) {
89 return true;
90 }
91
92 if (other && $(other, isKindOfClass, _Data())) {
93
94 const Data *this = (Data *) self;
95 const Data *that = (Data *) other;
96
97 if (this->length == that->length) {
98 if (this->length == 0) {
99 return true;
100 }
101
102 return memcmp(this->bytes, that->bytes, this->length) == 0;
103 }
104 }
105
106 return false;
107}
Class * _Data(void)
Definition Data.c:419
static bool isKindOfClass(const Object *self, const Class *clazz)
Definition Object.c:101

◆ setLength()

static void setLength ( Data self,
size_t  length 
)
static

Definition at line 349 of file Data.c.

349 {
350
351 const size_t newCapacity = (length / _pageSize + 1) * _pageSize;
352 if (newCapacity > self->capacity) {
353
354 if (self->bytes == NULL) {
355 self->bytes = calloc(newCapacity, sizeof(uint8_t));
356 assert(self->bytes);
357 } else {
358 if (self->destroy != free) {
359 uint8_t *owned = malloc(newCapacity);
360 assert(owned);
361 memcpy(owned, self->bytes, self->length);
362 if (length > self->length) {
363 memset(owned + self->length, 0, length - self->length);
364 }
365 self->bytes = owned;
366 self->destroy = free;
367 } else {
368 self->bytes = realloc(self->bytes, newCapacity);
369 assert(self->bytes);
370 if (length > self->length) {
371 memset(self->bytes + self->length, 0, length - self->length);
372 }
373 }
374 }
375
376 self->capacity = newCapacity;
377 } else if (length > self->length) {
378 memset(self->bytes + self->length, 0, length - self->length);
379 }
380
381 self->length = length;
382}
size_t _pageSize
Definition Class.c:39

◆ writeToFile()

static bool writeToFile ( const Data self,
const char *  path 
)
static

Definition at line 233 of file Data.c.

233 {
234
235 assert(path);
236
237 FILE *file = fopen(path, "w");
238 if (file) {
239
240 size_t count = 1;
241
242 if (self->length) {
243 count = fwrite(self->bytes, self->length, 1, file);
244 }
245
246 fclose(file);
247
248 if (count == 1) {
249 return true;
250 }
251 }
252
253 return false;
254}