[Gauche-devel-jp] Re: dbm.fsdbmで、バイナリデータをreadする時にエラー

Back to archive index

Shiro Kawai shiro****@lava*****
2004年 9月 12日 (日) 20:14:08 JST


From: yamada <yamad****@tir*****>
Subject: [Gauche-devel-jp] dbm.fsdbmで、バイナリデータをreadする時にエラー
Date: Sun, 12 Sep 2004 12:15:47 +0900

> 山田です。
> 
> dbm.fsdbmに、バイナリデータ(画像データ)を保存し、
> あとでそれを読み取るような事をさせようとしています。
> 保存は正常に行えるのですが、読み取り時に、
> 
> encountered EOF in middle of a multibyte character from
> port #<iport fsdbm内のファイル名>
> 
> のようなエラーになってしまいました。

ご指摘ありがとうございます。fsdbmでport->stringを安易に使ったのが
失敗でした。portutilには手を加えず、次のように解決することにしました。

--shiro




--- lib/dbm/fsdbm.scm	4 Feb 2004 22:20:26 -0000	1.6
+++ lib/dbm/fsdbm.scm	12 Sep 2004 11:05:09 -0000	1.7
@@ -30,7 +30,7 @@
 ;;;   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 ;;;   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ;;;  
-;;;  $Id: fsdbm.scm,v 1.6 2004/02/04 22:20:26 shirok Exp $
+;;;  $Id: fsdbm.scm,v 1.7 2004/09/12 11:05:09 shirok Exp $
 ;;;
 
 (define-module dbm.fsdbm
@@ -136,7 +136,7 @@
   (next-method)
   (let ((path (value-file-path (%dbm-k2s self key) (ref self 'path))))
     (cond ((call-with-input-file path
-             (lambda (p) (and p (%dbm-s2v self (port->string p))))
+             (lambda (p) (and p (%dbm-s2v self (read-chunk p))))
              :if-does-not-exist #f))
           ((pair? args) (car args))
           (else (errorf "fsdbm: no data for key ~s in database ~s"
@@ -161,7 +161,7 @@
         (if k
           (proc (%dbm-s2k self k)
                 (call-with-input-file path
-                  (lambda (p) (%dbm-s2v self (port->string p))))
+                  (lambda (p) (%dbm-s2v self (read-chunk p))))
                 seed)
           seed))))
   (next-method)
@@ -181,8 +181,10 @@
     (errorf "given path is not an fsdbm database: ~a" name))
   (remove-directory* name))
 
+;;
+;; Internal utilities
+;;
 
-;; basic utilities
 (define (fsdbm-directory? path)
   (and (file-is-directory? path)
        (file-exists? (build-path path *version-file*))))
@@ -194,6 +196,15 @@
     (lambda () (display *fsdbm-version*)))
   (sys-mkdir (build-path path *incoming-dir*) (dir-perm mode)))
 
+;; read everything from the port and returns potentially incomplete string
+(define (read-chunk port)
+  (let loop ((elt (read-block 1024 port))
+             (chunks '()))
+    (if (eof-object? elt)
+      (let ((s (string-concatenate-reverse chunks)))
+        (or (string-incomplete->complete! s) s))
+      (loop (read-block 1024 port) (cons elt chunks)))))
+
 (define (dir-perm file-perm)
   ;; trick: we copy 'r' bits to 'x' bits to make sure the 'readable'
   ;; database is also searchable.





Gauche-devel-jp メーリングリストの案内
Back to archive index