1 // This file is under GNU General Public License 3.0
12 static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
19 bloblist->mime_type = strdup(mime_type);
20 if (bloblist->mime_type == NULL) {
26 bloblist->filename = strdup(filename);
27 if (bloblist->filename == NULL) {
28 free(bloblist->mime_type);
31 /* Default behaviour, can be overwritten post-allocation with
32 set_blob_content_disposition */
33 if (strncmp(filename, "cid://", 6) == 0)
34 bloblist->disposition = PEP_CONTENT_DISP_INLINE;
38 bloblist->value = blob;
39 bloblist->size = size;
45 DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
48 bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
53 if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
61 DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
63 bloblist_t *curr = bloblist;
66 bloblist_t *next = curr->next;
67 if (curr->release_value)
68 curr->release_value(curr->value);
71 free(curr->mime_type);
78 DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
84 bloblist_t* head_ptr = NULL;
85 bloblist_t** dst_curr_ptr = &head_ptr;
87 const bloblist_t* src_curr = src;
91 for ( ; src_curr; src_curr = src_curr->next, dst_curr_ptr = &((*dst_curr_ptr)->next)) {
92 blob2 = malloc(src_curr->size);
98 // This is why we don't calloc
99 memcpy(blob2, src_curr->value, src_curr->size);
101 *dst_curr_ptr = new_bloblist(blob2, src_curr->size, src_curr->mime_type, src_curr->filename);
102 if (*dst_curr_ptr == NULL)
113 free_bloblist(head_ptr);
117 DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
118 const char *mime_type, const char *filename)
125 return new_bloblist(blob, size, mime_type, filename);
127 if (!bloblist->value) { // empty list
128 assert(!bloblist->next);
130 return NULL; // invalid list
132 if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
140 bloblist_t* list_curr = bloblist;
141 void (*release_value)(char *) = list_curr->release_value;
143 while (list_curr->next)
144 list_curr = list_curr->next;
146 list_curr->next = new_bloblist(blob, size, mime_type, filename);
147 list_curr->next->release_value = release_value;
149 assert(list_curr->next);
150 if (!list_curr->next)
153 return list_curr->next;
156 DYNAMIC_API bloblist_t* bloblist_join(bloblist_t* first, bloblist_t* second) {
165 bloblist_t* list_curr = first;
167 while (list_curr->next) {
168 list_curr = list_curr->next;
170 list_curr->next = second;
175 DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
179 for (const bloblist_t *_bl = bloblist; _bl && _bl->value; _bl = _bl->next)
185 DYNAMIC_API void set_blob_disposition(bloblist_t* blob,
186 content_disposition_type disposition)
189 blob->disposition = disposition;