Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
Date.c
Go to the documentation of this file.
1/*
2 * Objectively: Ultra-lightweight object oriented framework for GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include <assert.h>
25
26#include "Date.h"
27#include "Hash.h"
28
29#define _Class _Date
30
31#pragma mark - Object
32
36static int hash(const Object *self) {
37
38 Date *this = (Date *) self;
39
40 int hash = HASH_SEED;
41
42 hash = HashForInteger(hash, this->time.tv_sec);
43 hash = HashForInteger(hash, this->time.tv_usec);
44
45 return hash;
46}
47
51static bool isEqual(const Object *self, const Object *other) {
52
53 if (super(Object, self, isEqual, other)) {
54 return true;
55 }
56
57 if (other && $(other, isKindOfClass, _Date())) {
58
59 const Date *this = (Date *) self;
60 const Date *that = (Date *) other;
61
62 return $(this, compareTo, that) == OrderSame;
63 }
64
65 return false;
66}
67
68#pragma mark - Date
69
74static Order compareTo(const Date *self, const Date *other) {
75
76 if (other) {
77 const long seconds = self->time.tv_sec - other->time.tv_sec;
78 if (seconds == 0) {
79
80 const long microseconds = self->time.tv_usec - other->time.tv_usec;
81 if (microseconds == 0) {
82 return OrderSame;
83 }
84
85 return microseconds < 0 ? OrderAscending : OrderDescending;
86 }
87
88 return seconds < 0 ? OrderAscending : OrderDescending;
89 }
90
91 return OrderAscending;
92}
93
98static Date *date(void) {
99
100 return $$(Date, dateWithTimeSinceNow, NULL);
101}
102
107static Date *dateWithTimeSinceNow(const Time *interval) {
108
109 Date *date = $(alloc(Date), init);
110 if (date) {
111 if (interval) {
112 date->time.tv_sec += interval->tv_sec;
113 date->time.tv_usec += interval->tv_usec;
114 if (date->time.tv_usec >= USEC_PER_SEC) {
115 date->time.tv_sec++;
116 date->time.tv_usec -= USEC_PER_SEC;
117 } else if (date->time.tv_usec < 0) {
118 date->time.tv_sec--;
119 date->time.tv_usec += USEC_PER_SEC;
120 }
121 }
122 }
123
124 return date;
125}
126
131static Date *init(Date *self) {
132 return $(self, initWithTime, NULL);
133}
134
139static Date *initWithTime(Date *self, const Time *time) {
140
141 self = (Date *) super(Object, self, init);
142 if (self) {
143 if (time) {
144 self->time = *time;
145 } else {
146 gettimeofday(&self->time, NULL);
147 }
148 }
149
150 return self;
151}
152
157static Time timeSinceDate(const Date *self, const Date *date) {
158
159 assert(date);
160
161 return $(self, timeSinceTime, &date->time);
162}
163
168static Time timeSinceNow(const Date *self) {
169
170 Date *date = $$(Date, date);
171
172 Time time = $(self, timeSinceDate, date);
173
174 release(date);
175
176 return time;
177}
178
183static Time timeSinceTime(const Date *self, const Time *time) {
184
185 Time delta = {
186 .tv_sec = self->time.tv_sec - time->tv_sec,
187 .tv_usec = self->time.tv_usec - time->tv_usec
188 };
189
190 if (delta.tv_usec < 0) {
191 delta.tv_sec--;
192 delta.tv_usec += USEC_PER_SEC;
193 }
194
195 return delta;
196}
197
198#pragma mark - Class lifecycle
199
203static void initialize(Class *clazz) {
204
205 ((ObjectInterface *) clazz->interface)->hash = hash;
206 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
207
208 ((DateInterface *) clazz->interface)->compareTo = compareTo;
209 ((DateInterface *) clazz->interface)->date = date;
210 ((DateInterface *) clazz->interface)->dateWithTimeSinceNow = dateWithTimeSinceNow;
211 ((DateInterface *) clazz->interface)->init = init;
212 ((DateInterface *) clazz->interface)->initWithTime = initWithTime;
213 ((DateInterface *) clazz->interface)->timeSinceDate = timeSinceDate;
214 ((DateInterface *) clazz->interface)->timeSinceNow = timeSinceNow;
215 ((DateInterface *) clazz->interface)->timeSinceTime = timeSinceTime;
216}
217
222Class *_Date(void) {
223 static Class *clazz;
224 static Once once;
225
226 do_once(&once, {
227 clazz = _initialize(&(const ClassDef) {
228 .name = "Date",
229 .superclass = _Object(),
230 .instanceSize = sizeof(Date),
231 .interfaceOffset = offsetof(Date, interface),
232 .interfaceSize = sizeof(DateInterface),
234 });
235 });
236
237 return clazz;
238}
239
240#undef _Class
241
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:195
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
#define super(type, obj, method,...)
static Time timeSinceTime(const Date *self, const Time *time)
Definition Date.c:183
static Date * initWithTime(Date *self, const Time *time)
Definition Date.c:139
static bool isEqual(const Object *self, const Object *other)
Definition Date.c:51
static Order compareTo(const Date *self, const Date *other)
Definition Date.c:74
static Date * init(Date *self)
Definition Date.c:131
Class * _Date(void)
Definition Date.c:222
static Time timeSinceNow(const Date *self)
Definition Date.c:168
static Date * dateWithTimeSinceNow(const Time *interval)
Definition Date.c:107
static Date * date(void)
Definition Date.c:98
static void initialize(Class *clazz)
Definition Date.c:203
static Time timeSinceDate(const Date *self, const Date *date)
Definition Date.c:157
static int hash(const Object *self)
Definition Date.c:36
Microsecond-precision immutable dates.
struct timeval Time
Time (seconds and microseconds).
Definition Date.h:64
#define USEC_PER_SEC
Microseconds per second.
Definition Date.h:51
int HashForInteger(int hash, const long integer)
Accumulates the hash value of integer into hash.
Definition Hash.c:66
Utilities for calculating hash values.
#define HASH_SEED
The hash seed value.
Definition Hash.h:37
static bool isKindOfClass(const Object *self, const Class *clazz)
Definition Object.c:101
Class * _Object(void)
Definition Object.c:136
Order
Comparison constants.
Definition Types.h:70
@ OrderSame
Definition Types.h:72
@ OrderDescending
Definition Types.h:73
@ OrderAscending
Definition Types.h:71
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition Class.h:41
The runtime representation of a Class.
Definition Class.h:95
ident interface
The interface of the Class.
Definition Class.h:105
Microsecond-precision immutable dates.
Definition Date.h:74
Date * dateWithTimeSinceNow(const Time interval)
Returns a new Date with the given Time since now.
Date * init(Date *self)
Definition Date.c:131
Time timeSinceDate(const Date *self, const Date *date)
Definition Date.c:157
Date * initWithTime(Date *self, const Time *time)
Definition Date.c:139
Time time
The time.
Definition Date.h:90
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46