Encode a string to be suitable for an RFC2231 header.
If the value is large, the list will contain continuation lines.
358{
359 if (!attribute || !value)
360 return 0;
361
362 size_t count = 0;
364 bool add_quotes = false;
365 bool free_src_value = false;
366 bool split = false;
367 int continuation_number = 0;
368 size_t dest_value_len = 0;
369 size_t max_value_len = 0;
370 size_t cur_value_len = 0;
371 char *cur = NULL;
372 char *charset = NULL;
373 char *src_value = NULL;
375
378
379
380 for (cur = value; *cur; cur++)
381 {
382 if ((*cur < 0x20) || (*cur >= 0x7f))
383 {
385 break;
386 }
387 }
388
390 {
393 if (c_charset && c_send_charset)
394 {
397 }
398 if (src_value)
399 free_src_value = true;
400 if (!charset)
401 charset =
mutt_str_dup(c_charset ? c_charset :
"unknown-8bit");
402 }
403 if (!src_value)
404 src_value = value;
405
406
409
410 for (cur = src_value; *cur; cur++)
411 {
412 dest_value_len++;
413
415 {
416
417 if ((*cur < 0x20) || (*cur >= 0x7f) || strchr(
MimeSpecials, *cur) ||
418 strchr("*'%", *cur))
419 {
420 dest_value_len += 2;
421 }
422 }
423 else
424 {
425
427 add_quotes = true;
428
429 if ((*cur == '\\') || (*cur == '"'))
430 dest_value_len++;
431 }
432 }
433
434
435 max_value_len = 78 -
436 1 -
439 1 -
440 (add_quotes ? 2 : 0) -
441 1;
442
443 if (max_value_len < 30)
444 max_value_len = 30;
445
446 if (dest_value_len > max_value_len)
447 {
448 split = true;
449 max_value_len -= 4;
450
451 }
452
453
454 cur = src_value;
456 {
458 cur_value_len =
buf_len(cur_value);
459 }
460
461 while (*cur)
462 {
466
468 if (split)
472
473 while (*cur && (!split || (cur_value_len < max_value_len)))
474 {
476 {
477 if ((*cur < 0x20) || (*cur >= 0x7f) || strchr(
MimeSpecials, *cur) ||
478 strchr("*'%", *cur))
479 {
481 cur_value_len += 3;
482 }
483 else
484 {
486 cur_value_len++;
487 }
488 }
489 else
490 {
492 cur_value_len++;
493 if ((*cur == '\\') || (*cur == '"'))
494 cur_value_len++;
495 }
496
497 cur++;
498 }
499
502
504 cur_value_len = 0;
505 }
506
509
511 if (free_src_value)
513
515}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
const struct Slist * cs_subset_slist(const struct ConfigSubset *sub, const char *name)
Get a string-list config item by name.
const char MimeSpecials[]
Characters that need special treatment in MIME.
char * mutt_ch_choose(const char *fromcode, const struct Slist *charsets, const char *u, size_t ulen, char **d, size_t *dlen)
Figure the best charset to encode a string.
char * mutt_str_dup(const char *str)
Copy a string, safely.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
struct Parameter * mutt_param_new(void)
Create a new Parameter.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
#define TAILQ_INSERT_TAIL(head, elm, field)
static int encode(const char *d, size_t dlen, int col, const char *fromcode, const struct Slist *charsets, char **e, size_t *elen, const char *specials)
RFC2047-encode a string.
String manipulation buffer.
struct ListHead head
List containing values.
size_t count
Number of values in list.