Objectively
Object oriented framework for C.
Loading...
Searching...
No Matches
RESTClient.c File Reference
#include <assert.h>
#include <stdlib.h>
#include "RESTClient.h"
#include "URL.h"
#include "URLRequest.h"
#include "URLSessionDataTask.h"

Go to the source code of this file.

Data Structures

struct  RESTClient_AsyncState
 

Macros

#define _Class   _RESTClient
 

Functions

Class * _RESTClient (void)
 
static void dealloc (Object *self)
 
static int del (RESTClient *self, const char *url, const char **headers, Data **data)
 
static void delAsync (RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
 
static void destroy (Class *clazz)
 
static int get (RESTClient *self, const char *url, const char **headers, Data **data)
 
static void getAsync (RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
 
static int head (RESTClient *self, const char *url, const char **headers)
 
static void headAsync (RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
 
static RESTClient * init (RESTClient *self)
 
static void initialize (Class *clazz)
 
static RESTClient * initWithSession (RESTClient *self, URLSession *session)
 
static int options (RESTClient *self, const char *url, const char **headers, Data **data)
 
static void optionsAsync (RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
 
static int patch (RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
 
static void patchAsync (RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
 
static int post (RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
 
static void postAsync (RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
 
static int put (RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
 
static void putAsync (RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
 
static int request (RESTClient *self, HTTPMethod method, const char *url_string, const Data *body, const char **headers, Data **out_data)
 
static void requestAsync (RESTClient *self, HTTPMethod method, const char *url_string, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
 
static void RESTClient_AsyncCompletion (URLSessionTask *task, bool success)
 
static RESTClient * sharedInstance (void)
 

Variables

static RESTClient * _sharedInstance
 

Macro Definition Documentation

◆ _Class

#define _Class   _RESTClient

Definition at line 32 of file RESTClient.c.

Function Documentation

◆ _RESTClient()

Class * _RESTClient ( void  )

Definition at line 342 of file RESTClient.c.

342 {
343
344 static Class *clazz;
345 static Once once;
346
347 do_once(&once, {
348 clazz = _initialize(&(const ClassDef) {
349 .name = "RESTClient",
350 .superclass = _Object(),
351 .instanceSize = sizeof(RESTClient),
352 .interfaceSize = sizeof(RESTClientInterface),
353 .initialize = initialize,
354 .destroy = destroy,
355 });
356 });
357
358 return clazz;
359}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:151
Class * _Object(void)
Definition Object.c:136
static void destroy(Class *clazz)
Definition RESTClient.c:310
static void initialize(Class *clazz)
Definition RESTClient.c:314
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
An HTTP REST client backed by URLSession.
Definition RESTClient.h:62

◆ dealloc()

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

Definition at line 139 of file RESTClient.c.

139 {
140
141 RESTClient *this = (RESTClient *) self;
142
143 release(this->session);
144
145 super(Object, self, dealloc);
146}
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:356
#define super(type, obj, method,...)
static void dealloc(Object *self)
Definition RESTClient.c:139
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ del()

static int del ( RESTClient *  self,
const char *  url,
const char **  headers,
Data **  data 
)
static

Definition at line 154 of file RESTClient.c.

154 {
155 return request(self, HTTP_DELETE, url, NULL, headers, data);
156}
static Data * data(void)
Definition Data.c:286
static int request(RESTClient *self, HTTPMethod method, const char *url_string, const Data *body, const char **headers, Data **out_data)
Definition RESTClient.c:57
@ HTTP_DELETE
Definition URLRequest.h:50

◆ delAsync()

static void delAsync ( RESTClient *  self,
const char *  url,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 162 of file RESTClient.c.

163 {
164 requestAsync(self, HTTP_DELETE, url, NULL, headers, completion, userData);
165}
static void requestAsync(RESTClient *self, HTTPMethod method, const char *url_string, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:99

◆ destroy()

static void destroy ( Class *  clazz)
static

Definition at line 310 of file RESTClient.c.

310 {
312}
static RESTClient * _sharedInstance
Definition RESTClient.c:291

◆ get()

static int get ( RESTClient *  self,
const char *  url,
const char **  headers,
Data **  data 
)
static

Definition at line 171 of file RESTClient.c.

171 {
172 return request(self, HTTP_GET, url, NULL, headers, data);
173}
@ HTTP_GET
Definition URLRequest.h:46

◆ getAsync()

static void getAsync ( RESTClient *  self,
const char *  url,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 179 of file RESTClient.c.

180 {
181 requestAsync(self, HTTP_GET, url, NULL, headers, completion, userData);
182}

◆ head()

static int head ( RESTClient *  self,
const char *  url,
const char **  headers 
)
static

Definition at line 188 of file RESTClient.c.

188 {
189 return request(self, HTTP_HEAD, url, NULL, headers, NULL);
190}
@ HTTP_HEAD
Definition URLRequest.h:44

◆ headAsync()

static void headAsync ( RESTClient *  self,
const char *  url,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 196 of file RESTClient.c.

197 {
198 requestAsync(self, HTTP_HEAD, url, NULL, headers, completion, userData);
199}

◆ init()

static RESTClient * init ( RESTClient *  self)
static

Definition at line 205 of file RESTClient.c.

205 {
206 return $(self, initWithSession, $$(URLSession, sharedInstance));
207}
static RESTClient * initWithSession(RESTClient *self, URLSession *session)
Definition RESTClient.c:213
static RESTClient * sharedInstance(void)
Definition RESTClient.c:297
A management context for loading resources via URLs.
Definition URLSession.h:57

◆ initialize()

static void initialize ( Class *  clazz)
static

Definition at line 314 of file RESTClient.c.

314 {
315
316 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
317
318 RESTClientInterface *rest = (RESTClientInterface *) clazz->interface;
319
320 rest->init = init;
322
323 rest->del = del;
324 rest->get = get;
325 rest->head = head;
326 rest->options = options;
327 rest->patch = patch;
328 rest->post = post;
329 rest->put = put;
330
331 rest->delAsync = delAsync;
332 rest->getAsync = getAsync;
333 rest->headAsync = headAsync;
334 rest->optionsAsync = optionsAsync;
335 rest->patchAsync = patchAsync;
336 rest->postAsync = postAsync;
337 rest->putAsync = putAsync;
338
339 rest->sharedInstance = sharedInstance;
340}
static int head(RESTClient *self, const char *url, const char **headers)
Definition RESTClient.c:188
static void getAsync(RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:179
static void putAsync(RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:286
static void optionsAsync(RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:235
static void delAsync(RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:162
static int del(RESTClient *self, const char *url, const char **headers, Data **data)
Definition RESTClient.c:154
static void patchAsync(RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:252
static int put(RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
Definition RESTClient.c:278
static RESTClient * init(RESTClient *self)
Definition RESTClient.c:205
static void postAsync(RESTClient *self, const char *url, const Data *body, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:269
static int post(RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
Definition RESTClient.c:261
static int get(RESTClient *self, const char *url, const char **headers, Data **data)
Definition RESTClient.c:171
static int patch(RESTClient *self, const char *url, const Data *body, const char **headers, Data **data)
Definition RESTClient.c:244
static void headAsync(RESTClient *self, const char *url, const char **headers, RESTClientCompletion completion, void *userData)
Definition RESTClient.c:196
static int options(RESTClient *self, const char *url, const char **headers, Data **data)
Definition RESTClient.c:227
ident interface
The interface of the Class.
Definition Class.h:100
RESTClient * initWithSession(RESTClient *, URLSession *)
Initializes this RESTClient with the specified URLSession.
Definition RESTClient.c:213
int del(RESTClient *, const char *, const char **, Data **)
Synchronously performs an HTTP DELETE request.
Definition RESTClient.c:154

◆ initWithSession()

static RESTClient * initWithSession ( RESTClient *  self,
URLSession *  session 
)
static

Definition at line 213 of file RESTClient.c.

213 {
214
215 self = (RESTClient *) super(Object, self, init);
216 if (self) {
217 assert(session);
218 self->session = retain(session);
219 }
220 return self;
221}
ident retain(ident obj)
Atomically increment the given Object's reference count.
Definition Class.c:372
URLSession * session
The URLSession backing this client.
Definition RESTClient.h:78

◆ options()

static int options ( RESTClient *  self,
const char *  url,
const char **  headers,
Data **  data 
)
static

Definition at line 227 of file RESTClient.c.

227 {
228 return request(self, HTTP_OPTIONS, url, NULL, headers, data);
229}
@ HTTP_OPTIONS
Definition URLRequest.h:45

◆ optionsAsync()

static void optionsAsync ( RESTClient *  self,
const char *  url,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 235 of file RESTClient.c.

236 {
237 requestAsync(self, HTTP_OPTIONS, url, NULL, headers, completion, userData);
238}

◆ patch()

static int patch ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
Data **  data 
)
static

Definition at line 244 of file RESTClient.c.

244 {
245 return request(self, HTTP_PATCH, url, body, headers, data);
246}
@ HTTP_PATCH
Definition URLRequest.h:49

◆ patchAsync()

static void patchAsync ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 252 of file RESTClient.c.

253 {
254 requestAsync(self, HTTP_PATCH, url, body, headers, completion, userData);
255}

◆ post()

static int post ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
Data **  data 
)
static

Definition at line 261 of file RESTClient.c.

261 {
262 return request(self, HTTP_POST, url, body, headers, data);
263}
@ HTTP_POST
Definition URLRequest.h:47

◆ postAsync()

static void postAsync ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 269 of file RESTClient.c.

270 {
271 requestAsync(self, HTTP_POST, url, body, headers, completion, userData);
272}

◆ put()

static int put ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
Data **  data 
)
static

Definition at line 278 of file RESTClient.c.

278 {
279 return request(self, HTTP_PUT, url, body, headers, data);
280}
@ HTTP_PUT
Definition URLRequest.h:48

◆ putAsync()

static void putAsync ( RESTClient *  self,
const char *  url,
const Data *  body,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 286 of file RESTClient.c.

287 {
288 requestAsync(self, HTTP_PUT, url, body, headers, completion, userData);
289}

◆ request()

static int request ( RESTClient *  self,
HTTPMethod  method,
const char *  url_string,
const Data *  body,
const char **  headers,
Data **  out_data 
)
static

Definition at line 57 of file RESTClient.c.

58 {
59
60 if (out_data) {
61 *out_data = NULL;
62 }
63
65
66 if (method == HTTP_GET && !headers) {
67 URL *url = $(alloc(URL), initWithCharacters, url_string);
68 task = $(self->session, dataTaskWithURL, url, NULL);
69 release(url);
70 } else {
71 URL *url = $(alloc(URL), initWithCharacters, url_string);
73 release(url);
74 request->httpMethod = method;
75 if (body) {
76 request->httpBody = retain((Data *) body);
77 $(request, setValueForHTTPHeaderField, "application/json", "Content-Type");
78 }
79 if (headers) {
80 for (size_t i = 0; headers[i] && headers[i + 1]; i += 2) {
81 $(request, setValueForHTTPHeaderField, headers[i + 1], headers[i]);
82 }
83 }
84 task = $(self->session, dataTaskWithRequest, request, NULL);
86 }
87
88 $((URLSessionTask *) task, execute);
89
90 const int status = task->urlSessionTask.response->httpStatusCode;
91 if (out_data && task->data) {
92 *out_data = retain(task->data);
93 }
94
95 release(task);
96 return status;
97}
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:226
static String * initWithCharacters(String *self, const char *chars)
Definition String.c:633
static URLRequest * initWithURL(URLRequest *self, URL *url)
Definition URLRequest.c:150
static void setValueForHTTPHeaderField(URLRequest *self, const char *value, const char *field)
Definition URLRequest.c:169
static URLSessionDataTask * dataTaskWithRequest(URLSession *self, URLRequest *request, URLSessionTaskCompletion completion)
Definition URLSession.c:76
static URLSessionDataTask * dataTaskWithURL(URLSession *self, URL *url, URLSessionTaskCompletion completion)
Definition URLSession.c:103
static void execute(URLSessionTask *self)
Data buffers.
Definition Data.h:50
Uniform Resource Locators (RFC 3986).
Definition URL.h:44
A protocol-agnostic abstraction for requesting resources via URLs.
Definition URLRequest.h:58
int httpStatusCode
The HTTP response status code.
Definition URLResponse.h:63
Use data tasks to send and receive Data in-memory.
Data * data
The data received.
URLSessionTask urlSessionTask
The superclass.
URL session tasks are handles to pending URL operations.
struct URLResponse * response
The response.

◆ requestAsync()

static void requestAsync ( RESTClient *  self,
HTTPMethod  method,
const char *  url_string,
const Data *  body,
const char **  headers,
RESTClientCompletion  completion,
void *  userData 
)
static

Definition at line 99 of file RESTClient.c.

100 {
101
102 URLSessionDataTask *task;
103
104 if (method == HTTP_GET && !headers) {
105 URL *url = $(alloc(URL), initWithCharacters, url_string);
107 release(url);
108 } else {
109 URL *url = $(alloc(URL), initWithCharacters, url_string);
111 release(url);
112 request->httpMethod = method;
113 if (body) {
114 request->httpBody = retain((Data *) body);
115 $(request, setValueForHTTPHeaderField, "application/json", "Content-Type");
116 }
117 if (headers) {
118 for (size_t i = 0; headers[i] && headers[i + 1]; i += 2) {
119 $(request, setValueForHTTPHeaderField, headers[i + 1], headers[i]);
120 }
121 }
124 }
125
126 RESTClient_AsyncState *state = calloc(1, sizeof(RESTClient_AsyncState));
127 state->completion = completion;
128 state->userData = userData;
129 task->urlSessionTask.data = state;
130
131 $((URLSessionTask *) task, resume);
132}
static void resume(OperationQueue *self)
static void RESTClient_AsyncCompletion(URLSessionTask *task, bool success)
Definition RESTClient.c:41
RESTClientCompletion completion
Definition RESTClient.c:37
ident data
User data.

◆ RESTClient_AsyncCompletion()

static void RESTClient_AsyncCompletion ( URLSessionTask *  task,
bool  success 
)
static

Definition at line 41 of file RESTClient.c.

41 {
42
43 RESTClient_AsyncState *state = task->data;
44 URLSessionDataTask *dataTask = (URLSessionDataTask *) task;
45 const int status = task->response ? task->response->httpStatusCode : 0;
46
47 if (state->completion) {
48 state->completion(status, dataTask->data, state->userData);
49 }
50
51 free(state);
52 release(task);
53}

◆ sharedInstance()

static RESTClient * sharedInstance ( void  )
static

Definition at line 297 of file RESTClient.c.

297 {
298
299 static Once once;
300
301 do_once(&once, {
303 });
304
305 return _sharedInstance;
306}

Variable Documentation

◆ _sharedInstance

RESTClient* _sharedInstance
static

Definition at line 291 of file RESTClient.c.