invfs 0.2 → 0.3

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 (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -16
  3. data/lib/invfs/zip.rb +94 -55
  4. data/lib/invfs.rb +57 -1
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2909cffa456fdd3f5b4fc6efdbc4cfaa07f1faf30db565da868af67233bf9635
4
- data.tar.gz: f5db8163c2fb5533c7fb72deab583d66c3b54d8bb29058c426d68733d2020821
3
+ metadata.gz: 5ba520faaa919d8053ed90c0e4f1a83566a0bfb15dc3dbc2a556a335d7c16922
4
+ data.tar.gz: ade81666d1041d7e2789929b03297592119767e7b9f9280775fcf7bd655127f4
5
5
  SHA512:
6
- metadata.gz: e4126c3039e12664d9564ff9877dafc8694777f91d286f3fe800667ed7df2ce8379d2d5488bee2c966bf7b7e8ff600368e6bab47a75ec98ee73faa13a3e1cfba
7
- data.tar.gz: 8b05d884e52a39537978f395e886f975f87a946e9ed38dcd04a145e9528c6408c2edf4582aab535d8a9f39a00a59ba1832c0462aab86bdcaa2671bddca9c0e56
6
+ metadata.gz: 69e2d22350e08b9ce911e75a071688f78916e30d5b821ae6b229e3c3a91c8cd082836d8a70fc02f92f776487732a6acb18625e70ba3697b4ded4c88fadde7222
7
+ data.tar.gz: f21cfaa41d7f266a24b737ee5665647735d67bf0b5b28e5d5a3f2594bab9bdf9ef0ff4b84ffe789ba21702a718965019e2f6e0e92120cac6e4c2692fd7a95cbb
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ruby の ``require`` に仮想ファイルシステム (VFS; Virtual Filesystem) 対応機能を追加します。
4
4
 
5
5
  * package name: invfs <https://github.com/dearblue/ruby-invfs>
6
- * version: 0.2
6
+ * version: 0.3
7
7
  * production quality: CONCEPT, EXPERIMENTAL, UNSTABLE
8
8
  * license: BSD-2-clause License
9
9
  * author: dearblue <mailto:dearblue@users.noreply.github.com>
@@ -89,7 +89,7 @@ VFS オブジェクトは ``$:`` に追加する、利用者定義のロード
89
89
  * ``.size(path) -> integer``
90
90
  * ``.read(path) -> string as binary``
91
91
 
92
- 実際にどのように定義すればいいのかについては、[lib/invfs/zip.rb](lib/invfs/zip.rb) あるいは [lib/invfs.rb](lib.invfs.rb) で定義されている ``InVFS::UnionFS``、``InVFS::StringMapFS`` を参考にして下さい。
92
+ 実際にどのように定義すればいいのかについては、[lib/invfs/zip.rb](lib/invfs/zip.rb) あるいは [lib/invfs.rb](lib/invfs.rb) で定義されている ``InVFS::UnionFS``、``InVFS::StringMapFS`` を参考にして下さい。
93
93
 
94
94
  ### ``.to_path() -> string``
95
95
 
@@ -122,6 +122,41 @@ VFS からファイルを読み込むためのメソッドです。
122
122
  ***文字列、または nil を返して下さい。***
123
123
 
124
124
 
125
+ ## VFS ハンドラ
126
+
127
+ ``$:`` にファイルを追加した場合、``require`` 時に VFS と解釈可能であれば、内部的にそのファイルを VFS として扱われる機能です。
128
+
129
+ 前にあった例を書き換えた場合の利用例を示します。(2) の部分です。
130
+
131
+ ```ruby
132
+ require "invfs/zip" # (1)
133
+
134
+ $: << "mybox.zip" # (2)
135
+
136
+ require "mybox/core" # (3)
137
+
138
+ MyBox.sayhello!
139
+ ```
140
+
141
+ VFS ハンドラを利用したい場合は、``.probe`` と ``.open`` メソッドを持ったオブジェクトを ``InVFS.regist`` で登録して下さい。
142
+
143
+ ```ruby
144
+ class VFSHandler
145
+ def VFSHandler.probe(file)
146
+ # check available as VFS
147
+ end
148
+
149
+ def VFSHandler.open(file)
150
+ # open as VFS
151
+ end
152
+
153
+ InVFS.regist self
154
+ end
155
+ ```
156
+
157
+ 実際にどのようにつかっているのかについては、[lib/invfs.rb](lib/invfs.rb) を見て下さい。
158
+
159
+
125
160
  ## Environment Variables (環境変数について)
126
161
 
127
162
  * ``RUBY_REQUIRE_INVFS_MAX_LOADSIZE`` :: 読み込みファイルの最大ファイルサイズの指定
@@ -175,17 +210,3 @@ VFS からファイルを読み込むためのメソッドです。
175
210
 
176
211
  ``caller_locations`` で VFS の直接確認が出来るようにするためには ruby の
177
212
  C コードに手を入れなきゃなんないし諦める。
178
-
179
- * ``$:`` にファイルを指定した場合、InVFS の VFS mapper が自動で VFS に置き換えるようにするか?
180
-
181
- 実現させると、以下のことが可能となる:
182
-
183
- ```shell
184
- $ ruby -I mybox.zip -r invfs/zip -r mybox/core -e '......'
185
- ```
186
-
187
- これは、以下と同等である:
188
-
189
- ```shell
190
- $ ruby -r invfs/zip -e '$: << InVFS.zip("mybox.zip"); require "mybox/core"; ......'
191
- ```
data/lib/invfs/zip.rb CHANGED
@@ -3,73 +3,112 @@
3
3
  require "zip/filesystem"
4
4
  require_relative "../invfs"
5
5
 
6
+ using InVFS::Extensions
7
+
6
8
  def InVFS.zip(*args)
7
9
  InVFS::Zip.new(*args)
8
10
  end
9
11
 
10
- class InVFS::Zip
11
- attr_reader :path, :zip, :zipfile
12
+ module InVFS
13
+ class Zip
14
+ attr_reader :path, :zip, :zipfile
12
15
 
13
- def initialize(path)
14
- @path = String(path)
15
- @zip = Zip::File.open(@path)
16
- @zipfile = @zip.file
17
- end
16
+ def initialize(path)
17
+ @path = String(path)
18
+ @zip = ::Zip::File.open(@path)
19
+ @zipfile = @zip.file
20
+ end
18
21
 
19
- #
20
- # call-seq:
21
- # to_path -> string
22
- #
23
- # REQUIRED method for VFS.
24
- #
25
- # This value MUST be not modifying in each objects.
26
- #
27
- def to_path
28
- path
29
- end
22
+ #
23
+ # call-seq:
24
+ # to_path -> string
25
+ #
26
+ # REQUIRED method for VFS.
27
+ #
28
+ # This value MUST be not modifying in each objects.
29
+ #
30
+ def to_path
31
+ path
32
+ end
30
33
 
31
- #
32
- # call-seq:
33
- # file?(path) -> true OR false (OR nil)
34
- #
35
- # REQUIRED method for VFS.
36
- #
37
- def file?(path)
38
- zipfile.file?(path)
39
- end
34
+ #
35
+ # call-seq:
36
+ # file?(path) -> true OR false (OR nil)
37
+ #
38
+ # REQUIRED method for VFS.
39
+ #
40
+ def file?(path)
41
+ zipfile.file?(path)
42
+ end
40
43
 
41
- #
42
- # call-seq:
43
- # size(path) -> integer for file size
44
- #
45
- # REQUIRED method for VFS.
46
- #
47
- def size(path)
48
- zipfile.size(path)
49
- end
44
+ #
45
+ # call-seq:
46
+ # size(path) -> integer for file size
47
+ #
48
+ # REQUIRED method for VFS.
49
+ #
50
+ def size(path)
51
+ zipfile.size(path)
52
+ end
50
53
 
51
- #
52
- # call-seq:
53
- # read(path) -> string
54
- #
55
- # REQUIRED method for VFS.
56
- #
57
- def read(path)
58
- zipfile.read(path)
59
- end
54
+ #
55
+ # call-seq:
56
+ # read(path) -> string
57
+ #
58
+ # REQUIRED method for VFS.
59
+ #
60
+ def read(path)
61
+ zipfile.read(path)
62
+ end
60
63
 
61
- #
62
- # optional method for VFS.
63
- #
64
- def to_s
65
- %(#{path} (#{self.class}))
66
- end
64
+ #
65
+ # optional method for VFS.
66
+ #
67
+ def to_s
68
+ %(#{path} (#{self.class}))
69
+ end
70
+
71
+ def inspect
72
+ %(#<#{self.class}:#{path}>)
73
+ end
67
74
 
68
- def inspect
69
- %(#<#{self.class}:#{path}>)
75
+ def pretty_print(q)
76
+ q.text inspect
77
+ end
70
78
  end
71
79
 
72
- def pretty_print(q)
73
- q.text inspect
80
+ class Zip
81
+ #
82
+ # VFS Handler Methods
83
+ ;
84
+
85
+ #
86
+ # call-seq:
87
+ # probe(file) -> true or false
88
+ #
89
+ # REQUIRED method for VFS Handler.
90
+ #
91
+ # Check available as VFS.
92
+ #
93
+ def Zip.probe(file)
94
+ file.readat(0, 4) == "PK\x03\x04"
95
+ end
96
+
97
+ #
98
+ # call-seq:
99
+ # open(file) -> VFS object
100
+ #
101
+ # REQUIRED method for VFS Handler.
102
+ #
103
+ # Open as VFS.
104
+ #
105
+ def Zip.open(file)
106
+ new file
107
+ end
108
+
109
+ #
110
+ # Regist handler as VFS.
111
+ #
112
+ InVFS.regist self
74
113
  end
75
114
  end
data/lib/invfs.rb CHANGED
@@ -75,6 +75,20 @@ module InVFS
75
75
  end
76
76
  end
77
77
 
78
+ refine BasicObject do
79
+ def it_a_file?
80
+ false
81
+ end
82
+ end
83
+
84
+ [::String, ::File, ::Dir, ::Pathname].each do |klass|
85
+ refine klass do
86
+ def it_a_file?
87
+ File.file?(self)
88
+ end
89
+ end
90
+ end
91
+
78
92
  [::String, ::File, ::Dir].each do |klass|
79
93
  refine klass do
80
94
  def file?(path)
@@ -83,6 +97,15 @@ module InVFS
83
97
  end
84
98
  end
85
99
 
100
+ [::String, ::File, ::Pathname].each do |klass|
101
+ refine klass do
102
+ def readat(off, size = nil, buf = "".b)
103
+ buf.replace File.binread(self, size, off)
104
+ buf
105
+ end
106
+ end
107
+ end
108
+
86
109
  refine Object do
87
110
  if Object.const_defined?(:DEBUGGER__)
88
111
  BREAKPOINT_SET = {}
@@ -184,10 +207,43 @@ module InVFS
184
207
  dir += "/" unless dir.empty? || dir[-1] == "/"
185
208
  (a, b, c) = lib.partition(dir)
186
209
  next unless a.empty? && !b.empty? && !c.empty?
210
+ next unless vfs = mapvfs(vfs)
187
211
  yield(vfs, c)
188
212
  end
189
213
  else
190
- $:.each { |vfs| yield(vfs, lib) }
214
+ $:.each do |vfs|
215
+ next unless vfs = mapvfs(vfs)
216
+ yield(vfs, lib)
217
+ end
218
+ end
219
+
220
+ nil
221
+ end
222
+
223
+ @mapped_list = {}
224
+ @handler_list = []
225
+
226
+ def InVFS.regist(handler)
227
+ unless handler.respond_to?(:probe) && handler.respond_to?(:open)
228
+ raise "%s - #<%s:0x08x>" %
229
+ ["need ``.probe'' and ``.open'' methods for vfs handler",
230
+ handler.class, handler.object_id]
231
+ end
232
+
233
+ @handler_list << handler
234
+
235
+ nil
236
+ end
237
+
238
+ def InVFS.mapvfs(vfs)
239
+ return vfs unless vfs.it_a_file?
240
+
241
+ v = @mapped_list[vfs]
242
+ return v if v
243
+
244
+ @handler_list.each do |handler|
245
+ next unless handler.probe(vfs)
246
+ return @mapped_list[vfs] = handler.open(vfs)
191
247
  end
192
248
 
193
249
  nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invfs
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - dearblue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-10 00:00:00.000000000 Z
11
+ date: 2018-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip