基于维基(和some of the tests),我认为这将是这个样子(买者自负:我没有访问您的数据,所以我真的不知道,如果这个工程)的Choice syntax节:
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
现在我们的房地产类看起来会更加清晰:
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
选项,但如果你使用这为阅读和不写作你可以跳过他们。我不太确定如何为:data_len
编写:value
选项;或许就像value: -> { data.num_bytes }
。
同样,我不知道上述任何一种方法是否有效,但希望它能起作用。
非常感谢乔丹,这正是我需要的! [如果你确实有一分钟,我在这里问了一个更小的问题。](http://stackoverflow.com/questions/37692554/skipping-bytes-when-reading-with-bindata)最后一个,答应! – Fianite