* elmo-pop3.el (toplevel): Require elmo-map.
authorhmurata <hmurata>
Sat, 23 Sep 2006 05:56:08 +0000 (05:56 +0000)
committerhmurata <hmurata>
Sat, 23 Sep 2006 05:56:08 +0000 (05:56 +0000)
(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
elmo/elmo-map.el
elmo/elmo-pop3.el

index 81b6895..37499b2 100644 (file)
@@ -1,3 +1,20 @@
+2006-09-23  Hiroya Murata  <lapis-lazuli@pop06.odn.ne.jp>
+
+       * 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  <lapis-lazuli@pop06.odn.ne.jp>
 
        * elmo-map.el (elmo-location-map): New class; split location and
index 50bc2ac..2576f05 100644 (file)
 (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.
        (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
               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)))
 
index 96a18ec..14e98e3 100644 (file)
@@ -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))