src/bloblist.c
author Roker <roker@pep-project.org>
Thu, 14 Dec 2017 15:20:49 +0100
branchENGINE-321
changeset 2298 640f83c07bbd
parent 2020 bb198b900e2d
permissions -rw-r--r--
add declaration & implementation of bloblist_iterate()
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 
     6 #include <stdlib.h>
     7 #include <assert.h>
     8 #include <string.h>
     9 
    10 #include "bloblist.h"
    11 
    12 static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
    13                           const char* filename) {
    14     
    15     if (!bloblist)
    16         return false;
    17         
    18     if (mime_type) {
    19        bloblist->mime_type = strdup(mime_type);
    20        if (bloblist->mime_type == NULL) {
    21            return false;
    22        }
    23     }
    24     
    25     if (filename) {
    26        bloblist->filename = strdup(filename);
    27        if (bloblist->filename == NULL) {
    28            free(bloblist->mime_type);
    29            return false;
    30        }
    31        /* Default behaviour, can be overwritten post-allocation with
    32           set_blob_content_disposition */
    33        if (strstr(filename, "cid://") == filename)
    34            bloblist->disposition = PEP_CONTENT_DISP_INLINE;
    35                         
    36     }               
    37     
    38     if (blob) {
    39         bloblist->value = blob;
    40         bloblist->size = size;
    41     }
    42     
    43     return true;
    44 }
    45 
    46 DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    47         const char *filename)
    48 {
    49     bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
    50     assert(bloblist);
    51     if (bloblist == NULL)
    52         return NULL;
    53 
    54     if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
    55         free(bloblist);
    56         bloblist = NULL;
    57     }
    58 
    59     return bloblist;
    60 }
    61 
    62 DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
    63 {
    64     bloblist_t *curr = bloblist;
    65 
    66     while (curr) {
    67         bloblist_t *next = curr->next;
    68         free(curr->value);
    69         free(curr->mime_type);
    70         free(curr->filename);
    71         free(curr);
    72         curr = next;
    73     }
    74 }
    75 
    76 DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
    77 {
    78     assert(src);
    79     if (src == NULL)
    80         return NULL;
    81     
    82     bloblist_t *bloblist = NULL;
    83 
    84     // head
    85     char *blob2 = malloc(src->size);
    86     assert(blob2);
    87     if (blob2 == NULL)
    88         goto enomem;
    89 
    90     memcpy(blob2, src->value, src->size);
    91 
    92     bloblist = new_bloblist(blob2, src->size, src->mime_type, src->filename);
    93     if (bloblist == NULL)
    94         goto enomem;
    95     blob2 = NULL;
    96 
    97     bloblist_t* src_curr = src->next;
    98     bloblist_t** dst_curr_ptr = &bloblist->next;
    99 
   100     // list
   101     while (src_curr) {
   102         blob2 = malloc(src_curr->size);
   103 
   104         assert(blob2);
   105         if (blob2 == NULL)
   106             goto enomem;
   107 
   108         memcpy(blob2, src_curr->value, src_curr->size);
   109         *dst_curr_ptr = new_bloblist(blob2, src_curr->size, src_curr->mime_type, src_curr->filename);
   110         if (*dst_curr_ptr == NULL)
   111             goto enomem;
   112 
   113         src_curr = src_curr->next;
   114         dst_curr_ptr = &((*dst_curr_ptr)->next);
   115     }
   116 
   117     return bloblist;
   118 
   119 enomem:
   120     free(blob2);
   121     free_bloblist(bloblist);
   122     return NULL;
   123 }
   124 
   125 DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
   126         const char *mime_type, const char *filename)
   127 {
   128     assert(blob);
   129     if (blob == NULL)
   130         return NULL;
   131 
   132     if (bloblist == NULL)
   133         return new_bloblist(blob, size, mime_type, filename);
   134 
   135     if (bloblist->value == NULL) { // empty list
   136         if (bloblist->next != NULL)
   137             return NULL; // invalid list
   138             
   139         if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
   140             free(bloblist);
   141             bloblist = NULL;
   142         }
   143 
   144         return bloblist;
   145     }
   146 
   147     bloblist_t* list_curr = bloblist;
   148 
   149     while (list_curr->next)
   150         list_curr = list_curr->next;
   151 
   152     list_curr->next = new_bloblist(blob, size, mime_type, filename);
   153 
   154     assert(list_curr->next);
   155     if (list_curr->next == NULL)
   156         return NULL;
   157 
   158     return list_curr->next;
   159 
   160 }
   161 
   162 DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
   163 {
   164     int len = 0;
   165 
   166     for (const bloblist_t *_bl = bloblist; _bl && _bl->value; _bl = _bl->next)
   167         len++;
   168 
   169     return len;
   170 }
   171 
   172 
   173 DYNAMIC_API bloblist_t* bloblist_iterate(bloblist_t *bloblist, bool(*func)(bloblist_t* element))
   174 {
   175     while(bloblist && !func(bloblist))
   176     {
   177         bloblist = bloblist->next;
   178     }
   179     return bloblist;
   180 }
   181 
   182 
   183 DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
   184                                       content_disposition_type disposition) {
   185     if (blob)                                    
   186         blob->disposition = disposition;
   187 }