Fix and cleanup MemberValues bugs

This commit is contained in:
Spencer McIntyre
2020-04-04 12:17:23 -04:00
parent 94d67eae87
commit f447feb328
2 changed files with 40 additions and 17 deletions
@@ -13,8 +13,8 @@ module Primitives
self.val != 0
end
def set(v)
self.val = v ? 1 : 0
def set(value)
self.val = value ? 1 : 0
end
end
@@ -55,8 +55,8 @@ module Primitives
class LengthPrefixedString < BinData::BasePrimitive
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/10b218f5-9b2b-4947-b4b7-07725a2c8127
def assign(val)
super(binary_string(val))
def assign(value)
super(binary_string(value))
end
private
@@ -91,7 +91,7 @@ module Primitives
def get
end
def set(v)
def set(value)
end
end
@@ -107,8 +107,8 @@ module Primitives
self.val
end
def set(v)
self.val = v
def set(value)
self.val = value
register_self
end
@@ -127,7 +127,7 @@ module Primitives
mandatory_parameter :member_type_info
array :member_values, initial_length: -> { class_info.member_count } do
choice :member_value, :selection => lambda { selection_routine(index) } do
record -1
record Types::Record
boolean Enums::PrimitiveTypeEnum[:Boolean]
uint8 Enums::PrimitiveTypeEnum[:Byte]
#??? Enums::PrimitiveTypeEnum[:Char] # todo: implement this primitive type
@@ -148,37 +148,42 @@ module Primitives
end
end
attr_reader :params
def get
self.member_values
end
def set(v)
self.member_values = v
def set(member_values)
return if self.member_values.object_id == member_values.object_id
self.member_values = member_values
end
private
def selection_routine(index)
index = index || 0
member_type = eval_parameter(:member_type_info).member_types[index]
if member_type[:binary_type] == Enums::BinaryTypeEnum[:Primitive]
return member_type[:additional_info]
end
-1
Types::Record
end
module Factory
def from_member_values(class_info:, member_type_info:, member_values:, **kwargs)
raise ArgumentError unless class_info.member_count == member_values.length
mv = MemberValues.new(
member_values,
class_info: class_info,
member_type_info: member_type_info
kwargs[:class_info] = class_info
kwargs[:member_type_info] = member_type_info
kwargs[:member_values] = MemberValues.new(
member_values,
class_info: class_info,
member_type_info: member_type_info
)
self.new(class_info: class_info, member_type_info: member_type_info, member_values: mv, **kwargs)
# pass class_info and member_type_info as *both* a value and a parameter
self.new(kwargs, class_info: class_info, member_type_info: member_type_info)
end
end
end
@@ -34,22 +34,40 @@ module RecordValues
class ClassWithId < BinData::Record
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/2d168388-37f4-408a-b5e0-e48dbce73e26
RECORD_TYPE = Enums::RecordTypeEnum[:ClassWithId]
default_parameter class_info: nil
default_parameter member_type_info: nil
endian :little
obj_id :obj_id
int32 :metadata_id
member_values :member_values, class_info: -> { class_info }, member_type_info: -> { member_type_info }
attr_reader :params
def assign(val, *args)
self.params.merge!(val.params) if val.is_a? self.class
super(val, *args)
end
def class_info
ci = eval_parameter(:class_info)
return ci unless ci.nil?
stream = DotNetDeserialization.get_ancestor(self, SerializedStream)
object = stream.get_object(metadata_id.value)
object.record_value.class_info
end
def member_type_info
mti = eval_parameter(:member_type_info)
return mti unless mti.nil?
stream = DotNetDeserialization.get_ancestor(self, SerializedStream)
object = stream.get_object(metadata_id.value)
object.record_value.member_type_info
end
include Primitives::MemberValues::Factory
self.singleton_class.include Primitives::MemberValues::Factory
end
class ClassWithMembersAndTypes < BinData::Record