Class: Bayonetta::EFFFile::Directory
- Inherits:
-
Object
- Object
- Bayonetta::EFFFile::Directory
- Includes:
- Alignment, Bayonetta::Endianness
- Defined in:
- lib/bayonetta/eff.rb
Constant Summary collapse
- EXTENSIONS =
{ "TEX\0".b => "wtb", "MOD\0".b => "dat" }
- ALIGNMENT =
{ "TEX\0".b => 0x1000, "MOD\0".b => 0x1000, "EST\0".b => 0x10, "IDT\0".b => 0x10 }
- KNOWN_DIRECTORIES =
[ "SAD\0".b, "SST\0".b, "TUV\0".b, "TEX\0".b, "MOD\0".b, "EST\0".b ]
- KNOWN_STRUCTURE =
[ "TEX\0".b, "MOD\0".b, "EST\0".b, "IDT\0".b ]
- UNKNOWN_STRUCTURE =
KNOWN_DIRECTORIES - KNOWN_STRUCTURE
Instance Attribute Summary collapse
-
#big ⇒ Object
readonly
Returns the value of attribute big.
-
#file_infos ⇒ Object
Returns the value of attribute file_infos.
-
#file_number ⇒ Object
Returns the value of attribute file_number.
-
#files ⇒ Object
Returns the value of attribute files.
-
#name ⇒ Object
Returns the value of attribute name.
Instance Method Summary collapse
- #compute_layout ⇒ Object
- #each ⇒ Object
-
#initialize(f, big) ⇒ Directory
constructor
A new instance of Directory.
- #push(id, f) ⇒ Object
- #size ⇒ Object
- #to_stringio ⇒ Object
Constructor Details
#initialize(f, big) ⇒ Directory
Returns a new instance of Directory.
47 48 49 50 51 52 53 54 55 56 57 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 |
# File 'lib/bayonetta/eff.rb', line 47 def initialize(f, big) @big = big if f @name = f.read(4) case @name when *UNKNOWN_STRUCTURE f.rewind @file_number = 1 @file_infos = [[0, 0, f.size]] @files = [f] when *KNOWN_STRUCTURE uint = get_uint @file_number = f.read(4).unpack(uint).first @file_infos = @file_number.times.collect { |i| f.read(8).unpack("#{uint}2") } sorted_file_infos = @file_infos.sort { |e1, e2| e1[1] <=> e2[1] } sorted_file_infos.each_with_index { |info, i| id, offset = info if sorted_file_infos[i+1] size = sorted_file_infos[i+1][1] - offset else size = f.size - offset end info.push(size) } @files = @file_infos.collect { |id, offset, size| f.seek(offset) of = StringIO::new( f.read(size), "rb") } else raise "Unknown directory type: #{@name}!" end @extname = EXTENSIONS[@name] @extname = @name.delete("\x00").downcase unless @extname else @name = nil @file_number = 0 @file_infos = [] @files = [] end end |
Instance Attribute Details
#big ⇒ Object (readonly)
Returns the value of attribute big.
17 18 19 |
# File 'lib/bayonetta/eff.rb', line 17 def big @big end |
#file_infos ⇒ Object
Returns the value of attribute file_infos.
15 16 17 |
# File 'lib/bayonetta/eff.rb', line 15 def file_infos @file_infos end |
#file_number ⇒ Object
Returns the value of attribute file_number.
14 15 16 |
# File 'lib/bayonetta/eff.rb', line 14 def file_number @file_number end |
#files ⇒ Object
Returns the value of attribute files.
16 17 18 |
# File 'lib/bayonetta/eff.rb', line 16 def files @files end |
#name ⇒ Object
Returns the value of attribute name.
18 19 20 |
# File 'lib/bayonetta/eff.rb', line 18 def name @name end |
Instance Method Details
#compute_layout ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/bayonetta/eff.rb', line 119 def compute_layout case @name when *UNKNOWN_STRUCTURE raise "Unsupported file number #{@file_number}!" unless @file_number == 1 @file_infos[0][1] = 0x0 @file_infos[0][2] when *KNOWN_STRUCTURE current_offset = align(4 + 4 + @file_infos.length * 8, ALIGNMENT[@name]) @file_infos = @file_infos.collect { |id, _, size| ret = [id, current_offset, size] current_offset += size current_offset = align(current_offset, ALIGNMENT[@name]) ret } current_offset else raise "Invalid directory #{@name}!" end end |
#each ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/bayonetta/eff.rb', line 90 def each if block_given? @file_number.times { |i| yield ("%010d." % @file_infos[i][0])+@extname, @files[i] } else to_enum(:each) end end |
#push(id, f) ⇒ Object
100 101 102 103 104 105 106 107 108 |
# File 'lib/bayonetta/eff.rb', line 100 def push(id, f) f.rewind sz = f.size of = StringIO::new( f.read, "rb") @file_number += 1 @files.push of @file_infos.push [id, nil, sz] self end |
#size ⇒ Object
139 140 141 |
# File 'lib/bayonetta/eff.rb', line 139 def size compute_layout end |
#to_stringio ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/bayonetta/eff.rb', line 143 def to_stringio total_size = compute_layout str = StringIO::new("\x00".b*total_size, "w+b") str.rewind case @name when *UNKNOWN_STRUCTURE f = @files[0] f.rewind str.write f.read f.rewind when *KNOWN_STRUCTURE uint = get_uint str.write @name str.write [@file_number].pack(uint) @file_infos.each { |id, offset, _| str.write [id, offset].pack("#{uint}*") } @file_number.times { |i| str.seek(@file_infos[i][1]) f = @files[i] f.rewind str.write f.read f.rewind } end str.rewind str.close_write str end |