ziperu 0.1.1-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +24 -0
  3. data/LICENSE-rubyzip.txt +24 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +276 -0
  6. data/lib/rubyzip.rb +4 -0
  7. data/lib/zip/central_directory.rb +5 -0
  8. data/lib/zip/compressor.rb +5 -0
  9. data/lib/zip/constants.rb +5 -0
  10. data/lib/zip/crypto/aes_encryption.rb +5 -0
  11. data/lib/zip/crypto/decrypted_io.rb +5 -0
  12. data/lib/zip/crypto/encryption.rb +5 -0
  13. data/lib/zip/crypto/null_encryption.rb +5 -0
  14. data/lib/zip/crypto/traditional_encryption.rb +5 -0
  15. data/lib/zip/crypto.rb +5 -0
  16. data/lib/zip/decompressor.rb +5 -0
  17. data/lib/zip/deflater.rb +5 -0
  18. data/lib/zip/dirtyable.rb +5 -0
  19. data/lib/zip/dos_time.rb +5 -0
  20. data/lib/zip/entry.rb +5 -0
  21. data/lib/zip/entry_set.rb +5 -0
  22. data/lib/zip/errors.rb +5 -0
  23. data/lib/zip/extra_field/aes.rb +5 -0
  24. data/lib/zip/extra_field/generic.rb +5 -0
  25. data/lib/zip/extra_field/ntfs.rb +5 -0
  26. data/lib/zip/extra_field/old_unix.rb +5 -0
  27. data/lib/zip/extra_field/universal_time.rb +5 -0
  28. data/lib/zip/extra_field/unix.rb +5 -0
  29. data/lib/zip/extra_field/unknown.rb +5 -0
  30. data/lib/zip/extra_field/zip64.rb +5 -0
  31. data/lib/zip/extra_field.rb +5 -0
  32. data/lib/zip/file.rb +5 -0
  33. data/lib/zip/file_split.rb +5 -0
  34. data/lib/zip/filesystem/dir.rb +5 -0
  35. data/lib/zip/filesystem/directory_iterator.rb +5 -0
  36. data/lib/zip/filesystem/file.rb +5 -0
  37. data/lib/zip/filesystem/file_stat.rb +5 -0
  38. data/lib/zip/filesystem/zip_file_name_mapper.rb +5 -0
  39. data/lib/zip/filesystem.rb +5 -0
  40. data/lib/zip/inflater.rb +5 -0
  41. data/lib/zip/input_stream.rb +5 -0
  42. data/lib/zip/ioextras/abstract_input_stream.rb +5 -0
  43. data/lib/zip/ioextras/abstract_output_stream.rb +5 -0
  44. data/lib/zip/ioextras/fake_io.rb +5 -0
  45. data/lib/zip/ioextras.rb +5 -0
  46. data/lib/zip/null_compressor.rb +5 -0
  47. data/lib/zip/null_decompressor.rb +5 -0
  48. data/lib/zip/null_input_stream.rb +5 -0
  49. data/lib/zip/output_stream.rb +5 -0
  50. data/lib/zip/pass_thru_compressor.rb +5 -0
  51. data/lib/zip/pass_thru_decompressor.rb +5 -0
  52. data/lib/zip/streamable_directory.rb +5 -0
  53. data/lib/zip/streamable_stream.rb +5 -0
  54. data/lib/zip/version.rb +5 -0
  55. data/lib/zip.rb +19 -0
  56. data/lib/ziperu/3.1/ziperu.so +0 -0
  57. data/lib/ziperu/3.2/ziperu.so +0 -0
  58. data/lib/ziperu/3.3/ziperu.so +0 -0
  59. data/lib/ziperu/3.4/ziperu.so +0 -0
  60. data/lib/ziperu/4.0/ziperu.so +0 -0
  61. data/lib/ziperu/central_directory.rb +136 -0
  62. data/lib/ziperu/compressor.rb +14 -0
  63. data/lib/ziperu/constants.rb +148 -0
  64. data/lib/ziperu/crypto.rb +72 -0
  65. data/lib/ziperu/decompressor.rb +35 -0
  66. data/lib/ziperu/deflater.rb +41 -0
  67. data/lib/ziperu/dirtyable.rb +48 -0
  68. data/lib/ziperu/dos_time.rb +87 -0
  69. data/lib/ziperu/entry.rb +760 -0
  70. data/lib/ziperu/entry_set.rb +147 -0
  71. data/lib/ziperu/errors.rb +154 -0
  72. data/lib/ziperu/extra_field/aes.rb +52 -0
  73. data/lib/ziperu/extra_field/generic.rb +45 -0
  74. data/lib/ziperu/extra_field/ntfs.rb +98 -0
  75. data/lib/ziperu/extra_field/old_unix.rb +52 -0
  76. data/lib/ziperu/extra_field/universal_time.rb +81 -0
  77. data/lib/ziperu/extra_field/unix.rb +45 -0
  78. data/lib/ziperu/extra_field/unknown.rb +37 -0
  79. data/lib/ziperu/extra_field/zip64.rb +86 -0
  80. data/lib/ziperu/extra_field.rb +109 -0
  81. data/lib/ziperu/file.rb +614 -0
  82. data/lib/ziperu/file_split.rb +93 -0
  83. data/lib/ziperu/filesystem/dir.rb +88 -0
  84. data/lib/ziperu/filesystem/directory_iterator.rb +50 -0
  85. data/lib/ziperu/filesystem/file.rb +265 -0
  86. data/lib/ziperu/filesystem/file_stat.rb +112 -0
  87. data/lib/ziperu/filesystem/zip_file_name_mapper.rb +83 -0
  88. data/lib/ziperu/filesystem.rb +76 -0
  89. data/lib/ziperu/inflater.rb +60 -0
  90. data/lib/ziperu/input_stream.rb +296 -0
  91. data/lib/ziperu/ioextras/abstract_input_stream.rb +137 -0
  92. data/lib/ziperu/ioextras/abstract_output_stream.rb +57 -0
  93. data/lib/ziperu/ioextras/fake_io.rb +41 -0
  94. data/lib/ziperu/ioextras.rb +42 -0
  95. data/lib/ziperu/null_compressor.rb +20 -0
  96. data/lib/ziperu/null_decompressor.rb +25 -0
  97. data/lib/ziperu/null_input_stream.rb +55 -0
  98. data/lib/ziperu/output_stream.rb +223 -0
  99. data/lib/ziperu/pass_thru_compressor.rb +29 -0
  100. data/lib/ziperu/pass_thru_decompressor.rb +37 -0
  101. data/lib/ziperu/streamable_directory.rb +15 -0
  102. data/lib/ziperu/streamable_stream.rb +59 -0
  103. data/lib/ziperu/version.rb +7 -0
  104. data/lib/ziperu.rb +116 -0
  105. metadata +156 -0
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ module Ziperu
6
+ module FileSystem
7
+ class Dir # :nodoc:all
8
+ def initialize(mapped_zip)
9
+ @mapped_zip = mapped_zip
10
+ end
11
+
12
+ attr_writer :file
13
+
14
+ def new(directory_name)
15
+ DirectoryIterator.new(entries(directory_name))
16
+ end
17
+
18
+ def open(directory_name)
19
+ dir_iter = new(directory_name)
20
+ if block_given?
21
+ begin
22
+ yield(dir_iter)
23
+ return nil
24
+ ensure
25
+ dir_iter.close
26
+ end
27
+ end
28
+ dir_iter
29
+ end
30
+
31
+ def pwd
32
+ @mapped_zip.pwd
33
+ end
34
+ alias getwd pwd
35
+
36
+ def chdir(directory_name)
37
+ unless @file.stat(directory_name).directory?
38
+ raise Errno::EINVAL, "Invalid argument - #{directory_name}"
39
+ end
40
+
41
+ @mapped_zip.pwd = @file.expand_path(directory_name)
42
+ end
43
+
44
+ def entries(directory_name)
45
+ entries = []
46
+ foreach(directory_name) { |e| entries << e }
47
+ entries
48
+ end
49
+
50
+ def glob(...)
51
+ @mapped_zip.glob(...)
52
+ end
53
+
54
+ def foreach(directory_name)
55
+ unless @file.stat(directory_name).directory?
56
+ raise Errno::ENOTDIR, directory_name
57
+ end
58
+
59
+ path = @file.expand_path(directory_name)
60
+ path << '/' unless path.end_with?('/')
61
+ path = Regexp.escape(path)
62
+ subdir_entry_regex = Regexp.new("^#{path}([^/]+)$")
63
+ @mapped_zip.each do |filename|
64
+ match = subdir_entry_regex.match(filename)
65
+ yield(match[1]) unless match.nil?
66
+ end
67
+ end
68
+
69
+ def delete(entry_name)
70
+ unless @file.stat(entry_name).directory?
71
+ raise Errno::EINVAL, "Invalid argument - #{entry_name}"
72
+ end
73
+
74
+ @mapped_zip.remove(entry_name)
75
+ end
76
+ alias rmdir delete
77
+ alias unlink delete
78
+
79
+ def mkdir(entry_name, permissions = 0o755)
80
+ @mapped_zip.mkdir(entry_name, permissions)
81
+ end
82
+
83
+ def chroot(*_args)
84
+ raise NotImplementedError, 'The chroot() function is not implemented'
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ module Ziperu
6
+ module FileSystem
7
+ class DirectoryIterator # :nodoc:all
8
+ include Enumerable
9
+
10
+ def initialize(filenames)
11
+ @filenames = filenames
12
+ @index = 0
13
+ end
14
+
15
+ def close
16
+ @filenames = nil
17
+ end
18
+
19
+ def each(&a_proc)
20
+ raise IOError, 'closed directory' if @filenames.nil?
21
+
22
+ @filenames.each(&a_proc)
23
+ end
24
+
25
+ def read
26
+ raise IOError, 'closed directory' if @filenames.nil?
27
+
28
+ @filenames[(@index += 1) - 1]
29
+ end
30
+
31
+ def rewind
32
+ raise IOError, 'closed directory' if @filenames.nil?
33
+
34
+ @index = 0
35
+ end
36
+
37
+ def seek(position)
38
+ raise IOError, 'closed directory' if @filenames.nil?
39
+
40
+ @index = position
41
+ end
42
+
43
+ def tell
44
+ raise IOError, 'closed directory' if @filenames.nil?
45
+
46
+ @index
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,265 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ require_relative 'file_stat'
6
+
7
+ module Ziperu
8
+ module FileSystem
9
+ # Instances of this class are normally accessed via the accessor
10
+ # Ziperu::File::file. An instance of File behaves like ruby's
11
+ # builtin File (class) object, except it works on Ziperu::File entries.
12
+ #
13
+ # The individual methods are not documented due to their
14
+ # similarity with the methods in File
15
+ class File # :nodoc:all
16
+ attr_writer :dir
17
+
18
+ def initialize(mapped_zip)
19
+ @mapped_zip = mapped_zip
20
+ end
21
+
22
+ def find_entry(filename)
23
+ unless exists?(filename)
24
+ raise Errno::ENOENT, "No such file or directory - #{filename}"
25
+ end
26
+
27
+ @mapped_zip.find_entry(filename)
28
+ end
29
+
30
+ def unix_mode_cmp(filename, mode)
31
+ e = find_entry(filename)
32
+ e.fstype == FSTYPE_UNIX && (e.external_file_attributes >> 16).anybits?(mode)
33
+ rescue Errno::ENOENT
34
+ false
35
+ end
36
+ private :unix_mode_cmp
37
+
38
+ def exists?(filename)
39
+ expand_path(filename) == '/' || !@mapped_zip.find_entry(filename).nil?
40
+ end
41
+ alias exist? exists?
42
+
43
+ # Permissions not implemented, so if the file exists it is accessible
44
+ alias owned? exists?
45
+ alias grpowned? exists?
46
+
47
+ def readable?(filename)
48
+ unix_mode_cmp(filename, 0o444)
49
+ end
50
+ alias readable_real? readable?
51
+
52
+ def writable?(filename)
53
+ unix_mode_cmp(filename, 0o222)
54
+ end
55
+ alias writable_real? writable?
56
+
57
+ def executable?(filename)
58
+ unix_mode_cmp(filename, 0o111)
59
+ end
60
+ alias executable_real? executable?
61
+
62
+ def setuid?(filename)
63
+ unix_mode_cmp(filename, 0o4000)
64
+ end
65
+
66
+ def setgid?(filename)
67
+ unix_mode_cmp(filename, 0o2000)
68
+ end
69
+
70
+ def sticky?(filename)
71
+ unix_mode_cmp(filename, 0o1000)
72
+ end
73
+
74
+ def umask(*args)
75
+ ::File.umask(*args)
76
+ end
77
+
78
+ def truncate(_filename, _len)
79
+ raise StandardError, 'truncate not supported'
80
+ end
81
+
82
+ def directory?(filename)
83
+ entry = @mapped_zip.find_entry(filename)
84
+ expand_path(filename) == '/' || (!entry.nil? && entry.directory?)
85
+ end
86
+
87
+ def open(filename, mode = 'r', permissions = 0o644, &block)
88
+ mode = mode.tr('b', '') # ignore b option
89
+ case mode
90
+ when 'r'
91
+ @mapped_zip.get_input_stream(filename, &block)
92
+ when 'w'
93
+ @mapped_zip.get_output_stream(filename, permissions, &block)
94
+ else
95
+ raise StandardError, "openmode '#{mode} not supported" unless mode == 'r'
96
+ end
97
+ end
98
+
99
+ def new(filename, mode = 'r')
100
+ self.open(filename, mode)
101
+ end
102
+
103
+ def size(filename)
104
+ @mapped_zip.get_entry(filename).size
105
+ end
106
+
107
+ # Returns nil for not found and nil for directories.
108
+ # We disable the cop here for compatibility with `::File.size?`.
109
+ def size?(filename)
110
+ entry = @mapped_zip.find_entry(filename)
111
+ entry.nil? || entry.directory? ? nil : entry.size # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
112
+ end
113
+
114
+ def chown(owner, group, *filenames)
115
+ filenames.each do |filename|
116
+ e = find_entry(filename)
117
+ e.extra.create(:iunix) unless e.extra.member?(:iunix)
118
+ e.extra[:iunix].uid = owner
119
+ e.extra[:iunix].gid = group
120
+ end
121
+ filenames.size
122
+ end
123
+
124
+ def chmod(mode, *filenames)
125
+ filenames.each do |filename|
126
+ e = find_entry(filename)
127
+ e.fstype = FSTYPE_UNIX # Force conversion filesystem type to unix.
128
+ e.unix_perms = mode
129
+ e.external_file_attributes = mode << 16
130
+ end
131
+ filenames.size
132
+ end
133
+
134
+ def zero?(filename)
135
+ sz = size(filename)
136
+ sz.nil? || sz == 0
137
+ rescue Errno::ENOENT
138
+ false
139
+ end
140
+
141
+ def file?(filename)
142
+ entry = @mapped_zip.find_entry(filename)
143
+ !entry.nil? && entry.file?
144
+ end
145
+
146
+ def dirname(filename)
147
+ ::File.dirname(filename)
148
+ end
149
+
150
+ def basename(filename)
151
+ ::File.basename(filename)
152
+ end
153
+
154
+ def split(filename)
155
+ ::File.split(filename)
156
+ end
157
+
158
+ def join(*fragments)
159
+ ::File.join(*fragments)
160
+ end
161
+
162
+ def utime(modified_time, *filenames)
163
+ filenames.each do |filename|
164
+ find_entry(filename).time = modified_time
165
+ end
166
+ end
167
+
168
+ def mtime(filename)
169
+ @mapped_zip.get_entry(filename).mtime
170
+ end
171
+
172
+ def atime(filename)
173
+ @mapped_zip.get_entry(filename).atime
174
+ end
175
+
176
+ def ctime(filename)
177
+ @mapped_zip.get_entry(filename).ctime
178
+ end
179
+
180
+ def pipe?(_filename)
181
+ false
182
+ end
183
+
184
+ def blockdev?(_filename)
185
+ false
186
+ end
187
+
188
+ def chardev?(_filename)
189
+ false
190
+ end
191
+
192
+ def symlink?(filename)
193
+ @mapped_zip.get_entry(filename).symlink?
194
+ end
195
+
196
+ def socket?(_filename)
197
+ false
198
+ end
199
+
200
+ def ftype(filename)
201
+ @mapped_zip.get_entry(filename).directory? ? 'directory' : 'file'
202
+ end
203
+
204
+ def readlink(_filename)
205
+ raise NotImplementedError, 'The readlink() function is not implemented'
206
+ end
207
+
208
+ def symlink(_filename, _symlink_name)
209
+ raise NotImplementedError, 'The symlink() function is not implemented'
210
+ end
211
+
212
+ def link(_filename, _symlink_name)
213
+ raise NotImplementedError, 'The link() function is not implemented'
214
+ end
215
+
216
+ def pipe
217
+ raise NotImplementedError, 'The pipe() function is not implemented'
218
+ end
219
+
220
+ def stat(filename)
221
+ raise Errno::ENOENT, filename unless exists?(filename)
222
+
223
+ Stat.new(self, filename)
224
+ end
225
+
226
+ alias lstat stat
227
+
228
+ def readlines(filename)
229
+ self.open(filename, &:readlines)
230
+ end
231
+
232
+ def read(filename)
233
+ @mapped_zip.read(filename)
234
+ end
235
+
236
+ def popen(*args, &a_proc)
237
+ ::File.popen(*args, &a_proc)
238
+ end
239
+
240
+ def foreach(filename, sep = $INPUT_RECORD_SEPARATOR, &a_proc)
241
+ self.open(filename) { |is| is.each_line(sep, &a_proc) }
242
+ end
243
+
244
+ def delete(*args)
245
+ args.each do |filename|
246
+ if directory?(filename)
247
+ raise Errno::EISDIR, "Is a directory - \"#{filename}\""
248
+ end
249
+
250
+ @mapped_zip.remove(filename)
251
+ end
252
+ end
253
+
254
+ def rename(file_to_rename, new_name)
255
+ @mapped_zip.rename(file_to_rename, new_name) { true }
256
+ end
257
+
258
+ alias unlink delete
259
+
260
+ def expand_path(path)
261
+ @mapped_zip.expand_path(path)
262
+ end
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ module Ziperu
6
+ module FileSystem
7
+ class File # :nodoc:all
8
+ class Stat # :nodoc:all
9
+ class << self
10
+ def delegate_to_fs_file(*methods)
11
+ methods.each do |method|
12
+ class_exec do
13
+ define_method(method) do
14
+ @zip_fs_file.__send__(method, @entry_name)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def initialize(zip_fs_file, entry_name)
22
+ @zip_fs_file = zip_fs_file
23
+ @entry_name = entry_name
24
+ end
25
+
26
+ def kind_of?(type)
27
+ super || type == ::File::Stat
28
+ end
29
+
30
+ delegate_to_fs_file :file?, :directory?, :pipe?, :chardev?, :symlink?,
31
+ :socket?, :blockdev?, :readable?, :readable_real?, :writable?, :ctime,
32
+ :writable_real?, :executable?, :executable_real?, :sticky?, :owned?,
33
+ :grpowned?, :setuid?, :setgid?, :zero?, :size, :size?, :mtime, :atime
34
+
35
+ def blocks
36
+ nil
37
+ end
38
+
39
+ def gid
40
+ e = find_entry
41
+ if e.extra.member? :iunix
42
+ e.extra[:iunix].gid || 0
43
+ else
44
+ 0
45
+ end
46
+ end
47
+
48
+ def uid
49
+ e = find_entry
50
+ if e.extra.member? :iunix
51
+ e.extra[:iunix].uid || 0
52
+ else
53
+ 0
54
+ end
55
+ end
56
+
57
+ def ino
58
+ 0
59
+ end
60
+
61
+ def dev
62
+ 0
63
+ end
64
+
65
+ def rdev
66
+ 0
67
+ end
68
+
69
+ def rdev_major
70
+ 0
71
+ end
72
+
73
+ def rdev_minor
74
+ 0
75
+ end
76
+
77
+ def ftype
78
+ if file?
79
+ 'file'
80
+ elsif directory?
81
+ 'directory'
82
+ else
83
+ raise StandardError, 'Unknown file type'
84
+ end
85
+ end
86
+
87
+ def nlink
88
+ 1
89
+ end
90
+
91
+ def blksize
92
+ nil
93
+ end
94
+
95
+ def mode
96
+ e = find_entry
97
+ if e.fstype == FSTYPE_UNIX
98
+ e.external_file_attributes >> 16
99
+ else
100
+ 0o100_666 # Equivalent to -rw-rw-rw-.
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def find_entry
107
+ @zip_fs_file.find_entry(@entry_name)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ module Ziperu
6
+ module FileSystem
7
+ # All access to Ziperu::File from FileSystem::File and FileSystem::Dir
8
+ # goes through a ZipFileNameMapper, which has one responsibility: ensure
9
+ class ZipFileNameMapper # :nodoc:all
10
+ include Enumerable
11
+
12
+ def initialize(zip_file)
13
+ @zip_file = zip_file
14
+ @pwd = '/'
15
+ end
16
+
17
+ attr_accessor :pwd
18
+
19
+ def find_entry(filename)
20
+ @zip_file.find_entry(expand_to_entry(filename))
21
+ end
22
+
23
+ def get_entry(filename)
24
+ @zip_file.get_entry(expand_to_entry(filename))
25
+ end
26
+
27
+ def get_input_stream(filename, &a_proc)
28
+ @zip_file.get_input_stream(expand_to_entry(filename), &a_proc)
29
+ end
30
+
31
+ def get_output_stream(filename, permissions = nil, &a_proc)
32
+ @zip_file.get_output_stream(
33
+ expand_to_entry(filename), permissions: permissions, &a_proc
34
+ )
35
+ end
36
+
37
+ def glob(pattern, *flags, &block)
38
+ @zip_file.glob(expand_to_entry(pattern), *flags, &block)
39
+ end
40
+
41
+ def read(filename)
42
+ @zip_file.read(expand_to_entry(filename))
43
+ end
44
+
45
+ def remove(filename)
46
+ @zip_file.remove(expand_to_entry(filename))
47
+ end
48
+
49
+ def rename(filename, new_name, &continue_on_exists_proc)
50
+ @zip_file.rename(
51
+ expand_to_entry(filename),
52
+ expand_to_entry(new_name),
53
+ &continue_on_exists_proc
54
+ )
55
+ end
56
+
57
+ def mkdir(filename, permissions = 0o755)
58
+ @zip_file.mkdir(expand_to_entry(filename), permissions)
59
+ end
60
+
61
+ # Turns entries into strings and adds leading /
62
+ # and removes trailing slash on directories
63
+ def each
64
+ @zip_file.each do |e|
65
+ yield("/#{e.to_s.chomp('/')}")
66
+ end
67
+ end
68
+
69
+ def expand_path(path)
70
+ expanded = path.start_with?('/') ? path.dup : ::File.join(@pwd, path)
71
+ expanded.gsub!(/\/\.(\/|$)/, '')
72
+ expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, '')
73
+ expanded.empty? ? '/' : expanded
74
+ end
75
+
76
+ private
77
+
78
+ def expand_to_entry(path)
79
+ expand_path(path)[1..]
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ported verbatim from rubyzip (Copyright (C) 2002-2026 the rubyzip authors).
4
+
5
+ require 'ziperu'
6
+ require_relative 'filesystem/zip_file_name_mapper'
7
+ require_relative 'filesystem/directory_iterator'
8
+ require_relative 'filesystem/dir'
9
+ require_relative 'filesystem/file'
10
+
11
+ module Ziperu
12
+ # The ZipFileSystem API provides an API for accessing entries in
13
+ # a zip archive that is similar to ruby's builtin File and Dir
14
+ # classes.
15
+ #
16
+ # Requiring 'zip/filesystem' includes this module in Ziperu::File
17
+ # making the methods in this module available on Ziperu::File objects.
18
+ #
19
+ # Using this API the following example creates a new zip file
20
+ # <code>my.zip</code> containing a normal entry with the name
21
+ # <code>first.txt</code>, a directory entry named <code>mydir</code>
22
+ # and finally another normal entry named <code>second.txt</code>
23
+ #
24
+ # ```
25
+ # require 'ziperu/filesystem'
26
+ #
27
+ # Ziperu::File.open('my.zip', create: true) do |zipfile|
28
+ # zipfile.file.open('first.txt', 'w') { |f| f.puts 'Hello world' }
29
+ # zipfile.dir.mkdir('mydir')
30
+ # zipfile.file.open('mydir/second.txt', 'w') { |f| f.puts 'Hello again' }
31
+ # end
32
+ # ```
33
+ #
34
+ # Reading is as easy as writing, as the following example shows. The
35
+ # example writes the contents of <code>first.txt</code> from zip archive
36
+ # <code>my.zip</code> to standard out.
37
+ #
38
+ # ```
39
+ # require 'ziperu/filesystem'
40
+ #
41
+ # Ziperu::File.open('my.zip') do |zipfile|
42
+ # puts zipfile.file.read('first.txt')
43
+ # end
44
+ # ```
45
+ module FileSystem
46
+ def initialize # :nodoc:
47
+ mapped_zip = ZipFileNameMapper.new(self)
48
+ @zip_fs_dir = Dir.new(mapped_zip)
49
+ @zip_fs_file = File.new(mapped_zip)
50
+ @zip_fs_dir.file = @zip_fs_file
51
+ @zip_fs_file.dir = @zip_fs_dir
52
+ end
53
+
54
+ # Returns a Ziperu::FileSystem::Dir which is much like ruby's builtin Dir
55
+ # (class) object, except it works on the Ziperu::File on which this method is
56
+ # invoked
57
+ def dir
58
+ @zip_fs_dir
59
+ end
60
+
61
+ # Returns a Ziperu::FileSystem::File which is much like ruby's builtin File
62
+ # (class) object, except it works on the Ziperu::File on which this method is
63
+ # invoked
64
+ def file
65
+ @zip_fs_file
66
+ end
67
+ end
68
+
69
+ class File # :nodoc:
70
+ include FileSystem
71
+ end
72
+ end
73
+
74
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
75
+ # rubyzip is free software; you can redistribute it and/or
76
+ # modify it under the terms of the ruby license.