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