Module: Amp::Repositories::Stores
Defined Under Namespace
Modules: FilenameCache Classes: BasicStore, EncodedOpener, EncodedStore, FilenameCacheStore, StoreError
Constant Summary collapse
- WINDOWS_RESERVED_FILENAMES =
can’t name a file one of these on windows, apparently
%w(con prn aux nul com1 com2 com3 com4 com5 com6 com7 com8 com8 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9)
- MAX_PATH_LEN_IN_HGSTORE =
120
- DIR_PREFIX_LEN =
8
- MAX_SHORTENED_DIRS_LEN =
8 * (DIR_PREFIX_LEN + 1) - 4
Instance Method Summary collapse
-
#auxilliary_encode(path) ⇒ Object
Copypasta.
-
#decode_filename(s) ⇒ Object
Decodes an encoding performed by encode_filename.
-
#encode_filename(s, underscore = true) ⇒ String
Reversible encoding of the filename.
-
#hybrid_encode(path) ⇒ String
uber encoding that’s straight up crazy.
-
#illegal_character_map(underscore = true) ⇒ Object
Gets the basic character map that maps disallowed letters to allowable substitutes.
-
#lower_encode(s) ⇒ Object
Normal encoding, but without extra underscores in the filenames.
-
#pick(requirements, path, opener, pathjoiner = nil) ⇒ Object
Picks which store to use, given a list of requirements.
Instance Method Details
#auxilliary_encode(path) ⇒ Object
Copypasta
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/amp/repository/store.rb', line 413 def auxilliary_encode(path) res = [] path.split('/').each do |n| if n.any? base = n.split('.')[0] if !(base.nil?) && base.any? && WINDOWS_RESERVED_FILENAMES.include?(base) ec = "~%02x" % n[2,1].ord n = n[0..1] + ec + n[3..-1] end if ['.',' '].include? n[-1,1] n = n[0..-2] + ("~%02x" % n[-1,1].ord) end end res << n end res.join("/") end |
#decode_filename(s) ⇒ Object
Decodes an encoding performed by encode_filename
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/amp/repository/store.rb', line 385 def decode_filename(s) cmap = illegal_character_map true dmap = {} cmap.each do |k, v| dmap[v] = k end i = 0 result = [] while i < s.size 1.upto(3) do |l| if dmap[s[i..(i+l-1)]] result << dmap[s[i..(i+l-1)]] i += l break end end end result.join end |
#encode_filename(s, underscore = true) ⇒ String
Reversible encoding of the filename
375 376 377 378 |
# File 'lib/amp/repository/store.rb', line 375 def encode_filename(s, underscore=true) cmap = illegal_character_map underscore s.split("").map {|c| cmap[c]}.join end |
#hybrid_encode(path) ⇒ String
uber encoding that’s straight up crazy. Max length of 120 means we have a non-reversible encoding, but since the FilenameCache only cares about name lookups, one-way is really all that matters!
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/amp/repository/store.rb', line 449 def hybrid_encode(path) return path unless path =~ /data\// ndpath = path["data/".size..-1] res = "data/" + auxilliary_encode(encode_filename(ndpath)) if res.size > MAX_PATH_LEN_IN_HGSTORE digest = path.sha1.hexdigest aep = auxilliary_encode(lower_encode(ndpath)) root, ext = File.amp_split_extension aep parts = aep.split('/') basename = File.basename aep sdirs = [] parts[0..-2].each do |p| d = p[0..(DIR_PREFIX_LEN-1)] d = d[0..-2] + "_" if " .".include?(d[-1,1]) t = sdirs.join("/") + "/" + d break if t.size > MAX_SHORTENED_DIRS_LEN sdirs << d end dirs = sdirs.join("/") dirs += "/" if dirs.size > 0 res = "dh/" + dirs + digest + ext space_left = MAX_PATH_LEN_IN_HGSTORE - res.size if space_left > 0 filler = basename[0..(space_left-1)] res = "dh/" + dirs + filler + digest + ext end end return res end |
#illegal_character_map(underscore = true) ⇒ Object
Gets the basic character map that maps disallowed letters to allowable substitutes.
353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/amp/repository/store.rb', line 353 def illegal_character_map(underscore=true) e = '_' win_reserved = "\\:*?\"<>|".split("").map {|x| x.ord} cmap = {}; 0.upto(126) {|x| cmap[x.chr] = x.chr} ((0..31).to_a + (126..255).to_a + win_reserved).each do |x| cmap[x.chr] = "~%02x" % x end ((("A".ord)..("Z".ord)).to_a + [e.ord]).each do |x| cmap[x.chr] = e + x.chr.downcase if underscore cmap[x.chr] = x.chr.downcase unless underscore end cmap end |
#lower_encode(s) ⇒ Object
Normal encoding, but without extra underscores in the filenames.
433 434 435 |
# File 'lib/amp/repository/store.rb', line 433 def lower_encode(s) encode_filename s, false end |
#pick(requirements, path, opener, pathjoiner = nil) ⇒ Object
Picks which store to use, given a list of requirements.
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/amp/repository/store.rb', line 7 def pick(requirements, path, opener, pathjoiner=nil) pathjoiner ||= proc {|*args| File.join(args) } if requirements.include? 'store' if requirements.include? 'fncache' return FilenameCacheStore.new(path, opener, pathjoiner) else return EncodedStore.new(path, EncodedOpener, pathjoiner) end else return BasicStore.new(path, opener, pathjoiner) end end |