invfs 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
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