Class: WolfRpg::FileCoder
- Inherits:
-
Object
- Object
- WolfRpg::FileCoder
- Defined in:
- lib/wolfrpg/filecoder.rb
Constant Summary collapse
- CRYPT_HEADER_SIZE =
Constants #
10
- DECRYPT_INTERVALS =
[1, 2, 5]
Instance Attribute Summary collapse
-
#crypt_header ⇒ Object
readonly
Returns the value of attribute crypt_header.
-
#io ⇒ Object
readonly
Attributes #.
Class Method Summary collapse
Instance Method Summary collapse
-
#close ⇒ Object
Other #.
- #dump(size) ⇒ Object
- #dump_until(pattern) ⇒ Object
- #encrypted? ⇒ Boolean
- #eof? ⇒ Boolean
-
#initialize(io, crypt_header = nil, filename = nil, seed_indices = nil) ⇒ FileCoder
constructor
Initialize #.
-
#read(size = nil) ⇒ Object
Read #.
- #read_byte ⇒ Object
- #read_byte_array ⇒ Object
- #read_int ⇒ Object
- #read_int_array ⇒ Object
- #read_string ⇒ Object
- #read_string_array ⇒ Object
- #skip(size) ⇒ Object
- #tell ⇒ Object
- #verify(data) ⇒ Object
-
#write(data) ⇒ Object
Write #.
- #write_byte(data) ⇒ Object
- #write_byte_array(bytes) ⇒ Object
- #write_int(data) ⇒ Object
- #write_int_array(ints) ⇒ Object
- #write_string(str) ⇒ Object
- #write_string_array(strings) ⇒ Object
Constructor Details
#initialize(io, crypt_header = nil, filename = nil, seed_indices = nil) ⇒ FileCoder
Initialize #
59 60 61 62 63 |
# File 'lib/wolfrpg/filecoder.rb', line 59 def initialize(io, crypt_header = nil, filename = nil, seed_indices = nil) @io = io @crypt_header = crypt_header @filename = filename end |
Instance Attribute Details
#crypt_header ⇒ Object (readonly)
Returns the value of attribute crypt_header.
6 7 8 |
# File 'lib/wolfrpg/filecoder.rb', line 6 def crypt_header @crypt_header end |
#io ⇒ Object (readonly)
Attributes #
5 6 7 |
# File 'lib/wolfrpg/filecoder.rb', line 5 def io @io end |
Class Method Details
.open(filename, mode, seed_indices = nil, crypt_header = nil) ⇒ Object
Class methods #
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/wolfrpg/filecoder.rb', line 18 def self.open(filename, mode, seed_indices = nil, crypt_header = nil) case mode when :read coder = FileCoder.new(File.open(filename, 'rb')) # If encryptable, # we need to make an extra check to see if it needs decrypting if seed_indices unless (indicator = coder.read_byte) == 0 header = [indicator] (CRYPT_HEADER_SIZE - 1).times { |i| header << coder.read_byte } seeds = seed_indices.map { |i| header[i] } data = crypt(coder.read, seeds) coder = FileCoder.new(StringIO.new(data, 'rb'), header) end end when :write # If encryptable, open a StringIO and pass the encryption options # to the FileCoder if seed_indices && crypt_header coder = FileCoder.new(StringIO.new(''.force_encoding('BINARY'), 'wb'), crypt_header, filename, seed_indices) coder.write(crypt_header.pack('C*')) else coder = FileCoder.new(File.open(filename, 'wb')) coder.write_byte(0) if seed_indices end end if block_given? begin yield coder ensure coder.close end end return coder end |
Instance Method Details
#close ⇒ Object
Other #
188 189 190 191 192 193 194 195 196 197 |
# File 'lib/wolfrpg/filecoder.rb', line 188 def close if @crypt_header && @filename && @seed_indices File.open(@filename, 'wb') do |file| file.write(@crypt_header.pack('C*')) seeds = @seed_indices.map { |i| crypt_header[i] } file.write(FileCoder.crypt(@io.string, seeds)) end end @io.close end |
#dump(size) ⇒ Object
126 127 128 129 130 131 |
# File 'lib/wolfrpg/filecoder.rb', line 126 def dump(size) size.times do |i| print " %02x" % read_byte end print "\n" end |
#dump_until(pattern) ⇒ Object
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/wolfrpg/filecoder.rb', line 133 def dump_until(pattern) str = ''.force_encoding('BINARY') until str.end_with? pattern str << @io.readpartial(1) end str[0...-pattern.bytesize].each_byte do |byte| print " %02x" % byte end print "\n" end |
#encrypted? ⇒ Boolean
7 8 9 |
# File 'lib/wolfrpg/filecoder.rb', line 7 def encrypted? @crypt_header != nil end |
#eof? ⇒ Boolean
199 200 201 |
# File 'lib/wolfrpg/filecoder.rb', line 199 def eof? @io.eof? end |
#read(size = nil) ⇒ Object
Read #
67 68 69 70 71 72 73 |
# File 'lib/wolfrpg/filecoder.rb', line 67 def read(size = nil) if size @io.readpartial(size) else @io.read end end |
#read_byte ⇒ Object
75 76 77 |
# File 'lib/wolfrpg/filecoder.rb', line 75 def read_byte @io.readpartial(1).ord end |
#read_byte_array ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/wolfrpg/filecoder.rb', line 91 def read_byte_array bytes = Array.new(read_int) bytes.each_index do |i| bytes[i] = read_byte end return bytes end |
#read_int ⇒ Object
79 80 81 |
# File 'lib/wolfrpg/filecoder.rb', line 79 def read_int @io.readpartial(4).unpack('l<').first end |
#read_int_array ⇒ Object
99 100 101 102 103 104 105 |
# File 'lib/wolfrpg/filecoder.rb', line 99 def read_int_array ints = Array.new(read_int) ints.each_index do |i| ints[i] = read_int end return ints end |
#read_string ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/wolfrpg/filecoder.rb', line 83 def read_string size = read_int raise "got a string of size <= 0" unless size > 0 str = read(size - 1).encode(Encoding::UTF_8, Encoding::WINDOWS_31J) raise "string not null-terminated" unless read_byte == 0 return str end |
#read_string_array ⇒ Object
107 108 109 110 111 112 113 |
# File 'lib/wolfrpg/filecoder.rb', line 107 def read_string_array strings = Array.new(read_int) strings.each_index do |i| strings[i] = read_string end return strings end |
#skip(size) ⇒ Object
122 123 124 |
# File 'lib/wolfrpg/filecoder.rb', line 122 def skip(size) @io.seek(size, IO::SEEK_CUR) end |
#tell ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/wolfrpg/filecoder.rb', line 203 def tell if encrypted? @io.tell + CRYPT_HEADER_SIZE else @io.tell end end |
#verify(data) ⇒ Object
115 116 117 118 119 120 |
# File 'lib/wolfrpg/filecoder.rb', line 115 def verify(data) got = read(data.length) if got != data raise "could not verify magic data (expecting #{data.unpack('C*')}, got #{got.unpack('C*')})" end end |
#write(data) ⇒ Object
Write #
146 147 148 |
# File 'lib/wolfrpg/filecoder.rb', line 146 def write(data) @io.write(data) end |
#write_byte(data) ⇒ Object
150 151 152 |
# File 'lib/wolfrpg/filecoder.rb', line 150 def write_byte(data) @io.write(data.chr) end |
#write_byte_array(bytes) ⇒ Object
165 166 167 168 169 170 |
# File 'lib/wolfrpg/filecoder.rb', line 165 def write_byte_array(bytes) write_int(bytes.size) bytes.each do |b| write_byte(b) end end |
#write_int(data) ⇒ Object
154 155 156 |
# File 'lib/wolfrpg/filecoder.rb', line 154 def write_int(data) @io.write([data].pack('l<')) end |
#write_int_array(ints) ⇒ Object
172 173 174 175 176 177 |
# File 'lib/wolfrpg/filecoder.rb', line 172 def write_int_array(ints) write_int(ints.size) ints.each do |i| write_int(i) end end |
#write_string(str) ⇒ Object
158 159 160 161 162 163 |
# File 'lib/wolfrpg/filecoder.rb', line 158 def write_string(str) str = str.encode(Encoding::WINDOWS_31J, Encoding::UTF_8) write_int(str.bytesize + 1) write(str) write_byte(0) end |
#write_string_array(strings) ⇒ Object
179 180 181 182 183 184 |
# File 'lib/wolfrpg/filecoder.rb', line 179 def write_string_array(strings) write_int(strings.size) strings.each do |s| write_string(s) end end |