Function: rfc2047-decode-encoded-words

rfc2047-decode-encoded-words is a byte-compiled function defined in rfc2047.el.gz.

Signature

(rfc2047-decode-encoded-words WORDS)

Documentation

Decode successive encoded-words in WORDS and return a decoded string.

Each element of WORDS looks like (CHARSET ENCODING ENCODED-TEXT ENCODED-WORD).

Source Code

;; Defined in /usr/src/emacs/lisp/mail/rfc2047.el.gz
(defun rfc2047-decode-encoded-words (words)
  "Decode successive encoded-words in WORDS and return a decoded string.
Each element of WORDS looks like (CHARSET ENCODING ENCODED-TEXT
ENCODED-WORD)."
  (let (cs text rest)
    (dolist (word words)
      (if (and (setq cs (rfc2047-charset-to-coding-system
			 (car word) t))
	       (condition-case code
		   (cond ((char-equal ?B (nth 1 word))
			  (setq text (base64-decode-string
				      (rfc2047-pad-base64 (nth 2 word)))))
			 ((char-equal ?Q (nth 1 word))
			  (setq text (quoted-printable-decode-string
				      (subst-char-in-string
				       ?_ ?  (nth 2 word) t)))))
		 (error
		  (message "%s" (error-message-string code))
		  nil)))
	  (if (and rfc2047-allow-incomplete-encoded-text
		   (eq cs (caar rest)))
	      ;; Concatenate text of which the charset is the same.
	      (setcdr (car rest) (concat (cdar rest) text))
	    (push (cons cs text) rest))
	;; Don't decode encoded-word.
	(push (cons nil (nth 3 word)) rest)))
    (setq words nil)
    (while rest
      ;; FIXME: This looks O(N²).  Can we make it more efficient
      ;; with something like mapconcat?
      (setq words (concat
		   (or (and (setq cs (caar rest))
			    (condition-case code
				(decode-coding-string (cdar rest) cs)
			      (error
			       (message "%s" (error-message-string code))
			       nil)))
		       (concat (when (cdr rest) " ")
			       (cdar rest)
			       (when (and words
					  (not (eq (string-to-char words) ? )))
				 " ")))
		   words)
	    rest (cdr rest)))
    words))