我不确定选择是否符合我的要求,但我会解释我想要做的事情。我有以下BinData结构,工作正常。
class Property < BinData::Record
endian :little
int32 :name_len
string :name, :read_length => :name_len
int32 :type_len
string :type, :read_length => :type_len
int64 :data_len
end
然而,在我得到:data_len后,我需要获取实际数据。我如何处理接下来的内容取决于:type string的值。
任何人都可以帮我弄清楚如何导航这些路径并正确设置BinData :: Record吗?
答案 0 :(得分:0)
根据维基的Choice syntax部分(以及some of the tests),我认为它看起来像这样(警告经理:我没有访问您的数据,所以我真的不知道这是否有效):
class Property < BinData::Record
endian :little
int32 :name_len
string :name, read_length: :name_len
int32 :type_len
string :type, read_length: :type_len
int64 :data_len
choice :data, selection: :type do
# if type is "IntProperty" then the next four bytes (int32) is an int.
int32 "IntProperty"
# if type is "FloatProperty" then the next four bytes (float_32) is a float.
float "FloatProperty"
# if type is "StringProperty" then the next four bytes (int32) is an int (len
# of string) and the next (len * 8) are the string itself.
struct "StringProperty" do
int32 :len
string :data, read_length: :len
end
# if type is "ArrayProperty" then the next four bytes (int32) is an int (len
# of array), then next however many bytes is len of array many Property objects
# (to store in an array).
struct "ArrayProperty" do
int32 :num_properties
array :properties, type: :property, initial_length: :num_items
end
end
end
然而,我认为将它分成几类是有益的。我们在一些地方有int32
/ string
对,所以让我们将它们抽象到自己的类中:
class StringRecord < BinData::Record
endian :little
int32 :len, value: -> { data.length }
string :data, read_length: :len
end
如果您愿意,还可以make that a Primitive。
一个"PropertyArray"
类型:
class ArrayOfProperties < BinData::Record
endian :little
int32 :num_properties, value: -> { properties.size }
array :properties, type: :property, initial_length: :num_items
end
现在我们的Property类看起来更干净了:
class Property < BinData::Record
endian :little
string_record :name
string_record :type
int64 :data_len
choice :data, selection: :type do
int32 "IntProperty"
float "FloatProperty"
string_record "StringProperty"
array_of_properties "ArrayProperty"
end
end
我已为长度字段指定了:value
个选项,但如果您使用此选项进行阅读而不是写作,则可以跳过它们。我不太确定如何为:value
编写:data_len
选项;也许像value: -> { data.num_bytes }
。
同样,我不知道上述任何一项是否有效,但希望它会有所帮助。