Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
URLCachedResponse.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 "URLCachedResponse.h"
27#include "Hash.h"
28
29#define _Class _URLCachedResponse
30
31#pragma mark - Object
32
36static bool objectEquals(const Object *self, const Object *other) {
37
38 if (self) {
39 return other && $(self, isEqual, other);
40 }
41
42 return other == NULL;
43}
44
48static Object *copy(const Object *self) {
49
50 const URLCachedResponse *this = (URLCachedResponse *) self;
51
52 URLCachedResponse *that = $(alloc(URLCachedResponse), initWithResponseData, this->response, this->data);
53 if (that) {
54 release(that->timestamp);
55 that->timestamp = (Date *) $((Object *) this->timestamp, copy);
56 that->size = this->size;
57 }
58
59 return (Object *) that;
60}
61
65static void dealloc(Object *self) {
66
67 URLCachedResponse *this = (URLCachedResponse *) self;
68
69 release(this->response);
70 release(this->data);
71 release(this->timestamp);
72
73 super(Object, self, dealloc);
74}
75
79static int hash(const Object *self) {
80
81 const URLCachedResponse *this = (URLCachedResponse *) self;
82
83 int hash = HASH_SEED;
84 hash = HashForInteger(hash, this->size);
85 hash = HashForInteger(hash, this->response ? this->response->httpStatusCode : 0);
86 hash = HashForObject(hash, this->response ? this->response->httpHeaders : NULL);
87 hash = HashForObject(hash, this->data);
88 hash = HashForObject(hash, this->timestamp);
89
90 return hash;
91}
92
96static bool isEqual(const Object *self, const Object *other) {
97
98 if (super(Object, self, isEqual, other)) {
99 return true;
100 }
101
102 if (other && $(other, isKindOfClass, _URLCachedResponse())) {
103
104 const URLCachedResponse *this = (URLCachedResponse *) self;
105 const URLCachedResponse *that = (URLCachedResponse *) other;
106
107 return this->size == that->size
108 && this->response->httpStatusCode == that->response->httpStatusCode
109 && objectEquals((Object *) this->response->httpHeaders, (Object *) that->response->httpHeaders)
110 && objectEquals((Object *) this->data, (Object *) that->data)
111 && objectEquals((Object *) this->timestamp, (Object *) that->timestamp);
112 }
113
114 return false;
115}
116
117#pragma mark - URLCachedResponse
118
124 const Data *data) {
125
126 assert(response);
127
128 self = (URLCachedResponse *) super(Object, self, init);
129 if (self) {
130 self->response = (URLResponse *) $((Object *) response, copy);
131
132 if (data) {
133 self->data = $(alloc(Data), initWithBytes, data->bytes, data->length);
134 } else {
135 self->data = $(alloc(Data), initWithBytes, (const uint8_t *) "", 0);
136 }
137
138 self->timestamp = $$(Date, date);
139 self->size = self->data ? self->data->length : 0;
140 }
141
142 return self;
143}
144
145#pragma mark - Class lifecycle
146
150static void initialize(Class *clazz) {
151
152 ((ObjectInterface *) clazz->interface)->copy = copy;
153 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
154 ((ObjectInterface *) clazz->interface)->hash = hash;
155 ((ObjectInterface *) clazz->interface)->isEqual = isEqual;
156
157 ((URLCachedResponseInterface *) clazz->interface)->initWithResponseData = initWithResponseData;
158}
159
165 static Class *clazz;
166 static Once once;
167
168 do_once(&once, {
169 clazz = _initialize(&(const ClassDef) {
170 .name = "URLCachedResponse",
171 .superclass = _Object(),
172 .instanceSize = sizeof(URLCachedResponse),
173 .interfaceOffset = offsetof(URLCachedResponse, interface),
174 .interfaceSize = sizeof(URLCachedResponseInterface),
176 });
177 });
178
179 return clazz;
180}
181
182#undef _Class
static Array * init(Array *self)
Definition Array.c:420
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 Data * initWithBytes(Data *self, const uint8_t *bytes, size_t length)
Definition Data.c:151
static Data * data(void)
Definition Data.c:286
static Date * date(void)
Definition Date.c:98
int HashForInteger(int hash, const long integer)
Accumulates the hash value of integer into hash.
Definition Hash.c:66
int HashForObject(int hash, const ident obj)
Accumulates the hash value of object into hash.
Definition Hash.c:72
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
Class * _URLCachedResponse(void)
static bool isEqual(const Object *self, const Object *other)
static bool objectEquals(const Object *self, const Object *other)
Tests equality of two Objects, accounting for NULL.
static void dealloc(Object *self)
static Object * copy(const Object *self)
static void initialize(Class *clazz)
static URLCachedResponse * initWithResponseData(URLCachedResponse *self, const URLResponse *response, const Data *data)
static int hash(const Object *self)
Cached HTTP responses.
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
Data buffers.
Definition Data.h:50
size_t length
The length of bytes.
Definition Data.h:76
uint8_t * bytes
The bytes.
Definition Data.h:66
Microsecond-precision immutable dates.
Definition Date.h:74
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46
Object * copy(const Object *self)
Creates a shallow copy of this Object.
Definition Array.c:84
void dealloc(Object *self)
Frees all resources held by this Object.
Definition Array.c:99
A cached HTTP response.
URLResponse * response
The HTTP response.
Data * data
The response body.
Date * timestamp
The time this response was cached.
size_t size
The cached body size.
A protocol-agnostic abstraction for URLSessionTask responses.
Definition URLResponse.h:42
Dictionary * httpHeaders
The HTTP response headers.
Definition URLResponse.h:58
int httpStatusCode
The HTTP response status code.
Definition URLResponse.h:63