X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=mel-b-el.el;h=eac60b57e851afa4981ad5404df565121d2485b1;hb=e3697d7a1aa5dd7b573c5ff3f320ed03fd6614bd;hp=7426cc539ef1e32bcfbe35f64ceff7efe6f9364b;hpb=f7230fcb61e32630f6bcf87e6eb8b35c564dd06c;p=elisp%2Fflim.git diff --git a/mel-b-el.el b/mel-b-el.el index 7426cc5..eac60b5 100644 --- a/mel-b-el.el +++ b/mel-b-el.el @@ -1,13 +1,13 @@ -;;; mel-b-el.el: Base64 encoder/decoder for GNU Emacs +;;; mel-b-el.el --- Base64 encoder/decoder. -;; Copyright (C) 1992,1995,1996,1997,1998 Free Software Foundation, Inc. +;; Copyright (C) 1992,95,96,97,98,99,2001 Free Software Foundation, Inc. ;; Author: ENAMI Tsugutomo -;; MORIOKA Tomohiko +;; MORIOKA Tomohiko ;; Created: 1995/6/24 ;; Keywords: MIME, Base64 -;; This file is part of MEL (MIME Encoding Library). +;; This file is part of FLIM (Faithful Library about Internet Message). ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -20,14 +20,16 @@ ;; General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the +;; along with this program; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Code: -(require 'poe) (require 'mime-def) +(eval-when-compile + ;; XXX: the macro `as-binary-process' should be provided when compiling. + (require 'pces)) ;;; @ variables @@ -48,7 +50,8 @@ :type '(cons (file :tag "Command")(repeat :tag "Arguments" string))) (defcustom base64-external-decoder-option-to-specify-file '("-o") - "*list of options of base64 decoder program to specify file." + "*list of options of base64 decoder program to specify file. +If the base64 decoder program does not have such option, set this as nil." :group 'base64 :type '(repeat :tag "Arguments" string)) @@ -72,6 +75,26 @@ external decoder is called." (integer :tag "Size"))) +;;; @ utility function +;;; + +(defun pack-sequence (seq size) + "Split sequence SEQ into SIZE elements packs, and return list of packs. +\[mel-b-el; tl-seq function]" + (let ((len (length seq)) + (p 0) + dest unit) + (while (< p len) + (setq unit (cons (elt seq p) unit)) + (setq p (1+ p)) + (when (zerop (mod p size)) + (setq dest (cons (nreverse unit) dest)) + (setq unit nil))) + (if unit + (nreverse (cons (nreverse unit) dest)) + (nreverse dest)))) + + ;;; @ internal base64 encoder ;;; based on base64 decoder by Enami Tsugutomo @@ -84,33 +107,33 @@ external decoder is called." `(aref base64-characters ,n)) (defun base64-encode-1 (pack) - (let ((a (car pack)) - (b (nth 1 pack)) - (c (nth 2 pack))) - (concat - (char-to-string (base64-num-to-char (ash a -2))) - (if b - (concat - (char-to-string - (base64-num-to-char (logior (ash (logand a 3) 4) (ash b -4)))) - (if c - (concat - (char-to-string - (base64-num-to-char (logior (ash (logand b 15) 2) (ash c -6)))) - (char-to-string (base64-num-to-char (logand c 63))) - ) - (concat (char-to-string - (base64-num-to-char (ash (logand b 15) 2))) "=") - )) - (concat (char-to-string - (base64-num-to-char (ash (logand a 3) 4))) "==") - )))) - -(defun-maybe base64-encode-string (string) - "Encode STRING to base64, and return the result." - (let ((len (length string)) - (b 0)(e 57) - dest) + (let ((buf (make-string 4 ?=))) + (aset buf 0 (base64-num-to-char (ash (car pack) -2))) + (if (nth 1 pack) + (progn + (aset buf 1 (base64-num-to-char + (logior (ash (logand (car pack) 3) 4) + (ash (nth 1 pack) -4)))) + (if (nth 2 pack) + (progn + (aset buf 2 (base64-num-to-char + (logior (ash (logand (nth 1 pack) 15) 2) + (ash (nth 2 pack) -6)))) + (aset buf 3 (base64-num-to-char + (logand (nth 2 pack) 63)))) + (aset buf 2 (base64-num-to-char + (ash (logand (nth 1 pack) 15) 2))))) + (aset buf 1 (base64-num-to-char + (ash (logand (car pack) 3) 4)))) + buf)) + +(defun-maybe base64-encode-string (string &optional no-line-break) + "Base64-encode STRING and return the result. +Optional second argument NO-LINE-BREAK means do not break long lines +into shorter lines." + (let* ((len (length string)) + (b 0)(e 57) + (dest "")) (while (< e len) (setq dest (concat dest @@ -118,34 +141,23 @@ external decoder is called." (function base64-encode-1) (pack-sequence (substring string b e) 3) "") - "\n")) + (if (not no-line-break) "\n"))) (setq b e - e (+ e 57) - ) - ) - (let* ((es (mapconcat - (function base64-encode-1) - (pack-sequence (substring string b) 3) - "")) - (m (mod (length es) 4)) - ) - (concat dest es (cond ((= m 3) "=") - ((= m 2) "==") - )) - ))) - -(defun base64-internal-encode-region (beg end) + e (+ e 57))) + (concat dest + (mapconcat + (function base64-encode-1) + (pack-sequence (substring string b) 3) + "")))) + +(defun base64-internal-encode-region (beg end &optional no-line-break) (save-excursion (save-restriction (narrow-to-region beg end) - (let ((str (buffer-substring beg end))) - (delete-region beg end) - (insert (base64-encode-string str)) - ) - (or (bolp) - (insert "\n") - ) - ))) + (insert + (prog1 + (base64-encode-string (buffer-substring beg end) no-line-break) + (delete-region beg end)))))) ;;; @ internal base64 decoder @@ -166,8 +178,7 @@ external decoder is called." (defsubst base64-internal-decode (string buffer) (let* ((len (length string)) - (i 0) - (j 0) + (i 0)(j 0) v1 v2 v3) (catch 'tag (while (< i len) @@ -187,12 +198,9 @@ external decoder is called." (if v4 (aset buffer (prog1 j (setq j (1+ j))) (logior (lsh (logand v3 3) 6) v4)) - (throw 'tag nil) - )) - (throw 'tag nil) - )))) - (substring buffer 0 j) - )) + (throw 'tag nil))) + (throw 'tag nil))))) + (substring buffer 0 j))) (defun base64-internal-decode-string (string) (base64-internal-decode string (make-string (length string) 0))) @@ -204,9 +212,10 @@ external decoder is called." (defun base64-internal-decode-region (beg end) (save-excursion (let ((str (string-as-unibyte (buffer-substring beg end)))) - (delete-region beg end) - (goto-char beg) - (insert (base64-internal-decode str str))))) + (insert + (prog1 + (base64-internal-decode str str) + (delete-region beg end)))))) ;; (defun base64-internal-decode-region2 (beg end) ;; (save-excursion @@ -226,56 +235,63 @@ external decoder is called." ;;; @ external encoder/decoder ;;; -(defun base64-external-encode-region (beg end) +(defun base64-external-encode-region (beg end &optional no-line-break) (save-excursion (save-restriction (narrow-to-region beg end) (as-binary-process (apply (function call-process-region) beg end (car base64-external-encoder) - t t nil (cdr base64-external-encoder))) + t t nil + (cdr base64-external-encoder))) ;; for OS/2 ;; regularize line break code (goto-char (point-min)) (while (re-search-forward "\r$" nil t) (replace-match "")) - ))) + (if no-line-break + (progn + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match ""))))))) (defun base64-external-decode-region (beg end) (save-excursion (as-binary-process (apply (function call-process-region) beg end (car base64-external-decoder) - t t nil (cdr base64-external-decoder))) - )) + t t nil + (cdr base64-external-decoder))))) (defun base64-external-decode-string (string) (with-temp-buffer (insert string) (as-binary-process (apply (function call-process-region) - (point-min) (point-max) - (car base64-external-decoder) - t t nil (cdr base64-external-decoder))) + (point-min)(point-max) (car base64-external-decoder) + t t nil + (cdr base64-external-decoder))) (buffer-string))) ;;; @ application interfaces ;;; -(defun-maybe base64-encode-region (start end) - "Encode current region by base64. -START and END are buffer positions. +(defun-maybe base64-encode-region (start end &optional no-line-break) + "Base64-encode the region between START and END. +Return the length of the encoded text. +Optional third argument NO-LINE-BREAK means do not break long lines +into shorter lines. This function calls internal base64 encoder if size of region is smaller than `base64-internal-encoding-limit', otherwise it calls external base64 encoder specified by `base64-external-encoder'. In this case, you must install the program (maybe mmencode included in metamail or XEmacs package)." - (interactive "r") + (interactive "*r") (if (and base64-internal-encoding-limit (> (- end start) base64-internal-encoding-limit)) - (base64-external-encode-region start end) - (base64-internal-encode-region start end))) + (base64-external-encode-region start end no-line-break) + (base64-internal-encode-region start end no-line-break))) (defun-maybe base64-decode-region (start end) "Decode current region by base64. @@ -285,7 +301,7 @@ smaller than `base64-internal-decoding-limit', otherwise it calls external base64 decoder specified by `base64-external-decoder'. In this case, you must install the program (maybe mmencode included in metamail or XEmacs package)." - (interactive "r") + (interactive "*r") (if (and base64-internal-decoding-limit (> (- end start) base64-internal-decoding-limit)) (base64-external-decode-region start end) @@ -298,7 +314,6 @@ smaller than `base64-internal-decoding-limit', otherwise it calls external base64 decoder specified by `base64-external-decoder'. In this case, you must install the program (maybe mmencode included in metamail or XEmacs package)." - (interactive "r") (if (and base64-internal-decoding-limit (> (length string) base64-internal-decoding-limit)) (base64-external-decode-string string) @@ -318,8 +333,9 @@ metamail or XEmacs package)." 'base64-encode-string) (mel-define-method encoded-text-decode-string (string (nil "B")) - (if (and (string-match B-encoded-text-regexp string) - (string= string (match-string 0 string))) + (if (string-match (eval-when-compile + (concat "\\`" B-encoded-text-regexp "\\'")) + string) (base64-decode-string string) (error "Invalid encoded-text %s" string))) @@ -328,21 +344,21 @@ metamail or XEmacs package)." It calls external base64 encoder specified by `base64-external-encoder'. So you must install the program (maybe mmencode included in metamail or XEmacs package)." - (interactive (list (read-file-name "Insert encoded file: "))) + (interactive "*fInsert encoded file: ") (if (and base64-internal-encoding-limit (> (nth 7 (file-attributes filename)) base64-internal-encoding-limit)) - (apply (function call-process) (car base64-external-encoder) - filename t nil (cdr base64-external-encoder)) + (apply (function call-process) + (car base64-external-encoder) + filename t nil + (cdr base64-external-encoder)) (insert (base64-encode-string (with-temp-buffer (set-buffer-multibyte nil) (insert-file-contents-as-binary filename) (buffer-string)))) - (or (bolp) - (insert "\n")) - )) + (or (bolp) (insert ?\n)))) (mel-define-method-function (mime-insert-encoded-file filename (nil "base64")) 'base64-insert-encoded-file) @@ -350,56 +366,34 @@ mmencode included in metamail or XEmacs package)." (defun base64-write-decoded-region (start end filename) "Decode and write current region encoded by base64 into FILENAME. START and END are buffer positions." - (interactive - (list (region-beginning) (region-end) - (read-file-name "Write decoded region to file: "))) + (interactive "*r\nFWrite decoded region to file: ") (if (and base64-internal-decoding-limit (> (- end start) base64-internal-decoding-limit)) - (as-binary-process - (apply (function call-process-region) - start end (car base64-external-decoder) - nil nil nil - (append (cdr base64-external-decoder) - base64-external-decoder-option-to-specify-file - (list filename)))) + (progn + (as-binary-process + (apply (function call-process-region) + start end (car base64-external-decoder) + (null base64-external-decoder-option-to-specify-file) + (unless base64-external-decoder-option-to-specify-file + (list (current-buffer) nil)) + nil + (delq nil + (append + (cdr base64-external-decoder) + base64-external-decoder-option-to-specify-file + (when base64-external-decoder-option-to-specify-file + (list filename)))))) + (unless base64-external-decoder-option-to-specify-file + (write-region-as-binary (point-min) (point-max) filename))) (let ((str (buffer-substring start end))) (with-temp-buffer (insert (base64-internal-decode-string str)) - (write-region-as-binary (point-min) (point-max) filename) - )))) + (write-region-as-binary (point-min) (point-max) filename))))) (mel-define-method-function (mime-write-decoded-region start end filename (nil "base64")) 'base64-write-decoded-region) - -;;; @ etc -;;; - -(defun pack-sequence (seq size) - "Split sequence SEQ into SIZE elements packs, -and return list of packs. [mel-b-el; tl-seq function]" - (let ((len (length seq)) (p 0) obj - unit (i 0) - dest) - (while (< p len) - (setq obj (elt seq p)) - (setq unit (cons obj unit)) - (setq i (1+ i)) - (if (= i size) - (progn - (setq dest (cons (reverse unit) dest)) - (setq unit nil) - (setq i 0) - )) - (setq p (1+ p)) - ) - (if unit - (setq dest (cons (reverse unit) dest)) - ) - (reverse dest) - )) - ;;; @ end ;;;