File Coverage

third_party/modest/source/myurl/url.c
Criterion Covered Total %
statement 0 314 0.0
branch 0 146 0.0
condition n/a
subroutine n/a
pod n/a
total 0 460 0.0


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2016-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "myurl/url.h"
22             #include "myurl/resources.h"
23              
24 0           myurl_t * myurl_create(void)
25             {
26 0           return mycore_calloc(1, sizeof(myurl_t));
27             }
28              
29 0           mystatus_t myurl_init(myurl_t* url)
30             {
31 0           url->callback_malloc = myurl_callback_malloc;
32 0           url->callback_free = myurl_callback_free;
33 0           url->callback_realloc = myurl_callback_realloc;
34 0           url->callback_ctx = url;
35            
36 0           return MyURL_STATUS_OK;
37             }
38              
39 0           void myurl_clean(myurl_t* url)
40             {
41 0           memset(url, 0, sizeof(myurl_t));
42 0           }
43              
44 0           myurl_t * myurl_destroy(myurl_t* url, bool self_destroy)
45             {
46 0 0         if(url == NULL)
47 0           return NULL;
48            
49 0 0         if(self_destroy) {
50 0           mycore_free(url);
51 0           return NULL;
52             }
53            
54 0           return url;
55             }
56              
57             /*
58             * Entry
59             */
60 0           myurl_entry_t * myurl_entry_create_and_init(myurl_t* url)
61             {
62 0           myurl_entry_t *entry = url->callback_malloc(sizeof(myurl_entry_t), url->callback_ctx);
63 0 0         if(entry == NULL)
64 0           return NULL;
65            
66 0           memset(entry, 0, sizeof(myurl_entry_t));
67            
68 0 0         if(myurl_path_init(url, &entry->path, 56) != MyURL_STATUS_OK) {
69 0           return url->callback_free(entry, url->callback_ctx);
70             }
71            
72 0           entry->url_ref = url;
73            
74 0           return entry;
75             }
76              
77 0           void myurl_entry_clean(myurl_entry_t* url_entry)
78             {
79 0           myurl_t* url = url_entry->url_ref;
80            
81 0 0         if(url_entry->username)
82 0           url->callback_free(url_entry->username, url->callback_ctx);
83            
84 0 0         if(url_entry->password)
85 0           url->callback_free(url_entry->password, url->callback_ctx);
86            
87 0 0         if(url_entry->query)
88 0           url->callback_free(url_entry->query, url->callback_ctx);
89            
90 0 0         if(url_entry->fragment)
91 0           url->callback_free(url_entry->fragment, url->callback_ctx);
92            
93 0           myurl_host_destroy(url, &url_entry->host, false);
94 0           myurl_path_destroy(url, &url_entry->path, false);
95 0           myurl_scheme_destroy(url, &url_entry->scheme, false);
96            
97 0           memset(url_entry, 0, sizeof(myurl_entry_t));
98            
99 0           url_entry->url_ref = url;
100 0           }
101              
102 0           myurl_entry_t * myurl_entry_destroy(myurl_entry_t* url_entry, bool self_destroy)
103             {
104 0 0         if(url_entry == NULL)
105 0           return NULL;
106            
107 0           myurl_entry_clean(url_entry);
108            
109 0 0         if(self_destroy) {
110 0           return url_entry->url_ref->callback_free(url_entry, url_entry->url_ref->callback_ctx);
111             }
112            
113 0           return url_entry;
114             }
115              
116             /*
117             * The CODE
118             */
119 0           myurl_entry_t * myurl_parse(myurl_t* url, const char* data_url, size_t data_url_size, myurl_entry_t* base_url, mystatus_t* status)
120             {
121 0           myurl_entry_t* entry = myurl_entry_create_and_init(url);
122            
123 0 0         if(entry == NULL) {
124 0 0         if(status)
125 0           *status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
126            
127 0           return NULL;
128             }
129            
130 0           myurl_parser_begin(url, entry, base_url, data_url, data_url_size);
131            
132 0 0         if(status)
133 0           *status = entry->status;
134            
135 0 0         if(entry->status)
136 0           return myurl_entry_destroy(entry, true);
137            
138 0           return entry;
139             }
140              
141             /* api */
142             /* callback */
143 0           void myurl_callback_memory_set(myurl_t* url, myurl_callback_malloc_f callback_malloc, myurl_callback_realloc_f callback_realloc, myurl_callback_free_f callback_free, void* ctx)
144             {
145 0 0         if(callback_malloc)
146 0           url->callback_malloc = callback_malloc;
147             else
148 0           url->callback_malloc = myurl_callback_malloc;
149            
150 0 0         if(callback_realloc)
151 0           url->callback_realloc = callback_realloc;
152             else
153 0           url->callback_realloc = myurl_callback_realloc;
154            
155 0 0         if(callback_free)
156 0           url->callback_free = callback_free;
157             else
158 0           url->callback_free = myurl_callback_free;
159            
160 0 0         if(ctx)
161 0           url->callback_ctx = ctx;
162             else
163 0           url->callback_ctx = url;
164 0           }
165              
166 0           void * myurl_callback_memory_context(myurl_t* url)
167             {
168 0           return url->callback_ctx;
169             }
170              
171             /* api entry */
172             /* callback for as_string */
173 0           static mystatus_t myurl_entry_host_callback_for_as_string(const char* data, size_t len, void* ctx)
174             {
175 0           myurl_utils_serialization_ctx_t *obj_ctx = ctx;
176            
177 0 0         if(obj_ctx->error)
178 0           return MyCORE_STATUS_ERROR;
179            
180 0 0         if((obj_ctx->length + len + 1) >= obj_ctx->size) {
181 0           size_t new_size = obj_ctx->length + len + 128;
182            
183 0           char *tmp = obj_ctx->url->callback_realloc(obj_ctx->data, sizeof(char) * new_size,
184 0           obj_ctx->url->callback_ctx);
185            
186 0 0         if(tmp) {
187 0           obj_ctx->size = new_size;
188 0           obj_ctx->data = tmp;
189             }
190             else
191 0           obj_ctx->error = true;
192             }
193            
194 0           memcpy(&obj_ctx->data[ obj_ctx->length ], data, sizeof(char) * len);
195 0           obj_ctx->length += len;
196            
197 0           return MyCORE_STATUS_OK;
198             }
199              
200 0           static char * myurl_as_string(myurl_entry_t* url_entry, size_t *length, myurl_callback_serialization_func_f func)
201             {
202 0 0         if(length)
203 0           *length = 0;
204            
205 0 0         if(url_entry->url_ref == NULL)
206 0           return NULL;
207            
208 0           myurl_t* url = url_entry->url_ref;
209 0           myurl_utils_serialization_ctx_t ctx = {0};
210            
211 0           ctx.size = 128;
212 0           ctx.data = url->callback_malloc(sizeof(char) * ctx.size, url->callback_ctx);
213 0           ctx.url = url;
214            
215 0 0         if(ctx.data == NULL)
216 0           return NULL;
217            
218 0           func(url_entry, myurl_entry_host_callback_for_as_string, &ctx);
219            
220 0 0         if(ctx.error) {
221 0 0         if(ctx.data)
222 0           return url->callback_free(ctx.data, url->callback_ctx);
223            
224 0           return NULL;
225             }
226            
227 0 0         if(length)
228 0           *length = ctx.length;
229            
230 0           ctx.data[ ctx.length ] = '\0';
231            
232 0           return ctx.data;
233             }
234              
235 0           mystatus_t myurl_entry_status(myurl_entry_t* url_entry)
236             {
237 0           return url_entry->status;
238             }
239              
240 0           myurl_flags_t myurl_entry_flags(myurl_entry_t* url_entry)
241             {
242 0           return url_entry->flags;
243             }
244              
245 0           myurl_t * myurl_entry_url(myurl_entry_t* url_entry)
246             {
247 0           return url_entry->url_ref;
248             }
249              
250 0           char * myurl_entry_as_string(myurl_entry_t* url_entry, size_t *length)
251             {
252 0           return myurl_as_string(url_entry, length, myurl_serialization_with_fragment);
253             }
254              
255             /* scheme */
256 0           myurl_scheme_t * myurl_entry_scheme(myurl_entry_t* url_entry)
257             {
258 0           return &url_entry->scheme;
259             }
260              
261 0           const char * myurl_entry_scheme_name(myurl_entry_t* url_entry, size_t* length)
262             {
263 0 0         if(length)
264 0           *length = url_entry->scheme.length;
265            
266 0           return url_entry->scheme.name;
267             }
268              
269 0           unsigned int myurl_entry_scheme_port(myurl_entry_t* url_entry)
270             {
271 0           return (unsigned int)url_entry->scheme.port;
272             }
273              
274 0           myurl_scheme_id_t myurl_entry_scheme_id(myurl_entry_t* url_entry)
275             {
276 0           return url_entry->scheme.sid;
277             }
278              
279 0           myurl_scheme_type_t myurl_entry_scheme_type(myurl_entry_t* url_entry)
280             {
281 0           return url_entry->scheme.type;
282             }
283              
284             /* authority */
285 0           char * myurl_entry_authority_as_string(myurl_entry_t* url_entry, size_t* length)
286             {
287 0           return myurl_as_string(url_entry, length, myurl_serialization_authority);
288             }
289              
290 0           const char * myurl_entry_username(myurl_entry_t* url_entry, size_t *length)
291             {
292 0 0         if(length)
293 0           *length = url_entry->username_length;
294            
295 0           return url_entry->username;
296             }
297              
298 0           const char * myurl_entry_password(myurl_entry_t* url_entry, size_t *length)
299             {
300 0 0         if(length)
301 0           *length = url_entry->password_length;
302            
303 0           return url_entry->password;
304             }
305              
306             /* host */
307 0           myurl_host_t * myurl_entry_host(myurl_entry_t* url_entry)
308             {
309 0           return &url_entry->host;
310             }
311              
312 0           char * myurl_entry_host_as_string(myurl_entry_t* url_entry, size_t *length)
313             {
314 0           return myurl_as_string(url_entry, length, myurl_serialization_host);
315             }
316              
317 0           myurl_host_type_t myurl_entry_host_type(myurl_entry_t* url_entry)
318             {
319 0           return url_entry->host.type;
320             }
321              
322 0           const char * myurl_entry_host_domain(myurl_entry_t* url_entry, size_t *length)
323             {
324 0 0         if(url_entry->host.type != MyURL_HOST_TYPE_DOMAIN) {
325 0 0         if(length)
326 0           *length = 0;
327            
328 0           return NULL;
329             }
330            
331 0 0         if(length)
332 0           *length = url_entry->host.value.domain.length;
333            
334 0           return url_entry->host.value.domain.value;
335             }
336              
337 0           const char * myurl_entry_host_opaque(myurl_entry_t* url_entry, size_t *length)
338             {
339 0 0         if(url_entry->host.type != MyURL_HOST_TYPE_OPAQUE) {
340 0 0         if(length)
341 0           *length = 0;
342            
343 0           return NULL;
344             }
345            
346 0 0         if(length)
347 0           *length = url_entry->host.value.opaque.length;
348            
349 0           return url_entry->host.value.opaque.value;
350             }
351              
352 0           unsigned int myurl_entry_host_ipv4(myurl_entry_t* url_entry)
353             {
354 0 0         if(url_entry->host.type != MyURL_HOST_TYPE_IPv4)
355 0           return 0;
356            
357 0           return url_entry->host.value.ipv.pieces[0];
358             }
359              
360 0           unsigned int * myurl_entry_host_ipv6(myurl_entry_t* url_entry)
361             {
362 0 0         if(url_entry->host.type != MyURL_HOST_TYPE_IPv6)
363 0           return NULL;
364            
365 0           return url_entry->host.value.ipv.pieces;
366             }
367              
368             /* port */
369 0           bool myurl_entry_port_is_defined(myurl_entry_t* url_entry)
370             {
371 0           return url_entry->port_is_set;
372             }
373              
374 0           unsigned int myurl_entry_port(myurl_entry_t* url_entry)
375             {
376 0           return url_entry->port;
377             }
378              
379             /* path */
380 0           myurl_path_t * myurl_entry_path(myurl_entry_t* url_entry)
381             {
382 0           return &url_entry->path;
383             }
384              
385 0           char * myurl_entry_path_as_string(myurl_entry_t* url_entry, size_t* length)
386             {
387 0           return myurl_as_string(url_entry, length, myurl_serialization_path);
388             }
389              
390 0           size_t myurl_entry_path_length(myurl_entry_t* url_entry)
391             {
392 0           return url_entry->path.length;
393             }
394              
395 0           const char * myurl_entry_path_entry(myurl_entry_t* url_entry, size_t index, size_t *length)
396             {
397 0 0         if(url_entry->path.length < index) {
398 0 0         if(length)
399 0           *length = 0;
400            
401 0           return NULL;
402             }
403            
404 0 0         if(length)
405 0           *length = url_entry->path.list[index].length;
406            
407 0           return url_entry->path.list[index].data;
408             }
409              
410             /* query */
411 0           const char * myurl_entry_query(myurl_entry_t* url_entry, size_t *length)
412             {
413 0 0         if(length)
414 0           *length = url_entry->query_length;
415            
416 0           return url_entry->query;
417             }
418              
419             /* fragment */
420 0           const char * myurl_entry_fragment(myurl_entry_t* url_entry, size_t *length)
421             {
422 0 0         if(length)
423 0           *length = url_entry->fragment_length;
424            
425 0           return url_entry->fragment;
426             }
427              
428             /*
429             For changes
430             */
431             /* scheme */
432 0           const char * myurl_entry_scheme_name_set(myurl_entry_t* url_entry, const char* name, size_t length)
433             {
434 0 0         if(url_entry->url_ref == NULL)
435 0           return NULL;
436            
437 0           myurl_t* url = url_entry->url_ref;
438            
439 0 0         if(myurl_utils_data_copy_set(url, name, length, &url_entry->scheme.name, &url_entry->scheme.length))
440 0           return NULL;
441            
442 0           return url_entry->scheme.name;
443             }
444              
445 0           void myurl_entry_scheme_port_set(myurl_entry_t* url_entry, unsigned int port)
446             {
447 0           url_entry->scheme.port = port;
448 0           }
449              
450 0           void myurl_entry_scheme_id_set(myurl_entry_t* url_entry, myurl_scheme_id_t sid)
451             {
452 0           url_entry->scheme.sid = sid;
453 0           }
454              
455 0           void myurl_entry_scheme_type_set(myurl_entry_t* url_entry, myurl_scheme_type_t type)
456             {
457 0           url_entry->scheme.type = type;
458 0           }
459              
460 0           void myurl_entry_scheme_clean(myurl_entry_t* url_entry)
461             {
462 0 0         if(url_entry->url_ref)
463 0           myurl_scheme_clean(url_entry->url_ref, &url_entry->scheme);
464 0           }
465              
466             /* authority */
467 0           const char * myurl_entry_username_set(myurl_entry_t* url_entry, const char* username, size_t length)
468             {
469 0 0         if(url_entry->url_ref == NULL)
470 0           return NULL;
471            
472 0           myurl_t* url = url_entry->url_ref;
473            
474 0 0         if(myurl_utils_data_copy_set(url, username, length, &url_entry->username, &url_entry->username_length))
475 0           return NULL;
476            
477 0           return url_entry->username;
478             }
479              
480 0           const char * myurl_entry_password_set(myurl_entry_t* url_entry, const char* password, size_t length)
481             {
482 0 0         if(url_entry->url_ref == NULL)
483 0           return NULL;
484            
485 0           myurl_t* url = url_entry->url_ref;
486            
487 0 0         if(myurl_utils_data_copy_set(url, password, length, &url_entry->password, &url_entry->password_length))
488 0           return NULL;
489            
490 0           return url_entry->password;
491             }
492              
493             /* host */
494 0           mystatus_t myurl_entry_host_set(myurl_entry_t* url_entry, const char* host, size_t length)
495             {
496 0 0         if(url_entry->url_ref == NULL)
497 0           return MyURL_STATUS_ERROR;
498            
499             myurl_host_t new_host;
500 0           memset(&new_host, 0, sizeof(myurl_host_t));
501            
502 0           mystatus_t status = myurl_host_parser(url_entry->url_ref, &new_host, host, length, (url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL));
503            
504 0 0         if(status)
505 0           return status;
506            
507 0           myurl_host_clean(url_entry->url_ref, &url_entry->host);
508 0           url_entry->host = new_host;
509            
510 0           return status;
511             }
512              
513             /* port */
514 0           void myurl_entry_port_set(myurl_entry_t* url_entry, unsigned int port)
515             {
516 0           url_entry->port = port;
517 0           url_entry->port_is_set = true;
518 0           }
519              
520             /* path */
521 0           mystatus_t myurl_entry_path_set(myurl_entry_t* url_entry, const char* path, size_t length)
522             {
523 0 0         if(url_entry->url_ref == NULL || path == NULL)
    0          
524 0           return MyURL_STATUS_ERROR;
525            
526             mystatus_t status;
527 0           myurl_entry_t *new_entry = myurl_parse(url_entry->url_ref, path, length, url_entry, &status);
528            
529 0 0         if(new_entry) {
530 0           status = myurl_path_copy(url_entry->url_ref, &new_entry->path, &url_entry->path);
531            
532 0           myurl_entry_destroy(new_entry, true);
533             }
534            
535 0           return status;
536             }
537              
538 0           mystatus_t myurl_entry_path_append_entry(myurl_entry_t* url_entry, const char* entry, size_t length)
539             {
540 0 0         if(url_entry->url_ref == NULL || entry == NULL)
    0          
541 0           return MyURL_STATUS_ERROR;
542            
543             size_t buffer_length;
544 0           char *buffer = myurl_utils_percent_encode(url_entry->url_ref, entry, length, myurl_resources_static_map_path, &buffer_length);
545            
546 0 0         if(buffer == NULL)
547 0           return MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
548            
549 0 0         if(myurl_path_push(url_entry->url_ref, &url_entry->path, buffer, buffer_length) == NULL)
550 0           return MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
551            
552 0           return MyURL_STATUS_OK;
553             }
554              
555 0           void myurl_entry_path_pop_entry(myurl_entry_t* url_entry)
556             {
557 0           myurl_path_pop(&url_entry->path);
558 0           }
559              
560 0           mystatus_t myurl_entry_path_replace_entry(myurl_entry_t* url_entry, size_t index, const char* entry, size_t length)
561             {
562 0 0         if(url_entry->url_ref == NULL || entry == NULL)
    0          
563 0           return MyURL_STATUS_ERROR;
564            
565             size_t buffer_length;
566 0           char *buffer = myurl_utils_percent_encode(url_entry->url_ref, entry, length, myurl_resources_static_map_path, &buffer_length);
567            
568 0 0         if(buffer == NULL)
569 0           return MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
570            
571 0 0         if(myurl_path_push_to_index(url_entry->url_ref, &url_entry->path, index, buffer, buffer_length) == NULL)
572 0           return MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
573            
574 0           return MyURL_STATUS_OK;
575             }
576              
577 0           void myurl_entry_path_remove_entry(myurl_entry_t* url_entry, size_t index)
578             {
579 0 0         if(url_entry->url_ref == NULL)
580 0           return;
581            
582 0           myurl_path_remove_by_index(url_entry->url_ref, &url_entry->path, index);
583             }
584              
585 0           void myurl_entry_path_clean(myurl_entry_t* url_entry)
586             {
587 0 0         if(url_entry->url_ref == NULL)
588 0           return;
589            
590 0           myurl_path_clean(url_entry->url_ref, &url_entry->path);
591             }
592              
593             /* query */
594 0           const char * myurl_entry_query_set(myurl_entry_t* url_entry, const char* query, size_t length)
595             {
596 0 0         if(url_entry->url_ref == NULL)
597 0           return NULL;
598            
599 0           myurl_t* url = url_entry->url_ref;
600            
601             size_t buffer_length;
602 0           char *buffer = myurl_utils_percent_encode(url, query, length, myurl_resources_static_map_query_charset, &buffer_length);
603            
604 0 0         if(buffer == NULL)
605 0           return NULL;
606            
607 0 0         if(url_entry->query)
608 0           url->callback_free(url_entry->query, url->callback_ctx);
609            
610 0           url_entry->query = buffer;
611 0           url_entry->query_length = buffer_length;
612            
613 0           return url_entry->query;
614             }
615              
616             /* fragment */
617 0           const char * myurl_entry_fragment_set(myurl_entry_t* url_entry, const char* fragment, size_t length)
618             {
619 0 0         if(url_entry->url_ref == NULL)
620 0           return NULL;
621            
622 0           myurl_t* url = url_entry->url_ref;
623            
624             size_t buffer_length;
625 0           char *buffer = myurl_utils_percent_encode(url, fragment, length, myurl_resources_static_map_C0, &buffer_length);
626            
627 0 0         if(buffer == NULL)
628 0           return NULL;
629            
630 0 0         if(url_entry->fragment)
631 0           url->callback_free(url_entry->fragment, url->callback_ctx);
632            
633 0           url_entry->fragment = buffer;
634 0           url_entry->fragment_length = buffer_length;
635            
636 0           return url_entry->fragment;
637             }
638              
639             /* for free char* */
640 0           void myurl_entry_free_string(myurl_entry_t* url_entry, char* string)
641             {
642 0 0         if(url_entry->url_ref == NULL)
643 0           return;
644            
645 0 0         if(string)
646 0           url_entry->url_ref->callback_free(string, url_entry->url_ref->callback_ctx);
647             }
648              
649