Skip to content
This repository

preserves order of zipfile entries #65

Merged
merged 1 commit into from about 1 year ago

3 participants

Mark Hubbart bootstraponline Alexander Simonov
Mark Hubbart

Makes ZipEntrySet preserve the original order of files in the zipfile.
Also preserves the insertion order of files.

Mark Hubbart preserves order of zipfile entries
Makes ZipEntrySet preserve the original order of files in the zipfile.
Also preserves the insertion order of files.
31259bb
Alexander Simonov simonoff merged commit 66f0c0f into from February 07, 2013
Alexander Simonov simonoff closed this February 07, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Oct 19, 2012
Mark Hubbart preserves order of zipfile entries
Makes ZipEntrySet preserve the original order of files in the zipfile.
Also preserves the insertion order of files.
31259bb
This page is out of date. Refresh to see the latest.
20  lib/zip/zip_entry_set.rb
@@ -5,6 +5,7 @@ class ZipEntrySet #:nodoc:all
5 5
     def initialize(anEnumerable = [])
6 6
       super()
7 7
       @entrySet = {}
  8
+      @entryOrder = []
8 9
       anEnumerable.each { |o| push(o) }
9 10
     end
10 11
 
@@ -17,6 +18,8 @@ def find_entry(entry)
17 18
     end
18 19
 
19 20
     def <<(entry)
  21
+      @entryOrder.delete( to_key(entry) )
  22
+      @entryOrder << to_key(entry)
20 23
       @entrySet[to_key(entry)] = entry
21 24
     end
22 25
     alias :push :<<
@@ -28,25 +31,30 @@ def size
28 31
     alias :length :size
29 32
 
30 33
     def delete(entry)
31  
-      @entrySet.delete(to_key(entry)) ? entry : nil
  34
+      @entryOrder.delete(to_key(entry)) && @entrySet.delete(to_key(entry)) ?
  35
+        entry :
  36
+        nil
32 37
     end
33 38
 
34 39
     def each(&aProc)
35  
-      @entrySet.values.each(&aProc)
  40
+      @entryOrder.each do |key|
  41
+        aProc.call @entrySet[key]
  42
+      end
36 43
     end
37 44
 
38 45
     def entries
39  
-      @entrySet.values
  46
+      @entryOrder.map{|key| @entrySet[key] }
40 47
     end
41 48
 
42 49
     # deep clone
43 50
     def dup
44  
-      ZipEntrySet.new(@entrySet.values.map { |e| e.dup })
  51
+      ZipEntrySet.new(@entryOrder.map { |key| @entrySet[key].dup })
45 52
     end
46 53
 
47 54
     def ==(other)
48 55
       return false unless other.kind_of?(ZipEntrySet)
49  
-      @entrySet == other.entrySet      
  56
+      @entrySet == other.entrySet &&
  57
+      @entryOrder == other.entryOrder
50 58
     end
51 59
 
52 60
     def parent(entry)
@@ -63,7 +71,7 @@ def glob(pattern, flags = ::File::FNM_PATHNAME|::File::FNM_DOTMATCH)
63 71
 
64 72
 #TODO    attr_accessor :auto_create_directories
65 73
     protected
66  
-    attr_accessor :entrySet
  74
+    attr_accessor :entrySet, :entryOrder
67 75
 
68 76
     private
69 77
     def to_key(entry)
28  test/ziptest.rb
@@ -1459,6 +1459,34 @@ def test_changeComment
1459 1459
     zfRead = ZipFile.open(TEST_ZIP.zip_name)
1460 1460
     assert_equal("my changed comment", zfRead.comment)
1461 1461
   end
  1462
+  
  1463
+  def test_preserve_file_order
  1464
+    entryNames = nil
  1465
+    ZipFile.open(TEST_ZIP.zip_name) {
  1466
+      |zf|
  1467
+      entryNames = zf.entries.map{|e|e.to_s}
  1468
+      zf.get_output_stream("a.txt"){|os| os.write "this is a.txt"}
  1469
+      zf.get_output_stream("z.txt"){|os| os.write "this is z.txt"}
  1470
+      zf.get_output_stream("k.txt"){|os| os.write "this is k.txt"}
  1471
+      entryNames << "a.txt" << "z.txt" << "k.txt"
  1472
+    }
  1473
+
  1474
+    ZipFile.open(TEST_ZIP.zip_name) {
  1475
+      |zf|
  1476
+      assert_equal(entryNames, zf.entries.map{|e|e.to_s})
  1477
+      entries = zf.entries.sort_by{|e|e.name}.reverse
  1478
+      entries.each {
  1479
+        |e|
  1480
+        zf.remove e
  1481
+        zf.get_output_stream(e){|os| os.write "foo"}
  1482
+      }
  1483
+      entryNames = entries.map{|e|e.to_s}
  1484
+    }
  1485
+    ZipFile.open(TEST_ZIP.zip_name) {
  1486
+      |zf|
  1487
+      assert_equal(entryNames, zf.entries.map{|e|e.to_s})
  1488
+    }
  1489
+  end
1462 1490
 
1463 1491
   private
1464 1492
   def assert_contains(zf, entryName, filename = entryName)
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.