Mercurial > hg > xemacs-beta
diff lisp/mel/mel-b.el @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | |
children | 4b173ad71786 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/mel/mel-b.el Mon Aug 13 08:46:56 2007 +0200 @@ -0,0 +1,292 @@ +;;; +;;; mel-b.el: Base64 encoder/decoder for GNU Emacs +;;; +;;; Copyright (C) 1995 Free Software Foundation, Inc. +;;; Copyright (C) 1992 ENAMI Tsugutomo +;;; Copyright (C) 1995,1996 MORIOKA Tomohiko +;;; +;;; Author: ENAMI Tsugutomo <enami@sys.ptg.sony.co.jp> +;;; MORIOKA Tomohiko <morioka@jaist.ac.jp> +;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp> +;;; Created: 1995/6/24 +;;; Version: +;;; $Id: mel-b.el,v 1.1.1.1 1996/12/18 03:55:30 steve Exp $ +;;; Keywords: MIME, Base64 +;;; +;;; This file is part of MEL (MIME Encoding Library). +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 2, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with This program. If not, write to the Free Software +;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;;; +;;; Code: + +(require 'emu) + + +;;; @ variables +;;; + +(defvar base64-external-encoder '("mmencode") + "*list of base64 encoder program name and its arguments.") + +(defvar base64-external-decoder '("mmencode" "-u") + "*list of base64 decoder program name and its arguments.") + +(defvar base64-internal-encoding-limit 1000 + "*limit size to use internal base64 encoder. +If size of input to encode is larger than this limit, +external encoder is called.") + +(defvar base64-internal-decoding-limit 1000 + "*limit size to use internal base64 decoder. +If size of input to decode is larger than this limit, +external decoder is called.") + + +;;; @ internal base64 decoder/encoder +;;; based on base64 decoder by Enami Tsugutomo + +;;; @@ convert from/to base64 char +;;; + +(defun base64-num-to-char (n) + (cond ((eq n nil) ?=) + ((< n 26) (+ ?A n)) + ((< n 52) (+ ?a (- n 26))) + ((< n 62) (+ ?0 (- n 52))) + ((= n 62) ?+) + ((= n 63) ?/) + (t (error "not a base64 integer %d" n)))) + +(defun base64-char-to-num (c) + (cond ((and (<= ?A c) (<= c ?Z)) (- c ?A)) + ((and (<= ?a c) (<= c ?z)) (+ (- c ?a) 26)) + ((and (<= ?0 c) (<= c ?9)) (+ (- c ?0) 52)) + ((= c ?+) 62) + ((= c ?/) 63) + ((= c ?=) nil) + (t (error "not a base64 character %c" c)))) + + +;;; @@ encode/decode one base64 unit +;;; + +(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 base64-decode-1 (pack) + (let ((a (base64-char-to-num (car pack))) + (b (base64-char-to-num (nth 1 pack))) + (c (nth 2 pack)) + (d (nth 3 pack))) + (concat (char-to-string (logior (ash a 2) (ash b -4))) + (if (and c (setq c (base64-char-to-num c))) + (concat (char-to-string + (logior (ash (logand b 15) 4) (ash c -2))) + (if (and d (setq d (base64-char-to-num d))) + (char-to-string (logior (ash (logand c 3) 6) d)) + )))))) + + +;;; @@ base64 encoder/decoder for string +;;; + +(defun base64-encode-string (string) + (let ((len (length string)) + (b 0)(e 57) + dest) + (while (< e len) + (setq dest + (concat dest + (mapconcat + (function base64-encode-1) + (pack-sequence (substring string b e) 3) + "") + "\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-decode-string (string) + (mapconcat (function base64-decode-1) + (pack-sequence string 4) + "")) + + +;;; @ base64 encoder/decoder for region +;;; + +(defun base64-internal-encode-region (beg end) + (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") + ) + ))) + +(defun base64-internal-decode-region (beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (looking-at ".*\n") + (condition-case err + (replace-match + (base64-decode-string + (buffer-substring (match-beginning 0) (1- (match-end 0)))) + t t) + (error + (prog1 + (message (nth 1 err)) + (replace-match ""))))) + (if (looking-at ".*$") + (condition-case err + (replace-match + (base64-decode-string + (buffer-substring (match-beginning 0) (match-end 0))) + t t) + (error + (prog1 + (message (nth 1 err)) + (replace-match ""))) + )) + ))) + +(defun base64-external-encode-region (beg end) + (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)) + ) + ;; for OS/2 + ;; regularize line break code + (goto-char (point-min)) + (while (re-search-forward "\r$" 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)) + ))) + +(defun base64-encode-region (beg end) + (interactive "r") + (if (and base64-internal-encoding-limit + (> (- end beg) base64-internal-encoding-limit)) + (base64-external-encode-region beg end) + (base64-internal-encode-region beg end) + )) + +(defun base64-decode-region (beg end) + (interactive "r") + (if (and base64-internal-decoding-limit + (> (- end beg) base64-internal-decoding-limit)) + (base64-external-decode-region beg end) + (base64-internal-decode-region beg end) + )) + + +;;; @ base64 encoder/decoder for file +;;; + +(defun base64-insert-encoded-file (filename) + (interactive (list (read-file-name "Insert encoded file: "))) + (apply (function call-process) (car base64-external-encoder) + filename t nil (cdr base64-external-encoder)) + ) + + +;;; @ etc +;;; + +(defun base64-encoded-length (string) + (let ((len (length string))) + (* (+ (/ len 3) + (if (= (mod len 3) 0) 0 1) + ) 4) + )) + +(defun pack-sequence (seq size) + "Split sequence SEQ into SIZE elements packs, +and return list of packs. [mel-b; 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 +;;; + +(provide 'mel-b) + +;;; mel-b.el ends here.