зеркало из https://github.com/github/ruby.git
[ruby/fiddle] Make array access override compatible with base class (#25)
* Allow access to a struct's underlying memory with `struct[offset, length]`. * Make accessing a struct's underlying memory more convenient. * refactor memory access unit tests for improved clarity https://github.com/ruby/fiddle/commit/c082c81bb5
This commit is contained in:
Родитель
aa1d3c7d2c
Коммит
4a835621ce
|
@ -54,6 +54,8 @@ module Fiddle
|
|||
@entity = klass.entity_class.new(addr, types)
|
||||
@entity.assign_names(members)
|
||||
}
|
||||
define_method(:[]) { |*args| @entity.send(:[], *args) }
|
||||
define_method(:[]=) { |*args| @entity.send(:[]=, *args) }
|
||||
define_method(:to_ptr){ @entity }
|
||||
define_method(:to_i){ @entity.to_i }
|
||||
members.each{|name|
|
||||
|
@ -148,8 +150,21 @@ module Fiddle
|
|||
@size = PackInfo.align(offset, max_align)
|
||||
end
|
||||
|
||||
# Fetch struct member +name+
|
||||
def [](name)
|
||||
# Fetch struct member +name+ if only one argument is specified. If two
|
||||
# arguments are specified, the first is an offset and the second is a
|
||||
# length and this method returns the string of +length+ bytes beginning at
|
||||
# +offset+.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# my_struct = struct(['int id']).malloc
|
||||
# my_struct.id = 1
|
||||
# my_struct['id'] # => 1
|
||||
# my_struct[0, 4] # => "\x01\x00\x00\x00".b
|
||||
#
|
||||
def [](*args)
|
||||
return super(*args) if args.size > 1
|
||||
name = args[0]
|
||||
idx = @members.index(name)
|
||||
if( idx.nil? )
|
||||
raise(ArgumentError, "no such member: #{name}")
|
||||
|
@ -182,8 +197,20 @@ module Fiddle
|
|||
end
|
||||
end
|
||||
|
||||
# Set struct member +name+, to value +val+
|
||||
def []=(name, val)
|
||||
# Set struct member +name+, to value +val+. If more arguments are
|
||||
# specified, writes the string of bytes to the memory at the given
|
||||
# +offset+ and +length+.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# my_struct = struct(['int id']).malloc
|
||||
# my_struct['id'] = 1
|
||||
# my_struct[0, 4] = "\x01\x00\x00\x00".b
|
||||
# my_struct.id # => 1
|
||||
#
|
||||
def []=(*args)
|
||||
return super(*args) if args.size > 2
|
||||
name, val = *args
|
||||
idx = @members.index(name)
|
||||
if( idx.nil? )
|
||||
raise(ArgumentError, "no such member: #{name}")
|
||||
|
|
|
@ -54,6 +54,28 @@ module Fiddle
|
|||
assert_match(/call dlload before/, err.message)
|
||||
end
|
||||
|
||||
def test_struct_memory_access()
|
||||
# check memory operations performed directly on struct
|
||||
my_struct = Fiddle::Importer.struct(['int id']).malloc
|
||||
my_struct[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
|
||||
assert_equal 0x01010101, my_struct.id
|
||||
|
||||
my_struct.id = 0
|
||||
assert_equal "\x00".b * Fiddle::SIZEOF_INT, my_struct[0, Fiddle::SIZEOF_INT]
|
||||
end
|
||||
|
||||
def test_struct_ptr_array_subscript_multiarg()
|
||||
# check memory operations performed on struct#to_ptr
|
||||
struct = Fiddle::Importer.struct([ 'int x' ]).malloc
|
||||
ptr = struct.to_ptr
|
||||
|
||||
struct.x = 0x02020202
|
||||
assert_equal("\x02".b * Fiddle::SIZEOF_INT, ptr[0, Fiddle::SIZEOF_INT])
|
||||
|
||||
ptr[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
|
||||
assert_equal 0x01010101, struct.x
|
||||
end
|
||||
|
||||
def test_malloc()
|
||||
s1 = LIBC::Timeval.malloc()
|
||||
s2 = LIBC::Timeval.malloc()
|
||||
|
|
Загрузка…
Ссылка в новой задаче