Class: RMasm::Struct::Path
Overview
A path through structure fields : MyStructure.field1.fieldOfSubStructure…etc. This class is used to calculate offset inside a struct and can be used inside any assembler instruction that support it
Instance Attribute Summary collapse
-
#offset ⇒ Object
readonly
Returns the value of attribute offset.
Instance Method Summary collapse
-
#[](arg) ⇒ Object
Handle sub-array reference.
-
#initialize(owner_struct, field) ⇒ Path
constructor
A new instance of Path.
-
#method_missing(sym, *args) ⇒ Object
Method missing is used to resolve the path field.
-
#sizeof ⇒ Object
Calculate the sizeof this field.
- #to_s ⇒ Object
Constructor Details
#initialize(owner_struct, field) ⇒ Path
Returns a new instance of Path.
180 181 182 183 |
# File 'lib/rmasm/struct.rb', line 180 def initialize(owner_struct, field) @__path__ = [owner_struct, field] @offset = field.offset end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args) ⇒ Object
Method missing is used to resolve the path field
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/rmasm/struct.rb', line 229 def method_missing(sym, *args) # Last Field last_field = @__path__[-1] field_type = last_field.type # Does the type of the field respond to the method :sym ? if field_type.respond_to?(sym, false) return field_type.send(sym, *args) end # Is the last field a struct? if field_type.is_struct? # Does the type of the field has a field :sym ? subfield = field_type[sym] if subfield.nil? return Report.error(:R20E2, sym, self) end # If subfield is found, than add it to the path @offset += subfield.offset # update the path and return self @__path__ << subfield return self end # If the field type is a primitive just print a custom message if field_type.is_primitive? return Report.error(:R20F2, sym, self) end # else print an error return Report.error(:R20E2, sym, self) end |
Instance Attribute Details
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
178 179 180 |
# File 'lib/rmasm/struct.rb', line 178 def offset @offset end |
Instance Method Details
#[](arg) ⇒ Object
Handle sub-array reference
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/rmasm/struct.rb', line 186 def [](arg) # Check that the last_field is an array field = @__path__[-1] if field.array_size.nil? return Report.error(:R20G3, arg, self, field.name) end # Check that the index is an integer if ! arg.is_a?(Integer) return Report.error(:R20H2, arg, self) end # Check that the array index is not larger than the size of the field array maximum_index = ((field.array_size ==0)? DWord::MAX : field.array_size) - 1 if arg < 0 || arg > maximum_index return Report.error(:R20I3, arg, "0..#{maximum_index}", self) end # shift byte offset to the index in the array according to the size of the unitary field @offset += field.type.sizeof * arg # Create a new fake field that points to the array array_field_item = Field.new(field.type, "[#{arg}]", nil) # Add this field_array to the path @__path__ << array_field_item self end |
#sizeof ⇒ Object
Calculate the sizeof this field
218 219 220 221 222 223 224 225 226 |
# File 'lib/rmasm/struct.rb', line 218 def sizeof() last_field = @__path__[-1] field_type = last_field.type size = field_type.sizeof if ! last_field.array_size.nil? size = size * last_field.array_size end size end |
#to_s ⇒ Object
264 265 266 267 268 269 270 271 272 273 |
# File 'lib/rmasm/struct.rb', line 264 def to_s() str = "#{@__path__[0]}" @__path__[1..-1].each do |item| if item.name[0] != "[" str << "." end str << "#{item.name}" end str end |