From f592cf6e35fd4a5a7d68822f7a690193ccc9f3a2 Mon Sep 17 00:00:00 2001 From: simmone Date: Sun, 9 Feb 2014 17:08:23 +0800 Subject: [PATCH] file/unzip: add help func with-unzip with-unzip-entry --- .../racket-doc/file/scribblings/unzip.scrbl | 30 +++++++++++++++++ .../racket-test/tests/file/unzip-me.zip | Bin 0 -> 439 bytes .../racket-test/tests/file/unzip.rkt | 26 +++++++++++++++ racket/collects/file/unzip.rkt | 31 ++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 pkgs/racket-pkgs/racket-test/tests/file/unzip-me.zip create mode 100644 pkgs/racket-pkgs/racket-test/tests/file/unzip.rkt diff --git a/pkgs/racket-pkgs/racket-doc/file/scribblings/unzip.scrbl b/pkgs/racket-pkgs/racket-doc/file/scribblings/unzip.scrbl index ba2d49e8f7..b3dc8d99b5 100644 --- a/pkgs/racket-pkgs/racket-doc/file/scribblings/unzip.scrbl +++ b/pkgs/racket-pkgs/racket-doc/file/scribblings/unzip.scrbl @@ -30,6 +30,20 @@ aspects of the unpacking, such as the destination directory. @history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]} +@defproc[(with-unzip [zip_file path-string?] + [user_proc (-> path-string? any)]) + void?]{ + +A helper func to wrap unzip with clean temporay unzip files. + +Unzips an entire @exec{zip} archive from file path @racket[zip_file] to a temporary directory. + +The temporary directory is created in the @racket[zip_file]'s directory. + +@racket[user_proc] has this temporary directory path as its parameter. + +When done, delete temporay unzip files and directories.} + @defproc[(make-filesystem-entry-reader [#:dest dest-path (or/c path-string? #f) #f] [#:strip-count strip-count exact-nonnegative-integer? 0] @@ -137,6 +151,22 @@ If @racket[entry] is not in @racket[zipdir], an @history[#:changed "6.0.0.3" @elem{Added the @racket[#:preserve-timestamps?] argument.}]} +@defproc[(with-unzip-entry [zip_file path-string?] + [entry_file path-string?] + [user_proc (-> path-string? any)]) + void?]{ + +A helper func to wrap unzip-entry with clean temporay unzip file. + +Unzip an specific entry from @racket[zip_file] to a temporary directory, @racket[entry_file] is a entry path in @racket[zip_file]. + +The temporary directory is created in the @racket[zip_file]'s directory. + +@racket[user_proc] has this unzipped temporary file path as its parameter. + +When done, delete temporay unzip file.} + + @defproc[(path->zip-path [path path-string?]) bytes?]{ Converts a file name potentially containing path separators in the current diff --git a/pkgs/racket-pkgs/racket-test/tests/file/unzip-me.zip b/pkgs/racket-pkgs/racket-test/tests/file/unzip-me.zip new file mode 100644 index 0000000000000000000000000000000000000000..52237728d272d66cd584c21c0e99338831b01dba GIT binary patch literal 439 zcmWIWW@h1H0D<4po-SYpl;C6#U?@o~F43*ZEYJ^);9*$!?OV_)ApXiI!Vm!0#ukIB zjT>2;Ay^|w({3bRbxtGNunN*0ND)E3^Ty{oX6SKCw$I4X97Bcox|UF z!+LI@i#dTfz?+dtlo^+AcwnA$chIlfNX?0vJoJEaxlRB2{8oW lOJp|+BN?)!u>jQ&gr7O!eh%0|4!fWWWFb literal 0 HcmV?d00001 diff --git a/pkgs/racket-pkgs/racket-test/tests/file/unzip.rkt b/pkgs/racket-pkgs/racket-test/tests/file/unzip.rkt new file mode 100644 index 0000000000..bf52baa9ca --- /dev/null +++ b/pkgs/racket-pkgs/racket-test/tests/file/unzip.rkt @@ -0,0 +1,26 @@ +#lang racket/base +(require file/unzip tests/eli-tester) + +;; test-me.zip's directory structure is test-zip/1/data.dat +(define (test-with-unzip) + (with-unzip "unzip-me.zip" + (lambda (tmp_dir) + (with-input-from-file (build-path tmp_dir "test-zip" "1" "data.dat") + (lambda () + (test (read-line) => "chenxiao")))))) + +(define (test-with-unzip-entry) + (with-unzip-entry "unzip-me.zip" + (build-path "test-zip" "1" "data.dat") + (lambda (tmp_file) + (with-input-from-file tmp_file + (lambda () + (test (read-line) => "chenxiao")))))) + +(define (run-tests) + (test-with-unzip) + (test-with-unzip-entry)) + +(provide tests) +(module+ main (tests)) +(define (tests) (test do (run-tests))) diff --git a/racket/collects/file/unzip.rkt b/racket/collects/file/unzip.rkt index cc7105e1c3..21115ad0b0 100644 --- a/racket/collects/file/unzip.rkt +++ b/racket/collects/file/unzip.rkt @@ -43,6 +43,9 @@ . ->* . any)] + [with-unzip-entry (-> path-string? path-string? (-> path-string? any) any)] + [with-unzip (-> path-string? (-> path-string? any) any)] + [path->zip-path ((or/c string? path?) . -> . bytes?)])) ;; =========================================================================== @@ -359,3 +362,31 @@ (if (path? base) base (current-directory))) + +;; use dynamic-wind to clean temporary files +(define (with-unzip-entry zip_file entry_file user_proc) + (let ([temp_dir #f]) + (dynamic-wind + (lambda () + (set! temp_dir (make-temporary-file "ziptmp~a" 'directory "."))) + (lambda () + (let ([directory_entries (read-zip-directory zip_file)]) + (unzip-entry + zip_file + directory_entries + (path->zip-path entry_file) + (make-filesystem-entry-reader #:dest temp_dir #:exists 'replace)) + (user_proc (build-path temp_dir entry_file)))) + (lambda () + (delete-directory/files temp_dir))))) + +(define (with-unzip zip_file user_proc) + (let ([temp_dir #f]) + (dynamic-wind + (lambda () + (set! temp_dir (make-temporary-file "ziptmp~a" 'directory "."))) + (lambda () + (unzip zip_file (make-filesystem-entry-reader #:dest temp_dir #:exists 'replace)) + (user_proc temp_dir)) + (lambda () + (delete-directory/files temp_dir)))))