Class: MppReader::Blocks::FixedMeta
- Inherits:
-
Object
- Object
- MppReader::Blocks::FixedMeta
- Defined in:
- lib/mpp_reader/blocks/fixed_meta.rb
Overview
Index for a FixedData block. Layout (ported from MPXJ FixedMeta): 16-byte header (magic 0xFADFADBA, unknown, item count, unknown), then fixed-size meta items. The item count in the header is unreliable; the real count is derived from the block size. Bytes 4-7 of each meta item hold the corresponding item’s offset within the FixedData block.
Constant Summary collapse
- MAGIC =
0xFADFADBA- HEADER_SIZE =
16
Instance Attribute Summary collapse
-
#header_item_count ⇒ Object
readonly
Returns the value of attribute header_item_count.
-
#item_count ⇒ Object
readonly
Returns the value of attribute item_count.
Class Method Summary collapse
-
.with_derived_item_size(data, candidates, sibling_item_count) ⇒ Object
Some blocks (e.g. Fixed2Meta) have a version-dependent item size.
Instance Method Summary collapse
- #[](index) ⇒ Object
-
#initialize(data, item_size) ⇒ FixedMeta
constructor
A new instance of FixedMeta.
- #item_offset(index) ⇒ Object
Constructor Details
#initialize(data, item_size) ⇒ FixedMeta
Returns a new instance of FixedMeta.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 39 def initialize(data, item_size) magic = data.byteslice(0, 4).to_s.unpack1("V") unless magic == MAGIC raise CorruptFileError, format("bad FixedMeta magic 0x%08x", magic.to_i) end # The header count can be lower than the block-derived count when # stale records linger at the end; some readers must honour it. @header_item_count = data.byteslice(8, 4).unpack1("V") @item_count = (data.bytesize - HEADER_SIZE) / item_size @items = Array.new(@item_count) do |i| data.byteslice(HEADER_SIZE + i * item_size, item_size) end end |
Instance Attribute Details
#header_item_count ⇒ Object (readonly)
Returns the value of attribute header_item_count.
12 13 14 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 12 def header_item_count @header_item_count end |
#item_count ⇒ Object (readonly)
Returns the value of attribute item_count.
12 13 14 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 12 def item_count @item_count end |
Class Method Details
.with_derived_item_size(data, candidates, sibling_item_count) ⇒ Object
Some blocks (e.g. Fixed2Meta) have a version-dependent item size. Pick the candidate that divides the block evenly, preferring one whose item count matches a sibling block’s; otherwise the closest fit by MPXJ’s rule of thumb (header count * size vs available).
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 18 def self.with_derived_item_size(data, candidates, sibling_item_count) available = data.bytesize - HEADER_SIZE header_count = data.byteslice(8, 4).to_s.unpack1("V").to_i chosen = nil best_distance = nil candidates.each do |size| next unless (available % size).zero? if available / size == sibling_item_count chosen = size break end distance = header_count * size - available if distance <= 0 && (best_distance.nil? || distance > best_distance) chosen = size best_distance = distance end end new(data, chosen || candidates.first) end |
Instance Method Details
#[](index) ⇒ Object
54 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 54 def [](index) = @items[index] |
#item_offset(index) ⇒ Object
56 57 58 59 |
# File 'lib/mpp_reader/blocks/fixed_meta.rb', line 56 def item_offset(index) item = @items[index] item && item.byteslice(4, 4).to_s.unpack1("V") end |