X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=mime-def.el;h=2444b426888d8c9055ba4a619545225191086b4a;hb=eb9783f46dee7de4c9372e428a26e384e04d60f8;hp=d5e5525d2495078744c0ec713ad95d2c1ee1eaf1;hpb=a464fea43696d79afaee0064f2f58122adb2cfaa;p=elisp%2Fflim.git diff --git a/mime-def.el b/mime-def.el index d5e5525..2444b42 100644 --- a/mime-def.el +++ b/mime-def.el @@ -5,7 +5,7 @@ ;; Author: MORIOKA Tomohiko ;; Keywords: definition, MIME, multimedia, mail, news -;; This file is part of FLIM (Faithful Library about Internet Message). +;; This file is part of FLAM (Faithful Library About MIME). ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -24,15 +24,26 @@ ;;; Code: -(defconst mime-library-version - '("FLIM" "Tonosh.DNr" 1 9 1) - "Implementation name, version name and numbers of MIME-library package.") +(eval-and-compile + (defconst mime-library-product ["FLAM-DOODLE" (1 10 2) "$B@VGrFK(B 5.0YR8.0/6.0"] + "Product name, version number and code name of MIME-library package.") + ) + +(defmacro mime-product-name (product) + `(aref ,product 0)) -(defconst mime-library-version-string - `,(concat (car mime-library-version) " " +(defmacro mime-product-version (product) + `(aref ,product 1)) + +(defmacro mime-product-code-name (product) + `(aref ,product 2)) + +(defconst mime-library-version + (eval-when-compile + (concat (mime-product-name mime-library-product) " " (mapconcat #'number-to-string - (cddr mime-library-version) ".") - " - \"" (cadr mime-library-version) "\"")) + (mime-product-version mime-library-product) ".") + " - \"" (mime-product-code-name mime-library-product) "\""))) ;;; @ variables @@ -107,7 +118,30 @@ (concat mime-token-regexp "/" mime-token-regexp)) -;;; @@ Quoted-Printable +;;; @@ base64 / B +;;; + +(defconst base64-token-regexp "[A-Za-z0-9+/]") +(defconst base64-token-padding-regexp "[A-Za-z0-9+/=]") + +(defconst B-encoded-text-regexp + (concat "\\(\\(" + base64-token-regexp + base64-token-regexp + base64-token-regexp + base64-token-regexp + "\\)*" + base64-token-regexp + base64-token-regexp + base64-token-padding-regexp + base64-token-padding-regexp + "\\)")) + +;; (defconst eword-B-encoding-and-encoded-text-regexp +;; (concat "\\(B\\)\\?" eword-B-encoded-text-regexp)) + + +;;; @@ Quoted-Printable / Q ;;; (defconst quoted-printable-hex-chars "0123456789ABCDEF") @@ -116,6 +150,12 @@ (concat "=[" quoted-printable-hex-chars "][" quoted-printable-hex-chars "]")) +(defconst Q-encoded-text-regexp + (concat "\\([^=?]\\|" quoted-printable-octet-regexp "\\)+")) + +;; (defconst eword-Q-encoding-and-encoded-text-regexp +;; (concat "\\(Q\\)\\?" eword-Q-encoded-text-regexp)) + ;;; @ Content-Type ;;; @@ -275,9 +315,14 @@ message/rfc822, `mime-entity' structures of them are included in ;;; @ for mm-backend ;;; +(require 'alist) + (defvar mime-entity-implementation-alist nil) (defmacro mm-define-backend (type &optional parents) + "Define TYPE as a mm-backend. +If PARENTS is specified, TYPE inherits PARENTS. +Each parent must be backend name (symbol)." (if parents `(let ((rest ',(reverse parents))) (while rest @@ -290,6 +335,11 @@ message/rfc822, `mime-entity' structures of them are included in )))) (defmacro mm-define-method (name args &rest body) + "Define NAME as a method function of (nth 1 (car ARGS)) backend. + +ARGS is like an argument list of lambda, but (car ARGS) must be +specialized parameter. (car (car ARGS)) is name of variable and (nth +1 (car ARGS)) is name of backend." (let* ((specializer (car args)) (class (nth 1 specializer)) (self (car specializer))) @@ -310,6 +360,128 @@ message/rfc822, `mime-entity' structures of them are included in (put 'mm-define-method 'edebug-form-spec '(&define name ((arg symbolp) &rest arg) def-body)) +(defsubst mm-arglist-to-arguments (arglist) + (let (dest) + (while arglist + (let ((arg (car arglist))) + (or (memq arg '(&optional &rest)) + (setq dest (cons arg dest))) + ) + (setq arglist (cdr arglist))) + (nreverse dest))) + + +;;; @ for mel-backend +;;; + +(defvar mel-service-list nil) + +(defmacro mel-define-service (name &optional args &rest rest) + "Define NAME as a service for Content-Transfer-Encodings. +If ARGS is specified, NAME is defined as a generic function for the +service." + `(progn + (add-to-list 'mel-service-list ',name) + (defvar ,(intern (format "%s-obarray" name)) (make-vector 1 nil)) + ,@(if args + `((defun ,name ,args + ,@rest + (funcall (mel-find-function ',name ,(car (last args))) + ,@(mm-arglist-to-arguments (butlast args))) + ))) + )) + +(put 'mel-define-service 'lisp-indent-function 'defun) + + +(defvar mel-encoding-module-alist nil) + +(defsubst mel-find-function-from-obarray (ob-array encoding) + (let* ((f (intern-soft encoding ob-array))) + (or f + (let ((rest (cdr (assoc encoding mel-encoding-module-alist)))) + (while (and rest + (progn + (require (car rest)) + (null (setq f (intern-soft encoding ob-array))) + )) + (setq rest (cdr rest)) + ) + f)))) + +(defsubst mel-copy-method (service src-backend dst-backend) + (let* ((oa (symbol-value (intern (format "%s-obarray" service)))) + (f (mel-find-function-from-obarray oa src-backend)) + sym) + (when f + (setq sym (intern dst-backend oa)) + (or (fboundp sym) + (fset sym (symbol-function f)) + )))) + +(defsubst mel-copy-backend (src-backend dst-backend) + (let ((services mel-service-list)) + (while services + (mel-copy-method (car services) src-backend dst-backend) + (setq services (cdr services))))) + +(defmacro mel-define-backend (type &optional parents) + "Define TYPE as a mel-backend. +If PARENTS is specified, TYPE inherits PARENTS. +Each parent must be backend name (string)." + (cons 'progn + (mapcar (lambda (parent) + `(mel-copy-backend ,parent ,type) + ) + parents))) + +(defmacro mel-define-method (name args &rest body) + "Define NAME as a method function of (nth 1 (car (last ARGS))) backend. +ARGS is like an argument list of lambda, but (car (last ARGS)) must be +specialized parameter. (car (car (last ARGS))) is name of variable +and (nth 1 (car (last ARGS))) is name of backend (encoding)." + (let* ((specializer (car (last args))) + (class (nth 1 specializer))) + `(progn + (mel-define-service ,name) + (fset (intern ,class ,(intern (format "%s-obarray" name))) + (lambda ,(butlast args) + ,@body))))) + +(put 'mel-define-method 'lisp-indent-function 'defun) + +(defmacro mel-define-method-function (spec function) + "Set SPEC's function definition to FUNCTION. +First element of SPEC is service. +Rest of ARGS is like an argument list of lambda, but (car (last ARGS)) +must be specialized parameter. (car (car (last ARGS))) is name of +variable and (nth 1 (car (last ARGS))) is name of backend (encoding)." + (let* ((name (car spec)) + (args (cdr spec)) + (specializer (car (last args))) + (class (nth 1 specializer))) + `(let (sym) + (mel-define-service ,name) + (setq sym (intern ,class ,(intern (format "%s-obarray" name)))) + (or (fboundp sym) + (fset sym (symbol-function ,function)))))) + +(defmacro mel-define-function (function spec) + (let* ((name (car spec)) + (args (cdr spec)) + (specializer (car (last args))) + (class (nth 1 specializer))) + `(progn + (define-function ,function + (intern ,class ,(intern (format "%s-obarray" name)))) + ))) + +(defvar base64-dl-module + (and (fboundp 'dynamic-link) + (let ((path (expand-file-name "base64.so" exec-directory))) + (and (file-exists-p path) + path)))) + ;;; @ end ;;;