Marcel::Magic::Zip
Procedural refinement of ZIP-based container types.
The declarative magic tables scan a bounded prefix of the file (matchers are capped at 64KB offsets when the tables are generated), so ZIP containers whose distinguishing members are catalogued later in the archive — such as OOXML documents with [Content_Types].xml stored past the 64KB mark — fall back to their generic container type. This module instead parses the ZIP central directory, a bounded read from the end of the file, to recover the specific document type, including macro-enabled variants, which no prefix bytes can distinguish.
Constants
Standardised OPC part names identifying each OOXML document family: main part, macro part, and the types each implies.
A malformed trailer full of EOCD signature bytes could otherwise force a quadratic backward scan; real archives find the record on the first candidate.
The end-of-central-directory record sits at most a maximal comment from the end of the file, possibly preceded by a Zip64 locator.
Container types a central directory listing can make more specific.
4 (сигнатура) + 4 (диск) + 8 (смещение) + 2 (всего дисков, u16 — как в zip.rb: unpack("VQ<V"), 18-байтовая запись).
Class methods
A main part plus its macro part is as specific as classification gets.
Reads the archive's central directory and returns the OOXML part names it catalogues, or nil if no well-formed central directory is found.
Scans backward through the file's tail for the end-of-central-directory record, validating each candidate signature against its comment length.
Returns {entry count, central directory size, central directory offset}, following the Zip64 records when the classic fields overflow. Multi-disk archives and malformed records return nil.
Walks central directory entries, collecting the OOXML part names that discriminate between document families. Reads and entry counts are bounded; the walk stops early once a family and its macro part are both seen.
Returns a more specific type than +base_type+ if the IO's ZIP central directory identifies one, or +base_type+ unchanged. Unseekable IOs, partial reads and malformed archives refine nothing: the base type stands.