63 lines
1.5 KiB
Ruby
63 lines
1.5 KiB
Ruby
# -*- coding: binary -*-
|
|
class BitStruct
|
|
# Class for floats (single and double precision) in network order.
|
|
# Declared with BitStruct.float.
|
|
class FloatField < Field
|
|
# Used in describe.
|
|
def self.class_name
|
|
@class_name ||= "float"
|
|
end
|
|
|
|
def add_accessors_to(cl, attr = name) # :nodoc:
|
|
unless offset % 8 == 0
|
|
raise ArgumentError,
|
|
"Bad offset, #{offset}, for #{self.class} #{name}." +
|
|
" Must be multiple of 8."
|
|
end
|
|
|
|
unless length == 32 or length == 64
|
|
raise ArgumentError,
|
|
"Bad length, #{length}, for #{self.class} #{name}." +
|
|
" Must be 32 or 64."
|
|
end
|
|
|
|
offset_byte = offset / 8
|
|
length_byte = length / 8
|
|
last_byte = offset_byte + length_byte - 1
|
|
byte_range = offset_byte..last_byte
|
|
|
|
endian = (options[:endian] || options["endian"]).to_s
|
|
case endian
|
|
when "native"
|
|
ctl = case length
|
|
when 32; "f"
|
|
when 64; "d"
|
|
end
|
|
when "little"
|
|
ctl = case length
|
|
when 32; "e"
|
|
when 64; "E"
|
|
end
|
|
when "network", "big", ""
|
|
ctl = case length
|
|
when 32; "g"
|
|
when 64; "G"
|
|
end
|
|
else
|
|
raise ArgumentError,
|
|
"Unrecognized endian option: #{endian.inspect}"
|
|
end
|
|
|
|
cl.class_eval do
|
|
define_method attr do ||
|
|
self[byte_range].unpack(ctl).first
|
|
end
|
|
|
|
define_method "#{attr}=" do |val|
|
|
self[byte_range] = [val].pack(ctl)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|