Как начать чтение при смещении в двоичных данных?


У меня есть C-образная структура, подобная этой:

SomeStruct << BinData::Record
endian :little

uint32 :offsetOfName
uint32 :offsetOfLastname
#...
uint32 :lenVars
struct :Person, :length => :lenVars
    string :name
    string :lname
    #...
end

У меня есть куча смещений и длин перед :Person. Все смещения и длины описывают данные внутри структуры :Person.

Как я могу начать чтение данных с заданного смещения, для заданной длины или до следующего смещения?

3 5

3 ответа:

Найдите смещение 1234 и затем считайте 32 байта в строку s:

open 'some-binary-file', 'r' do |f|
  f.seek 1234
  s = f.read 32
  # tho in your case, something like:
  o = aBinData_object.read f
  p s
end

Update: похоже, что BinData понимает записи, которые кодируют длины своих собственных полей, но я сомневаюсь, что есть какой-либо способ заставить его искать вас, если вы не хотите по существу кодировать фиктивные поля размером с видимое пространство, а затем навсегда игнорировать данные, которые он пропускает.

Я подозреваю, что хорошее решение будет включать явный поиск, а затем someBinDataObject.read(f), чтобы получить запись.

BinData имеет две опции, связанные со смещениями -: check_offset и: adjust_offset. Они не задокументированы в руководстве, но задокументированы в bindata/offset.rb

Вот как они будут работать в вашем примере.
class SomeStruct < BinData::Record
  endian :little

  uint32 :offsetOfName
  uint32 :offsetOfLastname
  #...
  uint32 :lenVars

  struct :person do
    string :name,  :adjust_offset => :offsetOfName,
                   :read_length => lambda { offsetOfLastName - offsetOfName }
    string :lname, :adjust_offset => :offsetOfLastName,
                   :read_length => ...
    #...
  end
end

Документы для BinData: http://bindata.rubyforge.org/#nested_records

Не знаком с BinData, так что, возможно, я здесь не прав, но примеры, похоже, определяют класс для самой внешней структуры:

class SomeStruct < BinData::Record
...

Затем он говорит о вложении анонимных структур в этот класс:

  struct :person do
  ...

Кроме того, похоже, что вы даете своей внутренней структуре :человеку длину. Я думаю, что длина здесь не применяется.