src/bloblist.c
author Krista Bennett <krista@pep-project.org>
Tue, 01 Aug 2017 16:40:24 +0200
branchmessage-2.0
changeset 1979 3d0a778d035a
parent 1871 51337eb65533
child 1987 313073d93cd9
permissions -rw-r--r--
Changed name to ENGINE-214 for JIRA tracking - please use that branch instead.
     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 DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    13         const char *filename)
    14 {
    15     bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
    16     assert(bloblist);
    17     if (bloblist == NULL)
    18         return NULL;
    19 
    20     if (mime_type) {
    21         bloblist->mime_type = strdup(mime_type);
    22         if (bloblist->mime_type == NULL) {
    23             free(bloblist);
    24             return NULL;
    25         }
    26     }
    27 
    28     if (filename) {
    29         bloblist->filename = strdup(filename);
    30         if (bloblist->filename == NULL) {
    31             free(bloblist->mime_type);
    32             free(bloblist);
    33             return NULL;
    34         }
    35     }
    36 
    37     if (blob) {
    38         bloblist->value = blob;
    39         bloblist->size = size;
    40     }
    41 
    42     return bloblist;
    43 }
    44 
    45 DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
    46 {
    47     bloblist_t *curr = bloblist;
    48 
    49     while (curr) {
    50         bloblist_t *next = curr->next;
    51         free(curr->value);
    52         free(curr->mime_type);
    53         free(curr->filename);
    54         free(curr);
    55         curr = next;
    56     }
    57 }
    58 
    59 DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
    60 {
    61     assert(src);
    62     if (src == NULL)
    63         return NULL;
    64     
    65     bloblist_t *bloblist = NULL;
    66 
    67     // head
    68     char *blob2 = malloc(src->size);
    69     assert(blob2);
    70     if (blob2 == NULL)
    71         goto enomem;
    72 
    73     memcpy(blob2, src->value, src->size);
    74 
    75     bloblist = new_bloblist(blob2, src->size, src->mime_type, src->filename);
    76     if (bloblist == NULL)
    77         goto enomem;
    78     blob2 = NULL;
    79 
    80     bloblist_t* src_curr = src->next;
    81     bloblist_t** dst_curr_ptr = &bloblist->next;
    82 
    83     // list
    84     while (src_curr) {
    85         blob2 = malloc(src_curr->size);
    86 
    87         assert(blob2);
    88         if (blob2 == NULL)
    89             goto enomem;
    90 
    91         memcpy(blob2, src_curr->value, src_curr->size);
    92         *dst_curr_ptr = new_bloblist(blob2, src_curr->size, src_curr->mime_type, src_curr->filename);
    93         if (*dst_curr_ptr == NULL)
    94             goto enomem;
    95 
    96         src_curr = src_curr->next;
    97         dst_curr_ptr = &((*dst_curr_ptr)->next);
    98     }
    99 
   100     return bloblist;
   101 
   102 enomem:
   103     free(blob2);
   104     free_bloblist(bloblist);
   105     return NULL;
   106 }
   107 
   108 DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
   109         const char *mime_type, const char *filename)
   110 {
   111     assert(blob);
   112     if (blob == NULL)
   113         return NULL;
   114 
   115     if (bloblist == NULL)
   116         return new_bloblist(blob, size, mime_type, filename);
   117 
   118     if (bloblist->value == NULL) { // empty list
   119         if (bloblist->next != NULL)
   120             return NULL; // invalid list
   121 
   122         if (mime_type) {
   123             bloblist->mime_type = strdup(mime_type);
   124             if (bloblist->mime_type == NULL) {
   125                 free(bloblist);
   126                 return NULL;
   127             }
   128         }
   129         if (filename) {
   130             bloblist->filename = strdup(filename);
   131             if (bloblist->filename == NULL) {
   132                 free(bloblist->mime_type);
   133                 free(bloblist);
   134                 return NULL;
   135             }
   136         }
   137 
   138         bloblist->value = blob;
   139         bloblist->size = size;
   140 
   141         return bloblist;
   142     }
   143 
   144     bloblist_t* list_curr = bloblist;
   145 
   146     while (list_curr->next)
   147         list_curr = list_curr->next;
   148 
   149     list_curr->next = new_bloblist(blob, size, mime_type, filename);
   150 
   151     assert(list_curr->next);
   152     if (list_curr->next == NULL)
   153         return NULL;
   154 
   155     return list_curr->next;
   156 
   157 }
   158 
   159 DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
   160 {
   161     int len = 0;
   162 
   163     for (const bloblist_t *_bl = bloblist; _bl && _bl->value; _bl = _bl->next)
   164         len++;
   165 
   166     return len;
   167 }