Module: InVFS

Defined in:
lib/invfs.rb,
lib/invfs.rb,
lib/invfs.rb,
lib/invfs.rb

Defined Under Namespace

Modules: Extensions, Kernel Classes: StringMapFS, UnionFS, Zip

Constant Summary collapse

TOPLEVEL_BINDING =
binding.freeze
DEFAULT_MAX_LOADSIZE =
2.MiB
MINIMAL_MAX_LOADSIZE =
256.KiB
MAXIMAM_MAX_LOADSIZE =
64.MiB
MAX_LOADSIZE =
maxloadsize.clamp(MINIMAL_MAX_LOADSIZE, MAXIMAM_MAX_LOADSIZE)
LOADED_PREFIX =

$LOADED_FEATURES に追加される接頭辞

"<inVFS>:".freeze
MultipleDirectory =
UnionFS

Class Method Summary collapse

Class Method Details

.findlib(vfs, lib, relative) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/invfs.rb', line 139

def InVFS.findlib(vfs, lib, relative)
  if relative
    if vfs.file?(lib)
      lib
    else
      nil
    end
  else
    case
    when vfs.file?(lib)
      lib
    when vfs.file?(librb = lib + ".rb")
      librb
    when vfs.file?(libso = lib + ".so")
      libso
    else
      nil
    end
  end
end

.findpath(lib, relative) ⇒ Object

call-seq:

findpath(absolute_lib_path, relative) { |vfs, subpath| ... }


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/invfs.rb', line 173

def InVFS.findpath(lib, relative)
  if relative || Pathname(lib).absolute?
    # 絶対パス表記でのライブラリ指定、または require_relative の呼び出し元

    # NOTE: LOAD_PATH ($:) の順序を優先するか?
    # NOTE: 一致するティレクトリ階層の深さを優先するか?
    # NOTE: => とりあえずは順序を優先しておく

    $:.each do |vfs|
      #__BREAKHERE__
      dir = String(vfs.to_path)
      dir += "/" unless dir.empty? || dir[-1] == "/"
      (a, b, c) = lib.partition(dir)
      next unless a.empty? && !b.empty? && !c.empty?
      yield(vfs, c)
    end
  else
    $:.each { |vfs| yield(vfs, lib) }
  end

  nil
end

.findvfs(lib, relative) ⇒ Object



160
161
162
163
164
165
166
167
# File 'lib/invfs.rb', line 160

def InVFS.findvfs(lib, relative)
  findpath(lib, relative) do |vfs, sub|
    next unless sub = findlib(vfs, sub, relative)
    return nil if vfs.__native_file_path?
    next if vfs.size(sub) > MAX_LOADSIZE
    return [vfs, sub]
  end
end

.loaded?(vfs, lib) ⇒ Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/invfs.rb', line 196

def InVFS.loaded?(vfs, lib)
  !!$".include?(LOADED_PREFIX + File.join(vfs, lib))
end

.require_in(vfs, path) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/invfs.rb', line 200

def InVFS.require_in(vfs, path)
  code = String(vfs.read(path))
  loadpath = File.join(vfs, path)
  unless File.extname(path) == ".so"
    unless code.encoding == Encoding::UTF_8
      code = code.dup if code.frozen?
      code.force_encoding(Encoding::UTF_8)
    end

    eval code, InVFS::TOPLEVEL_BINDING.dup, loadpath, 1
  else
    Dir.mktmpdir do |dir|
      tempname = File.join(dir, File.basename(path))
      mode = File::CREAT | File::WRONLY | File::EXCL | File::BINARY
      File.open(tempname, mode, 0700) { |fd| fd << code }
      require! tempname
      $".pop # 偽装したライブラリパスであるため、削除
    end
  end

  $" << (LOADED_PREFIX + loadpath)

  true
end

.zip(*args) ⇒ Object



6
7
8
# File 'lib/invfs/zip.rb', line 6

def InVFS.zip(*args)
  InVFS::Zip.new(*args)
end