Line data Source code
1 : /** 2 : * @file 3 : * Store attributes associated with a MIME part 4 : * 5 : * @authors 6 : * Copyright (C) 2017 Richard Russon <rich@flatcap.org> 7 : * 8 : * @copyright 9 : * This program is free software: you can redistribute it and/or modify it under 10 : * the terms of the GNU General Public License as published by the Free Software 11 : * Foundation, either version 2 of the License, or (at your option) any later 12 : * version. 13 : * 14 : * This program is distributed in the hope that it will be useful, but WITHOUT 15 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 : * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 : * details. 18 : * 19 : * You should have received a copy of the GNU General Public License along with 20 : * this program. If not, see <http://www.gnu.org/licenses/>. 21 : */ 22 : 23 : /** 24 : * @page email_parameter Store attributes associated with a MIME part 25 : * 26 : * Store attributes associated with a MIME part 27 : */ 28 : 29 : #include "config.h" 30 : #include <stddef.h> 31 : #include <stdbool.h> 32 : #include "mutt/lib.h" 33 : #include "parameter.h" 34 : 35 : /** 36 : * mutt_param_new - Create a new Parameter 37 : * @retval ptr Newly allocated Parameter 38 : */ 39 125 : struct Parameter *mutt_param_new(void) 40 : { 41 125 : return mutt_mem_calloc(1, sizeof(struct Parameter)); 42 : } 43 : 44 : /** 45 : * mutt_param_free_one - Free a Parameter 46 : * @param[out] p Parameter to free 47 : */ 48 129 : void mutt_param_free_one(struct Parameter **p) 49 : { 50 129 : if (!p || !*p) 51 4 : return; 52 125 : FREE(&(*p)->attribute); 53 125 : FREE(&(*p)->value); 54 125 : FREE(p); 55 : } 56 : 57 : /** 58 : * mutt_param_free - Free a ParameterList 59 : * @param pl ParameterList to free 60 : */ 61 69 : void mutt_param_free(struct ParameterList *pl) 62 : { 63 69 : if (!pl) 64 2 : return; 65 : 66 67 : struct Parameter *np = TAILQ_FIRST(pl); 67 67 : struct Parameter *next = NULL; 68 192 : while (np) 69 : { 70 125 : next = TAILQ_NEXT(np, entries); 71 125 : mutt_param_free_one(&np); 72 125 : np = next; 73 : } 74 67 : TAILQ_INIT(pl); 75 : } 76 : 77 : /** 78 : * mutt_param_get - Find a matching Parameter 79 : * @param pl ParameterList 80 : * @param s String to match 81 : * @retval ptr Matching Parameter 82 : * @retval NULL No match 83 : */ 84 127 : char *mutt_param_get(const struct ParameterList *pl, const char *s) 85 : { 86 127 : if (!pl) 87 2 : return NULL; 88 : 89 125 : struct Parameter *np = NULL; 90 254 : TAILQ_FOREACH(np, pl, entries) 91 : { 92 159 : if (mutt_istr_equal(s, np->attribute)) 93 30 : return np->value; 94 : } 95 : 96 95 : return NULL; 97 : } 98 : 99 : /** 100 : * mutt_param_set - Set a Parameter 101 : * @param[in] pl ParameterList 102 : * @param[in] attribute Attribute to match 103 : * @param[in] value Value to set 104 : * 105 : * @note If value is NULL, the Parameter will be deleted 106 : * 107 : * @note If a matching Parameter isn't found a new one will be allocated. 108 : * The new Parameter will be inserted at the front of the list. 109 : */ 110 6 : void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value) 111 : { 112 6 : if (!pl) 113 2 : return; 114 : 115 4 : if (!value) 116 : { 117 2 : mutt_param_delete(pl, attribute); 118 2 : return; 119 : } 120 : 121 2 : struct Parameter *np = NULL; 122 2 : TAILQ_FOREACH(np, pl, entries) 123 : { 124 0 : if (mutt_istr_equal(attribute, np->attribute)) 125 : { 126 0 : mutt_str_replace(&np->value, value); 127 0 : return; 128 : } 129 : } 130 : 131 2 : np = mutt_param_new(); 132 2 : np->attribute = mutt_str_dup(attribute); 133 2 : np->value = mutt_str_dup(value); 134 2 : TAILQ_INSERT_HEAD(pl, np, entries); 135 : } 136 : 137 : /** 138 : * mutt_param_delete - Delete a matching Parameter 139 : * @param[in] pl ParameterList 140 : * @param[in] attribute Attribute to match 141 : */ 142 6 : void mutt_param_delete(struct ParameterList *pl, const char *attribute) 143 : { 144 6 : if (!pl) 145 2 : return; 146 : 147 4 : struct Parameter *np = NULL; 148 4 : TAILQ_FOREACH(np, pl, entries) 149 : { 150 0 : if (mutt_istr_equal(attribute, np->attribute)) 151 : { 152 0 : TAILQ_REMOVE(pl, np, entries); 153 0 : mutt_param_free_one(&np); 154 0 : return; 155 : } 156 : } 157 : } 158 : 159 : /** 160 : * mutt_param_cmp_strict - Strictly compare two ParameterLists 161 : * @param pl1 First parameter 162 : * @param pl2 Second parameter 163 : * @retval true Parameters are strictly identical 164 : */ 165 4 : bool mutt_param_cmp_strict(const struct ParameterList *pl1, const struct ParameterList *pl2) 166 : { 167 4 : if (!pl1 && !pl2) 168 0 : return false; 169 : 170 4 : if ((pl1 == NULL) ^ (pl2 == NULL)) 171 4 : return true; 172 : 173 0 : struct Parameter *np1 = TAILQ_FIRST(pl1); 174 0 : struct Parameter *np2 = TAILQ_FIRST(pl2); 175 : 176 0 : while (np1 && np2) 177 : { 178 0 : if (!mutt_str_equal(np1->attribute, np2->attribute) || 179 0 : !mutt_str_equal(np1->value, np2->value)) 180 : { 181 0 : return false; 182 : } 183 : 184 0 : np1 = TAILQ_NEXT(np1, entries); 185 0 : np2 = TAILQ_NEXT(np2, entries); 186 : } 187 : 188 0 : if (np1 || np2) 189 0 : return false; 190 : 191 0 : return true; 192 : }