comparison src/lib-imap-storage/imap-msgpart-url.c @ 14622:6fb61872b30a

lib-imap-storage: imap-msgpart rewrite and API change. The new API allows first parsing the validity of section strings and later relying on them being valid without having to re-parse it. The implementation also fixes a few things and adds "partial fetch cache".
author Timo Sirainen <tss@iki.fi>
date Thu, 21 Jun 2012 21:50:35 +0300
parents 27c8a6c9088d
children 1af9d08e67d7
comparison
equal deleted inserted replaced
14621:bf8a885c2077 14622:6fb61872b30a
1 /* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
2
1 #include "lib.h" 3 #include "lib.h"
2 #include "network.h" 4 #include "network.h"
3 #include "istream.h" 5 #include "istream.h"
4 #include "message-parser.h" 6 #include "message-parser.h"
5 #include "mail-storage.h" 7 #include "mail-storage.h"
160 mpurl->mail = mail; 162 mpurl->mail = mail;
161 *mail_r = mail; 163 *mail_r = mail;
162 return 1; 164 return 1;
163 } 165 }
164 166
167 static int
168 imap_msgpart_url_open_part(struct imap_msgpart_url *mpurl, struct mail **mail_r,
169 struct imap_msgpart **msgpart_r, const char **error_r)
170 {
171 int ret;
172
173 if ((ret = imap_msgpart_url_open_mail(mpurl, mail_r, error_r)) <= 0)
174 return ret;
175
176 if (imap_msgpart_parse((*mail_r)->box, mpurl->section, msgpart_r) < 0) {
177 *error_r = "Invalid section";
178 return 0;
179 }
180 imap_msgpart_set_partial(*msgpart_r, mpurl->partial_offset,
181 mpurl->partial_size == 0 ? (uoff_t)-1 :
182 mpurl->partial_size);
183 return 1;
184 }
185
165 int imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl, 186 int imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl,
166 struct istream **stream_r, uoff_t *size_r, 187 struct istream **stream_r, uoff_t *size_r,
167 const char **error_r) 188 const char **error_r)
168 { 189 {
169 struct mail *mail; 190 struct mail *mail;
170 struct istream *input; 191 struct imap_msgpart *msgpart;
171 uoff_t part_size; 192 struct imap_msgpart_open_result result;
172 int ret; 193 int ret;
173 194
174 if (mpurl->input != NULL) { 195 if (mpurl->input != NULL) {
175 i_stream_seek(mpurl->input, 0); 196 i_stream_seek(mpurl->input, 0);
176 *stream_r = mpurl->input; 197 *stream_r = mpurl->input;
177 *size_r = mpurl->part_size; 198 *size_r = mpurl->part_size;
178 return 1; 199 return 1;
179 } 200 }
180 201
181 /* open mail if it is not yet open */ 202 /* open mail if it is not yet open */
182 if ((ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r)) <= 0) 203 ret = imap_msgpart_url_open_part(mpurl, &mail, &msgpart, error_r);
204 if (ret <= 0)
183 return ret; 205 return ret;
184 206
185 /* open the referenced part as a stream */ 207 /* open the referenced part as a stream */
186 if ((ret = imap_msgpart_open(mail, mpurl->section, 208 ret = imap_msgpart_open(mail, msgpart, &result);
187 mpurl->partial_offset, mpurl->partial_size, 209 imap_msgpart_free(&msgpart);
188 &input, &part_size, error_r)) <= 0) 210 if (ret < 0) {
189 return ret; 211 *error_r = mailbox_get_last_error(mail->box, NULL);
190 212 return ret;
191 mpurl->input = input; 213 }
192 mpurl->part_size = part_size; 214
193 215 *stream_r = mpurl->input = result.input;
194 *stream_r = input; 216 *size_r = mpurl->part_size = result.size;
195 *size_r = part_size;
196 return 1; 217 return 1;
197 } 218 }
198 219
199 int imap_msgpart_url_verify(struct imap_msgpart_url *mpurl, 220 int imap_msgpart_url_verify(struct imap_msgpart_url *mpurl,
200 const char **error_r) 221 const char **error_r)
201 { 222 {
202 struct mail *mail; 223 struct mail *mail;
224 struct imap_msgpart *msgpart;
203 int ret; 225 int ret;
204 226
205 if (mpurl->input != NULL) 227 if (mpurl->input != NULL)
206 return 1; 228 return 1;
207 229
208 /* open mail if it is not yet open */ 230 /* open mail if it is not yet open */
209 if ((ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r)) <= 0) 231 ret = imap_msgpart_url_open_part(mpurl, &mail, &msgpart, error_r);
210 return ret; 232 if (ret > 0)
211 233 imap_msgpart_free(&msgpart);
212 /* open the referenced part as a stream */ 234 return ret;
213 return imap_msgpart_verify(mail, mpurl->section, error_r);
214 } 235 }
215 236
216 void imap_msgpart_url_free(struct imap_msgpart_url **_mpurl) 237 void imap_msgpart_url_free(struct imap_msgpart_url **_mpurl)
217 { 238 {
218 struct imap_msgpart_url *mpurl = *_mpurl; 239 struct imap_msgpart_url *mpurl = *_mpurl;