Class: RuneRb::Cache::FileSystem
- Inherits:
-
Object
- Object
- RuneRb::Cache::FileSystem
- Includes:
- RuneRb::Core::Logging
- Defined in:
- lib/rune/cache/file_system.rb
Overview
Defined Under Namespace
Classes: FileDescriptor
Instance Attribute Summary collapse
-
#cache ⇒ Hash<FileDescriptor, RuneRb::Cache::Archive>
readonly
A map of decoded archives.
-
#crc ⇒ Array<Integer>
readonly
The CRC values for the cache.
-
#crc_table ⇒ RuneRb::Core::Buffer
readonly
The CRC table for the cache.
-
#data_file ⇒ StringIO
readonly
The data file for the cache.
-
#indicies ⇒ Array<StringIO>
readonly
The indicies for the cache.
Instance Method Summary collapse
-
#archive(type, file) ⇒ Object
Retrieves an Archive by the specified FileDescriptor.
-
#cache_count ⇒ Integer
The number of index files in the cache.
-
#cache_file(descriptor) ⇒ RuneRb::Core::Buffer
Retrieves a RuneRb::Core::Buffer that corresponds to the specified FileDescriptor in the cache.
-
#check_for_archives(path) ⇒ Object
Checks for the existence of cache archives in a path.
- #close ⇒ Object
-
#file_count(cache) ⇒ Object
The number of files in a cache.
- #index_for(descriptor) ⇒ Object
-
#initialize(path) ⇒ FileSystem
constructor
Constructs a new FileSystem instance.
-
#read_layout(path) ⇒ Object
Reads the layout of the cache from the specified path.
Methods included from RuneRb::Core::Logging
Constructor Details
#initialize(path) ⇒ FileSystem
Constructs a new FileSystem instance.
27 28 29 30 31 32 33 34 |
# File 'lib/rune/cache/file_system.rb', line 27 def initialize(path) @indicies = Array.new @crc_table = RuneRb::Core::Buffer.new(mode: 'r') @crc = Array.new @cache = Hash.new @data_file = StringIO.new read_layout(path) end |
Instance Attribute Details
#cache ⇒ Hash<FileDescriptor, RuneRb::Cache::Archive> (readonly)
Returns a map of decoded archives.
7 8 9 |
# File 'lib/rune/cache/file_system.rb', line 7 def cache @cache end |
#crc ⇒ Array<Integer> (readonly)
Returns the CRC values for the cache.
15 16 17 |
# File 'lib/rune/cache/file_system.rb', line 15 def crc @crc end |
#crc_table ⇒ RuneRb::Core::Buffer (readonly)
Returns the CRC table for the cache.
11 12 13 |
# File 'lib/rune/cache/file_system.rb', line 11 def crc_table @crc_table end |
#data_file ⇒ StringIO (readonly)
Returns the data file for the cache.
23 24 25 |
# File 'lib/rune/cache/file_system.rb', line 23 def data_file @data_file end |
#indicies ⇒ Array<StringIO> (readonly)
Returns the indicies for the cache.
19 20 21 |
# File 'lib/rune/cache/file_system.rb', line 19 def indicies @indicies end |
Instance Method Details
#archive(type, file) ⇒ Object
Retrieves an Archive by the specified FileDescriptor.
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rune/cache/file_system.rb', line 39 def archive(type, file) descriptor = FileDescriptor.new(type, file) cached = @cache[descriptor] if cached == nil file = cache_file(descriptor) cached = RuneRb::Cache::Archive.decode(file) @cache[descriptor] = cached end cached end |
#cache_count ⇒ Integer
The number of index files in the cache.
135 136 137 |
# File 'lib/rune/cache/file_system.rb', line 135 def cache_count @indicies.length end |
#cache_file(descriptor) ⇒ RuneRb::Core::Buffer
Retrieves a RuneRb::Core::Buffer that corresponds to the specified FileDescriptor in the cache.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/rune/cache/file_system.rb', line 58 def cache_file(descriptor) index = index_for(descriptor) buffer = RuneRb::Core::Buffer.new(mode: 'r') position = index.block * RuneRb::Cache::BLOCK_SIZE read = 0 size = index.size blocks = size / RuneRb::Cache::CHUNK_SIZE if size % RuneRb::Cache::CHUNK_SIZE != 0 blocks += 1 end info "Reading #{blocks} blocks from position #{position}." blocks.times do |i| @data_file.seek(position) header = @data_file.read header_data = header.unpack('C*') position += RuneRb::Cache::HEADER_SIZE next_file = header_data[0] << 8 | header_data[1] current_chunk = header_data[2] << 8 | header_data[3] next_block = header_data[4] << 16 | header_data[5] << 8 | header_data[6] next_type = header_data[7] raise "Chunk id mismatch! (Current #{current_chunk}, Expected #{i})" if current_chunk != i chunk_size = size - read chunk_size = RuneRb::Cache::CHUNK_SIZE if chunk_size > RuneRb::Cache::CHUNK_SIZE @data_file.seek(position) buffer << @data_file.read read += chunk_size position = next_block * RuneRb::Cache::BLOCK_SIZE if size > read raise "Next type (#{next_type}) does not match descriptor type (#{descriptor.type + 1})." if next_type != descriptor.type + 1 raise "Next file (#{next_file}) does not match descriptor file (#{descriptor.file})." if next_file != descriptor.file end end info "Read #{buffer.length} from cache." buffer end |
#check_for_archives(path) ⇒ Object
Checks for the existence of cache archives in a path.
167 168 169 170 171 172 173 174 |
# File 'lib/rune/cache/file_system.rb', line 167 def check_for_archives(path) return false if path.nil? return false unless File.directory?(path) return false unless File.exist?(path) return false unless File.readable?(path) return false if Dir.empty?(path) true end |
#close ⇒ Object
128 129 130 131 |
# File 'lib/rune/cache/file_system.rb', line 128 def close @indicies.each(&:close) @data_file.close end |
#file_count(cache) ⇒ Object
The number of files in a cache.
141 142 143 |
# File 'lib/rune/cache/file_system.rb', line 141 def file_count(cache) (@indicies[cache].size / RuneRb::Core::INDEX_SIZE) - 1 end |
#index_for(descriptor) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/rune/cache/file_system.rb', line 107 def index_for(descriptor) idx = descriptor.type raise "Index out of bounds. (#{idx})" if idx < 0 || idx >= @indicies.length buffer = String.new idx_file = @indicies[idx] position = descriptor.file * RuneRb::Cache::INDEX_SIZE info "Reading index from position #{position}" if position >= 0 && (idx_file.length >= (position + RuneRb::Cache::INDEX_SIZE)) idx_file.seek(position, IO::SEEK_CUR) buffer << idx_file.read else raise "Could not find index file at position #{position}." end info " Length: #{buffer.length}, Index data: #{buffer.bytes}" RuneRb::Cache::Index.decode(buffer) end |
#read_layout(path) ⇒ Object
Reads the layout of the cache from the specified path.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/rune/cache/file_system.rb', line 148 def read_layout(path) raise "Cache archive not found. Please install them into the #{path} directory." unless check_for_archives(path) # Find how many index files exist count = 0.upto(255).each do |i| break i unless File.exist?(File.join(path, "main_file_cache.idx#{i}")) end # Gather file objects @data_file = File.open(File.join(path, "main_file_cache.dat"), "r") count.times do |i| data = File.read("#{path}/main_file_cache.idx#{i}") @indicies[i] = StringIO.new(data) end end |