class Arcana::Offset
Public Class Methods
new(str)
click to toggle source
# File lib/arcana.rb, line 60 def initialize(str) @str = str end
Public Instance Methods
exact?()
click to toggle source
# File lib/arcana.rb, line 64 def exact? @str.match?(/\A(?:-?[0-9]+|0x[0-9a-fA-F]+)\z/) end
indirect?()
click to toggle source
# File lib/arcana.rb, line 68 def indirect? @str.start_with?("(") end
position(input)
click to toggle source
# File lib/arcana.rb, line 82 def position(input) if exact? Integer(@str) elsif indirect? @str.match(/\A\(([0-9]+|0x[0-9a-fA-F]+)([.,])([bBcCeEfFgGhHiIlLmsSqQ])([+-](?:[0-9]+|0x[0-9a-fA-F]+))?\)\z/) || return add = $4 ? Integer($4) : 0 value = read_indirect(input, offset: Integer($1), signed: ($2 == ","), type: $3) return unless value # fixme value + add else binding.irb end end
relative?()
click to toggle source
# File lib/arcana.rb, line 72 def relative? @str.start_with?("&") end
seek(input)
click to toggle source
# File lib/arcana.rb, line 76 def seek(input) pos = position(input) return if pos.nil? # FIXME: raise? input.seek_pos(pos) end
to_s()
click to toggle source
# File lib/arcana.rb, line 96 def to_s @str end
Private Instance Methods
read_indirect(input, offset:, type:, signed:)
click to toggle source
# File lib/arcana.rb, line 102 def read_indirect(input, offset:, type:, signed:) input.seek_absolute(offset) return if input.eof? # FIXME case type when "b", "c", "B", "C" input.read(1).ord when "h", "s" input.read(2).unpack("s<")[0] when "H", "S" input.read(2).unpack("s>")[0] when "l" # also default? input.read(2).unpack("l<")[0] when "L" # also default? input.read(2).unpack("l>")[0] when "I" # https://stackoverflow.com/questions/5223025/why-do-mp3-files-use-synchsafe-integers bytes = input.read(4).bytes bytes[0] << 21 | bytes[1] << 14 | bytes[2] << 7 | bytes[3] else binding.irb raise "unsupported indirect type: #{type}" end end