From f7c3381baa8fbbc90b827d43635456562499ccb3 Mon Sep 17 00:00:00 2001 From: hmurata Date: Sat, 23 Sep 2006 05:56:08 +0000 Subject: [PATCH] * elmo-pop3.el (toplevel): Require elmo-map. (elmo-pop3-folder): Inherit elmo-location-map and abolish location-alist slot (All other related portions are changed). (elmo-pop3-folder-use-uidl): New function. (elmo-folder-msgdb-create): Don't sort message entities. (elmo-pop3-sort-msgdb-by-original-number): Abolish. (elmo-pop3-number-to-size): Convert return value to number. (elmo-pop3-msgdb-create-by-header): Use unwind-protect to delete a working buffer. * elmo-map.el: Use `location-map' as a variable name for instance instead of `mapper'. (elmo-location-map-setup): Return location alist. (elmo-location-map-update): Ditto. --- elmo/ChangeLog | 17 +++++ elmo/elmo-map.el | 78 ++++++++++---------- elmo/elmo-pop3.el | 205 ++++++++++++++++++++--------------------------------- 3 files changed, 135 insertions(+), 165 deletions(-) diff --git a/elmo/ChangeLog b/elmo/ChangeLog index 81b6895..37499b2 100644 --- a/elmo/ChangeLog +++ b/elmo/ChangeLog @@ -1,3 +1,20 @@ +2006-09-23 Hiroya Murata + + * elmo-pop3.el (toplevel): Require elmo-map. + (elmo-pop3-folder): Inherit elmo-location-map and abolish + location-alist slot (All other related portions are changed). + (elmo-pop3-folder-use-uidl): New function. + (elmo-folder-msgdb-create): Don't sort message entities. + (elmo-pop3-sort-msgdb-by-original-number): Abolish. + (elmo-pop3-number-to-size): Convert return value to number. + (elmo-pop3-msgdb-create-by-header): Use unwind-protect to delete a + working buffer. + + * elmo-map.el: Use `location-map' as a variable name for instance + instead of `mapper'. + (elmo-location-map-setup): Return location alist. + (elmo-location-map-update): Ditto. + 2006-09-21 Hiroya Murata * elmo-map.el (elmo-location-map): New class; split location and diff --git a/elmo/elmo-map.el b/elmo/elmo-map.el index 50bc2ac..2576f05 100644 --- a/elmo/elmo-map.el +++ b/elmo/elmo-map.el @@ -60,19 +60,21 @@ (defmacro elmo-location-map-key (number) `(concat "#" (int-to-string ,number))) -(defun elmo-location-map-load (mapper directory) +(defun elmo-location-map-load (location-map directory) (elmo-location-map-setup - mapper + location-map (elmo-msgdb-location-load directory))) -(defun elmo-location-map-save (mapper directory) - (let ((alist (elmo-location-map-alist mapper))) +(defun elmo-location-map-save (location-map directory) + (let ((alist (elmo-location-map-alist location-map))) (elmo-msgdb-location-save directory - (cons (cons (elmo-location-map-max-number mapper) nil) + (cons (cons (elmo-location-map-max-number location-map) nil) alist)))) -(defun elmo-location-map-setup (mapper locations) +(defun elmo-location-map-setup (location-map locations) + "Setup internal data of LOCATION-MAP by LOCATIONS. +Return a location alist." (let ((hash (elmo-make-hash (length locations))) (max-number 0)) ;; Set number-max and hashtables. @@ -82,23 +84,25 @@ (elmo-set-hash-val (cdr pair) pair hash) (elmo-set-hash-val (elmo-location-map-key (car pair)) pair hash))) (let ((inhibit-quit t)) - (elmo-location-map-set-max-number mapper max-number) - (elmo-location-map-set-alist mapper locations) - (elmo-location-map-set-hash mapper hash)))) - -(defun elmo-location-map-teardown (mapper) - (elmo-location-map-set-alist mapper nil) - (elmo-location-map-set-hash mapper nil)) - -(defun elmo-location-map-clear (mapper) - (elmo-location-map-set-max-number mapper 0) - (elmo-location-map-set-alist mapper nil) - (elmo-location-map-set-hash mapper (elmo-make-hash))) - -(defun elmo-location-map-update (mapper locations) - (let ((old-hash (elmo-location-map-hash mapper)) + (elmo-location-map-set-max-number location-map max-number) + (elmo-location-map-set-hash location-map hash) + (elmo-location-map-set-alist location-map locations)))) + +(defun elmo-location-map-teardown (location-map) + (elmo-location-map-set-alist location-map nil) + (elmo-location-map-set-hash location-map nil)) + +(defun elmo-location-map-clear (location-map) + (elmo-location-map-set-max-number location-map 0) + (elmo-location-map-set-alist location-map nil) + (elmo-location-map-set-hash location-map (elmo-make-hash))) + +(defun elmo-location-map-update (location-map locations) + "Update location alist in LOCATION-MAP by LOCATIONS. +Return new location alist." + (let ((old-hash (elmo-location-map-hash location-map)) (new-hash (elmo-make-hash (length locations))) - (number (elmo-location-map-max-number mapper)) + (number (elmo-location-map-max-number location-map)) new-alist) (setq new-alist (mapcar @@ -112,50 +116,50 @@ entry)) locations)) (let ((inhibit-quit t)) - (elmo-location-map-set-max-number mapper number) - (elmo-location-map-set-alist mapper new-alist) - (elmo-location-map-set-hash mapper new-hash)))) + (elmo-location-map-set-max-number location-map number) + (elmo-location-map-set-hash location-map new-hash) + (elmo-location-map-set-alist location-map new-alist)))) -(defun elmo-location-map-remove-numbers (mapper numbers) - (let ((alist (elmo-location-map-alist mapper)) - (hash (elmo-location-map-hash mapper))) +(defun elmo-location-map-remove-numbers (location-map numbers) + (let ((alist (elmo-location-map-alist location-map)) + (hash (elmo-location-map-hash location-map))) (dolist (number numbers) (let* ((key (elmo-location-map-key number)) (entry (elmo-get-hash-val key hash)) (inhibit-quit t)) (elmo-location-map-set-alist - mapper + location-map (setq alist (delq entry alist))) (elmo-clear-hash-val key hash) (elmo-clear-hash-val (cdr entry) hash))))) -(defun elmo-map-message-number (mapper location) +(defun elmo-map-message-number (location-map location) "Return number of the message in the MAPPER with LOCATION." (car (elmo-get-hash-val location - (elmo-location-map-hash mapper)))) + (elmo-location-map-hash location-map)))) -(defun elmo-map-message-location (mapper number) +(defun elmo-map-message-location (location-map number) "Return location of the message in the MAPPER with NUMBER." (cdr (elmo-get-hash-val (elmo-location-map-key number) - (elmo-location-map-hash mapper)))) + (elmo-location-map-hash location-map)))) -(defun elmo-map-numbers-to-locations (mapper numbers) +(defun elmo-map-numbers-to-locations (location-map numbers) (let (locations pair) (dolist (number numbers) (if (setq pair (elmo-get-hash-val (elmo-location-map-key number) - (elmo-location-map-hash mapper))) + (elmo-location-map-hash location-map))) (setq locations (cons (cdr pair) locations)))) (nreverse locations))) -(defun elmo-map-locations-to-numbers (mapper locations) +(defun elmo-map-locations-to-numbers (location-map locations) (let (numbers pair) (dolist (location locations) (if (setq pair (elmo-get-hash-val location - (elmo-location-map-hash mapper))) + (elmo-location-map-hash location-map))) (setq numbers (cons (car pair) numbers)))) (nreverse numbers))) diff --git a/elmo/elmo-pop3.el b/elmo/elmo-pop3.el index 96a18ec..14e98e3 100644 --- a/elmo/elmo-pop3.el +++ b/elmo/elmo-pop3.el @@ -33,6 +33,7 @@ (require 'elmo-msgdb) (require 'elmo-net) +(require 'elmo-map) (eval-when-compile (require 'elmo-util)) @@ -88,10 +89,15 @@ Debug information is inserted in the buffer \"*POP3 DEBUG*\"") ;;; ELMO POP3 folder (eval-and-compile - (luna-define-class elmo-pop3-folder (elmo-net-folder) - (use-uidl location-alist)) + (luna-define-class elmo-pop3-folder (elmo-net-folder elmo-location-map) + (use-uidl)) (luna-define-internal-accessors 'elmo-pop3-folder)) +(defsubst elmo-pop3-folder-use-uidl (folder) + (if elmo-inhibit-number-mapping + nil + (elmo-pop3-folder-use-uidl-internal folder))) + (luna-define-method elmo-folder-initialize ((folder elmo-pop3-folder) name) (let ((elmo-network-stream-type-alist (if elmo-pop3-stream-type-alist @@ -168,10 +174,7 @@ Debug information is inserted in the buffer \"*POP3 DEBUG*\"") "Get POP3 session for FOLDER. If IF-EXISTS is non-nil, don't get new session. If IF-EXISTS is `any-exists', get BIFF session or normal session if exists." - (let ((elmo-pop3-use-uidl-internal (if elmo-inhibit-number-mapping - nil - (elmo-pop3-folder-use-uidl-internal - folder)))) + (let ((elmo-pop3-use-uidl-internal (elmo-pop3-folder-use-uidl folder))) (prog1 (if (eq if-exists 'any-exists) (or (elmo-network-get-session 'elmo-pop3-session @@ -568,32 +571,7 @@ until the login delay period has expired")) (error "POP3: Error in UIDL"))))) (defun elmo-pop3-list-folder-by-location (folder locations) - (let* ((location-alist (elmo-pop3-folder-location-alist-internal folder)) - (locations-in-db (mapcar 'cdr location-alist)) - result new-locs new-alist deleted-locs i) - (setq new-locs - (elmo-delete-if (function - (lambda (x) (member x locations-in-db))) - locations)) - (setq deleted-locs - (elmo-delete-if (function - (lambda (x) (member x locations))) - locations-in-db)) - (setq i (or (elmo-max-of-list (mapcar 'car location-alist)) 0)) - (mapcar - (function - (lambda (x) - (setq location-alist - (delq (rassoc x location-alist) location-alist)))) - deleted-locs) - (while new-locs - (setq i (1+ i)) - (setq new-alist (cons (cons i (car new-locs)) new-alist)) - (setq new-locs (cdr new-locs))) - (setq result (nconc location-alist new-alist)) - (setq result (sort result (lambda (x y) (< (car x)(car y))))) - (elmo-pop3-folder-set-location-alist-internal folder result) - (mapcar 'car result))) + (mapcar #'car (elmo-location-map-update folder locations))) (defun elmo-pop3-list-by-uidl-subr (folder &optional nonsort) (let ((flist (elmo-pop3-list-folder-by-location @@ -619,8 +597,7 @@ until the login delay period has expired")) (error "POP3: Error in list"))))) (defsubst elmo-pop3-folder-list-messages (folder) - (if (and (not elmo-inhibit-number-mapping) - (elmo-pop3-folder-use-uidl-internal folder)) + (if (elmo-pop3-folder-use-uidl folder) (elmo-pop3-list-by-uidl-subr folder) (elmo-pop3-list-by-list folder))) @@ -631,15 +608,15 @@ until the login delay period has expired")) (luna-define-method elmo-folder-status ((folder elmo-pop3-folder)) (elmo-folder-open-internal folder) (elmo-folder-check folder) - (if (elmo-pop3-folder-use-uidl-internal folder) + (if (elmo-pop3-folder-use-uidl folder) (prog1 (elmo-pop3-list-by-uidl-subr folder 'nonsort) (elmo-folder-close-internal folder)) - (let* ((process - (elmo-network-session-process-internal - (elmo-pop3-get-session folder))) - (total 0) - response) + (let ((process + (elmo-network-session-process-internal + (elmo-pop3-get-session folder))) + (total 0) + response) (with-current-buffer (process-buffer process) (elmo-pop3-send-command process "STAT") (setq response (cdr (elmo-pop3-read-response process))) @@ -715,30 +692,11 @@ until the login delay period has expired")) (let ((process (elmo-network-session-process-internal (elmo-pop3-get-session folder)))) (with-current-buffer (process-buffer process) - (elmo-pop3-sort-msgdb-by-original-number + (elmo-pop3-msgdb-create-by-header folder - (elmo-pop3-msgdb-create-by-header - folder - process - numlist - flag-table - (if (elmo-pop3-folder-use-uidl-internal folder) - (elmo-pop3-folder-location-alist-internal folder))))))) - -(defun elmo-pop3-sort-msgdb-by-original-number (folder msgdb) - (let ((location-alist (elmo-pop3-folder-location-alist-internal folder))) - (when location-alist - (elmo-msgdb-sort-entities - msgdb - (lambda (ent1 ent2 loc-alist) - (< (elmo-pop3-uidl-to-number - (cdr (assq (elmo-message-entity-number ent1) - loc-alist))) - (elmo-pop3-uidl-to-number - (cdr (assq (elmo-message-entity-number ent2) - loc-alist))))) - location-alist)) - msgdb)) + process + (sort numlist #'<) + flag-table)))) (defun elmo-pop3-uidl-to-number (uidl) (string-to-number (elmo-get-hash-val uidl @@ -749,40 +707,39 @@ until the login delay period has expired")) elmo-pop3-number-uidl-hash)) (defun elmo-pop3-number-to-size (number) - (elmo-get-hash-val (format "#%d" number) - elmo-pop3-size-hash)) + (string-to-number + (elmo-get-hash-val (format "#%d" number) elmo-pop3-size-hash))) (defun elmo-pop3-msgdb-create-by-header (folder process numlist - flag-table - loc-alist) + flag-table) (let ((tmp-buffer (get-buffer-create " *ELMO Overview TMP*"))) - (with-current-buffer (process-buffer process) - (if loc-alist ; use uidl. - (setq numlist - (delq - nil - (mapcar - (lambda (number) - (elmo-pop3-uidl-to-number (cdr (assq number loc-alist)))) - numlist)))) - (elmo-pop3-retrieve-headers process tmp-buffer numlist) - (prog1 + (unwind-protect + (with-current-buffer (process-buffer process) + (when (elmo-pop3-folder-use-uidl folder) + (setq numlist + (delq + nil + (mapcar + (lambda (number) + (elmo-pop3-uidl-to-number + (elmo-map-message-location folder number))) + numlist)))) + (elmo-pop3-retrieve-headers process tmp-buffer numlist) (elmo-pop3-msgdb-create-message folder tmp-buffer process (length numlist) numlist - flag-table loc-alist) - (kill-buffer tmp-buffer))))) + flag-table)) + (kill-buffer tmp-buffer)))) (defun elmo-pop3-msgdb-create-message (folder buffer process num numlist - flag-table - loc-alist) + flag-table) (save-excursion (let ((new-msgdb (elmo-make-msgdb)) beg entity i number message-id flags) @@ -808,16 +765,14 @@ until the login delay period has expired")) (elmo-message-entity-set-field entity 'size - (string-to-number - (elmo-pop3-number-to-size - (elmo-message-entity-number entity)))) - (if (setq number - (car - (rassoc - (elmo-pop3-number-to-uidl - (elmo-message-entity-number entity)) - loc-alist))) - (elmo-message-entity-set-number entity number))) + (elmo-pop3-number-to-size + (elmo-message-entity-number entity))) + (when (setq number + (elmo-map-message-number + folder + (elmo-pop3-number-to-uidl + (elmo-message-entity-number entity)))) + (elmo-message-entity-set-number entity number))) (setq message-id (elmo-message-entity-field entity 'message-id) flags (elmo-flag-table-get flag-table message-id)) (elmo-global-flags-set flags folder number message-id) @@ -845,19 +800,16 @@ until the login delay period has expired")) t))) (luna-define-method elmo-folder-open-internal ((folder elmo-pop3-folder)) - (if (and (not elmo-inhibit-number-mapping) - (elmo-pop3-folder-use-uidl-internal folder)) - (elmo-pop3-folder-set-location-alist-internal - folder (elmo-msgdb-location-load (elmo-folder-msgdb-path folder))))) + (when (elmo-pop3-folder-use-uidl folder) + (elmo-location-map-load folder (elmo-folder-msgdb-path folder)))) (luna-define-method elmo-folder-commit :after ((folder elmo-pop3-folder)) - (when (elmo-folder-persistent-p folder) - (elmo-msgdb-location-save (elmo-folder-msgdb-path folder) - (elmo-pop3-folder-location-alist-internal - folder)))) + (when (and (not elmo-inhibit-number-mapping) + (elmo-folder-persistent-p folder)) + (elmo-location-map-save folder (elmo-folder-msgdb-path folder)))) (luna-define-method elmo-folder-close-internal ((folder elmo-pop3-folder)) - (elmo-pop3-folder-set-location-alist-internal folder nil) + (elmo-location-map-teardown folder) ;; Just close connection (elmo-folder-check folder)) @@ -865,16 +817,14 @@ until the login delay period has expired")) number strategy &optional section outbuf unseen) - (let* ((loc-alist (elmo-pop3-folder-location-alist-internal folder)) - (process (elmo-network-session-process-internal - (elmo-pop3-get-session folder))) + (let ((process (elmo-network-session-process-internal + (elmo-pop3-get-session folder))) size response errmsg msg) (with-current-buffer (process-buffer process) - (if loc-alist - (setq number (elmo-pop3-uidl-to-number - (cdr (assq number loc-alist))))) - (setq size (string-to-number - (elmo-pop3-number-to-size number))) + (when (elmo-pop3-folder-use-uidl folder) + (setq number (elmo-pop3-uidl-to-number + (elmo-map-message-location folder number)))) + (setq size (elmo-pop3-number-to-size number)) (when number (elmo-pop3-send-command process (format "retr %s" number)) @@ -904,29 +854,28 @@ until the login delay period has expired")) (elmo-delete-cr-buffer) response)))) -(defun elmo-pop3-delete-msg (process number loc-alist) - (with-current-buffer (process-buffer process) - (let (response errmsg msg) - (if loc-alist - (setq number (elmo-pop3-uidl-to-number - (cdr (assq number loc-alist))))) - (if number - (progn - (elmo-pop3-send-command process - (format "dele %s" number)) - (when (null (setq response (cdr (elmo-pop3-read-response - process t)))) - (error "Deleting message failed"))) - (error "Deleting message failed"))))) +(defun elmo-pop3-delete-msg (process number) + (unless number + (error "Deleting message failed")) + (elmo-pop3-send-command process (format "dele %s" number)) + (when (null (cdr (elmo-pop3-read-response process t))) + (error "Deleting message failed"))) (luna-define-method elmo-folder-delete-messages-plugged ((folder elmo-pop3-folder) msgs) - (let ((loc-alist (elmo-pop3-folder-location-alist-internal folder)) - (process (elmo-network-session-process-internal + (let ((process (elmo-network-session-process-internal (elmo-pop3-get-session folder)))) - (mapcar '(lambda (msg) (elmo-pop3-delete-msg process msg loc-alist)) - msgs))) + (with-current-buffer (process-buffer process) + (dolist (number (if (elmo-pop3-folder-use-uidl folder) + (mapcar + (lambda (number) + (elmo-pop3-uidl-to-number + (elmo-map-message-location folder number))) + msgs) + msgs)) + (elmo-pop3-delete-msg process number)) + t))) (luna-define-method elmo-message-use-cache-p ((folder elmo-pop3-folder) number) elmo-pop3-use-cache) @@ -938,7 +887,7 @@ until the login delay period has expired")) (luna-define-method elmo-folder-clear :around ((folder elmo-pop3-folder) &optional keep-killed) (unless keep-killed - (elmo-pop3-folder-set-location-alist-internal folder nil)) + (elmo-location-map-clear folder)) (luna-call-next-method)) (luna-define-method elmo-folder-check ((folder elmo-pop3-folder)) -- 1.7.10.4