【问题标题】:Skipping Bytes when reading with BinData使用 BinData 读取时跳过字节
【发布时间】:2016-06-08 03:05:45
【问题描述】:

所以我有这样的记录:

class Property < BinData::Record
    endian :little

    int32  :name_len
    string :name, read_length: :name_len

    # want to quit here.

    int32 :type_len
    string :type, read_length: :type_len
end

只有当 :name 等于某个值时,我有没有办法在读取 :name_len 和 :name 后停止读取记录?或者是不是一旦你开始读取带有 Record 的文件,它就必须一直运行?

我知道我可以使用 :onlyif 跳过所有剩余的内容,但是有没有办法将 :onlyif 放在之后的所有内容上?你能在一个选项上加上 :onlyif 吗?

我试过的代码:

class Property < BinData::Record
    endian :little

    int32  :name_len
    string :name, read_length: :name_len

    int32 :type_len, :onlyif => :not_none?
    string :type, read_length: :type_len, :onlyif => :not_none?

    int64 :data_len, :onlyif => :not_none?    
    choice :data, :onlyif => :not_none?, selection: :type do
        int32 "IntProperty\x00"

        float "FloatProperty\x00"

        struct "StrProperty\x00" do
            int32 :len
            string :data, read_length: :len
        end 

        struct "NameProperty\x00" do
            int32 :len
            string :data, read_length: :len
        end

        struct "ArrayProperty\x00" do
            int32 :num_items
            array :properties, type: :property, initial_length: :num_items
        end
    end

    def not_none?
        name != 'None\x00'
    end
end

我还尝试将 :name_len 和 :name 下面的所有内容放在它自己的记录中并这样做:

class Property < BinData::Record
    endian :little

    string_record :name

    property_data :p_data, :onlyif => :not_none?

    def not_none?
        name.data != 'None\x00'
    end 
end

但这不起作用,因为如果我将 PropertyData Record 放在上面(它必须是因为 Property 需要知道 PropertyData 是什么)然后它会出错,因为 PropertyData 需要知道 Property 是什么(因为它填充了数组与那种类型)。他们没有办法知道彼此的存在,因为他们都互相使用。

【问题讨论】:

  • 当您尝试:onlyif 时发生了什么?您可以在choice 中尝试skip
  • 我这样写了 :onlyif:choice :data, :onlyif =&gt; :not_none?, selection: :type do 但它错误地说无效的选择“”,因为由于相同的 only:if 而没有定义类型。跳过的问题是我不知道我想跳过这些字节,直到我读完它们,只有当 :name 等于某个值时。
  • 请编辑您的问题以包含您尝试过的代码。

标签: ruby bindata


【解决方案1】:

[T]这不起作用,因为如果我将 PropertyData 记录放在上面(它必须是因为 Property 需要知道 PropertyData 是什么)然后它会出错,因为 PropertyData 需要知道 Property 是什么(因为它填充该类型的数组)。

您可以通过在Property之前声明PropertyData类来解决这个问题,但在之后填写:

class PropertyData < BinData::Record; end # Forward declaration

class Property < BinData::Record
  endian :little

  # ...
end

class PropertyData < BinData::Record
  endian :little

  # ...
end

您可以在list.rb example 中看到同样的情况。

【讨论】:

  • 似乎使用前向声明可以让我避免该错误,但无论我做什么,使用:only_if 来防止 Record 对象获取数据似乎都不起作用,无论如何,选择仍然会触发。 I've posted the whole BinData setup on pastebin.
  • 在pastebin代码中,nop?的正文不应该是name.val != "None\x00",而不是name.val == "None\x00"吗?
  • 嘿乔丹,我搞定了。我最终将 Name 元素和其他元素分成不同的记录。然后我只是读取数据的名称,测试它是否没有,相应地读取数据。非常感谢您过去几天的所有帮助!
  • 太棒了!很高兴能提供帮助。
猜你喜欢
  • 2011-11-18
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多