* ew-dec.el (ew-decode-us-ascii): New function.
[elisp/flim.git] / ew-unit.el
1 (require 'closure)
2 (require 'ew-line)
3 (require 'ew-quote)
4 (require 'mel)
5
6 (provide 'ew-unit)
7
8 (defconst ew-anchored-encoded-word-regexp
9   (concat "\\`" ew-encoded-word-regexp "\\'"))
10
11 (defconst ew-b-regexp
12   (concat "\\`\\("
13           "[A-Za-z0-9+/]"
14           "[A-Za-z0-9+/]"
15           "[A-Za-z0-9+/]"
16           "[A-Za-z0-9+/]"
17           "\\)*"
18           "[A-Za-z0-9+/]"
19           "[A-Za-z0-9+/]"
20           "\\(==\\|"
21           "[A-Za-z0-9+/]"
22           "[A-Za-z0-9+/=]"
23           "\\)\\'"))
24
25 (defconst ew-q-regexp "\\`\\([^=?]\\|=[0-9A-Fa-f][0-9A-Fa-f]\\)*\\'")
26
27 (defconst ew-byte-decoder-alist
28   '(("B" . ew-b-decode)
29     ("Q" . ew-q-decode)))
30
31 (defconst ew-byte-checker-alist
32   '(("B" . ew-b-check)
33     ("Q" . ew-q-check)))
34
35 (defun ew-b-check (encoding encoded-text) (string-match ew-b-regexp encoded-text))
36 (defun ew-q-check (encoding encoded-text) (string-match ew-q-regexp encoded-text))
37
38 (defun ew-eword-p (str)
39   (let ((len (length str)))
40     (and
41      (<= 3 len)
42      (eq (aref str 0) ?=)
43      (eq (aref str 1) ??)
44      (eq (aref str (- len 2)) ??)
45      (eq (aref str (1- len)) ?=))))
46
47 (defun ew-decode-eword (str &optional eword-filter1 eword-filter2)
48   (if (string-match ew-anchored-encoded-word-regexp str)
49       (let ((charset (match-string 1 str))
50             (encoding (match-string 2 str))
51             (encoded-text (match-string 3 str))
52             bdec cdec
53             bcheck
54             tmp)
55         (if (and (setq bdec (ew-byte-decoder encoding))
56                  (setq cdec (ew-char-decoder charset)))
57             (if (or (null (setq bcheck (ew-byte-checker encoding)))
58                     (funcall bcheck encoding encoded-text))
59                 (progn
60                   (setq tmp (closure-call cdec (funcall bdec encoded-text)))
61                   (when eword-filter1 (setq tmp (closure-call eword-filter1 tmp)))
62                   (setq tmp (ew-quote tmp))
63                   (when eword-filter2 (setq tmp (closure-call eword-filter2 tmp)))
64                   tmp)
65               (ew-quote str))
66           (ew-quote-eword charset encoding encoded-text)))
67     (ew-quote str)))
68
69 (defun ew-byte-decoder (encoding)
70   (cdr (assoc (upcase encoding) ew-byte-decoder-alist)))
71
72 (defun ew-byte-checker (encoding)
73   (cdr (assoc (upcase encoding) ew-byte-checker-alist)))
74
75 (defalias 'ew-b-decode 'base64-decode-string)
76 (defalias 'ew-q-decode 'q-encoding-decode-string)
77
78 (defun ew-char-decoder (charset)
79   (let ((sym (intern (downcase charset))))
80     (when (mime-charset-to-coding-system sym 'LF)
81       (closure-make
82        (lambda (str) (decode-mime-charset-string str sym 'LF))
83        sym))))