Class: Omnizip::Formats::Ole::Header
- Inherits:
-
Object
- Object
- Omnizip::Formats::Ole::Header
- Includes:
- Constants
- Defined in:
- lib/omnizip/formats/ole/header.rb
Overview
OLE header parser
Parses the 512-byte header block from OLE compound documents. The first 76 bytes contain the header structure, followed by up to 109 BAT block indices.
Constant Summary collapse
- PACK =
Pack format for header structure
"a8 a16 v2 a2 v2 a6 V3 a4 V5"
Constants included from Constants
Constants::AVAIL, Constants::BAT, Constants::BYTE_ORDER_LE, Constants::DEFAULT_BIG_BLOCK_SHIFT, Constants::DEFAULT_SMALL_BLOCK_SHIFT, Constants::DEFAULT_THRESHOLD, Constants::DIRENT_COLORS, Constants::DIRENT_SIZE, Constants::DIRENT_TYPES, Constants::EOC, Constants::EOT, Constants::HEADER_BLOCK_SIZE, Constants::HEADER_SIZE, Constants::MAGIC, Constants::MAX_NAME_LENGTH, Constants::META_BAT
Instance Attribute Summary collapse
-
#b_shift ⇒ Integer
Big block shift (9 = 512 bytes).
-
#byte_order ⇒ String
2-byte byte order marker.
-
#clsid ⇒ String
16-byte CLSID (usually zeros).
-
#csectdir ⇒ Integer
Number of SECTs in directory (0 for v3).
-
#dirent_start ⇒ Integer
First block of directory entries.
-
#magic ⇒ String
8-byte OLE magic signature.
-
#major_ver ⇒ Integer
Major version (3 or 4).
-
#mbat_start ⇒ Integer
First block of Meta BAT.
-
#minor_ver ⇒ Integer
Minor version (usually 59).
-
#num_bat ⇒ Integer
Number of BAT blocks.
-
#num_mbat ⇒ Integer
Number of Meta BAT blocks.
-
#num_sbat ⇒ Integer
Number of SBAT blocks.
-
#reserved ⇒ String
6-byte reserved field.
-
#s_shift ⇒ Integer
Small block shift (6 = 64 bytes).
-
#sbat_start ⇒ Integer
First block of SBAT.
-
#threshold ⇒ Integer
Small block threshold (4096).
-
#transacting_signature ⇒ String
4-byte transaction signature.
Class Method Summary collapse
-
.create ⇒ Header
Create default header for new documents.
-
.parse(data) ⇒ Header
Parse header from binary data.
Instance Method Summary collapse
-
#apply_defaults ⇒ Object
Apply default values.
-
#big_block_size ⇒ Integer
Get big block size.
-
#initialize ⇒ Header
constructor
Initialize header.
-
#pack ⇒ String
Pack header to binary data.
-
#small_block_size ⇒ Integer
Get small block size.
-
#unpack(data) ⇒ Object
Unpack header from binary data.
-
#validate! ⇒ Object
Validate header structure.
Constructor Details
#initialize ⇒ Header
Initialize header
95 96 97 |
# File 'lib/omnizip/formats/ole/header.rb', line 95 def initialize apply_defaults end |
Instance Attribute Details
#b_shift ⇒ Integer
Returns Big block shift (9 = 512 bytes).
33 34 35 |
# File 'lib/omnizip/formats/ole/header.rb', line 33 def b_shift @b_shift end |
#byte_order ⇒ String
Returns 2-byte byte order marker.
30 31 32 |
# File 'lib/omnizip/formats/ole/header.rb', line 30 def byte_order @byte_order end |
#clsid ⇒ String
Returns 16-byte CLSID (usually zeros).
21 22 23 |
# File 'lib/omnizip/formats/ole/header.rb', line 21 def clsid @clsid end |
#csectdir ⇒ Integer
Returns Number of SECTs in directory (0 for v3).
42 43 44 |
# File 'lib/omnizip/formats/ole/header.rb', line 42 def csectdir @csectdir end |
#dirent_start ⇒ Integer
Returns First block of directory entries.
48 49 50 |
# File 'lib/omnizip/formats/ole/header.rb', line 48 def dirent_start @dirent_start end |
#magic ⇒ String
Returns 8-byte OLE magic signature.
18 19 20 |
# File 'lib/omnizip/formats/ole/header.rb', line 18 def magic @magic end |
#major_ver ⇒ Integer
Returns Major version (3 or 4).
27 28 29 |
# File 'lib/omnizip/formats/ole/header.rb', line 27 def major_ver @major_ver end |
#mbat_start ⇒ Integer
Returns First block of Meta BAT.
63 64 65 |
# File 'lib/omnizip/formats/ole/header.rb', line 63 def mbat_start @mbat_start end |
#minor_ver ⇒ Integer
Returns Minor version (usually 59).
24 25 26 |
# File 'lib/omnizip/formats/ole/header.rb', line 24 def minor_ver @minor_ver end |
#num_bat ⇒ Integer
Returns Number of BAT blocks.
45 46 47 |
# File 'lib/omnizip/formats/ole/header.rb', line 45 def num_bat @num_bat end |
#num_mbat ⇒ Integer
Returns Number of Meta BAT blocks.
66 67 68 |
# File 'lib/omnizip/formats/ole/header.rb', line 66 def num_mbat @num_mbat end |
#num_sbat ⇒ Integer
Returns Number of SBAT blocks.
60 61 62 |
# File 'lib/omnizip/formats/ole/header.rb', line 60 def num_sbat @num_sbat end |
#reserved ⇒ String
Returns 6-byte reserved field.
39 40 41 |
# File 'lib/omnizip/formats/ole/header.rb', line 39 def reserved @reserved end |
#s_shift ⇒ Integer
Returns Small block shift (6 = 64 bytes).
36 37 38 |
# File 'lib/omnizip/formats/ole/header.rb', line 36 def s_shift @s_shift end |
#sbat_start ⇒ Integer
Returns First block of SBAT.
57 58 59 |
# File 'lib/omnizip/formats/ole/header.rb', line 57 def sbat_start @sbat_start end |
#threshold ⇒ Integer
Returns Small block threshold (4096).
54 55 56 |
# File 'lib/omnizip/formats/ole/header.rb', line 54 def threshold @threshold end |
#transacting_signature ⇒ String
Returns 4-byte transaction signature.
51 52 53 |
# File 'lib/omnizip/formats/ole/header.rb', line 51 def transacting_signature @transacting_signature end |
Class Method Details
.create ⇒ Header
Create default header for new documents
88 89 90 91 92 |
# File 'lib/omnizip/formats/ole/header.rb', line 88 def self.create header = new header.apply_defaults header end |
.parse(data) ⇒ Header
Parse header from binary data
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/omnizip/formats/ole/header.rb', line 73 def self.parse(data) if data.nil? || data.bytesize < HEADER_SIZE raise ArgumentError, "Header data too short" end header = new header.unpack(data) header.validate! header end |
Instance Method Details
#apply_defaults ⇒ Object
Apply default values
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/omnizip/formats/ole/header.rb', line 100 def apply_defaults @magic = MAGIC.dup @clsid = "\x00".b * 16 @minor_ver = 59 @major_ver = 3 @byte_order = BYTE_ORDER_LE.dup @b_shift = DEFAULT_BIG_BLOCK_SHIFT @s_shift = DEFAULT_SMALL_BLOCK_SHIFT @reserved = "\x00".b * 6 @csectdir = 0 @num_bat = 1 @dirent_start = EOC @transacting_signature = "\x00".b * 4 @threshold = DEFAULT_THRESHOLD @sbat_start = EOC @num_sbat = 0 @mbat_start = EOC @num_mbat = 0 end |
#big_block_size ⇒ Integer
Get big block size
123 124 125 |
# File 'lib/omnizip/formats/ole/header.rb', line 123 def big_block_size 1 << @b_shift end |
#pack ⇒ String
Pack header to binary data
161 162 163 164 165 166 167 168 |
# File 'lib/omnizip/formats/ole/header.rb', line 161 def pack [ @magic, @clsid, @minor_ver, @major_ver, @byte_order, @b_shift, @s_shift, @reserved, @csectdir, @num_bat, @dirent_start, @transacting_signature, @threshold, @sbat_start, @num_sbat, @mbat_start, @num_mbat ].pack(PACK) end |
#small_block_size ⇒ Integer
Get small block size
130 131 132 |
# File 'lib/omnizip/formats/ole/header.rb', line 130 def small_block_size 1 << @s_shift end |
#unpack(data) ⇒ Object
Unpack header from binary data
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/omnizip/formats/ole/header.rb', line 137 def unpack(data) values = data[0, HEADER_SIZE].unpack(PACK) @magic = values[0] @clsid = values[1] @minor_ver = values[2] @major_ver = values[3] @byte_order = values[4] @b_shift = values[5] @s_shift = values[6] @reserved = values[7] @csectdir = values[8] @num_bat = values[9] @dirent_start = values[10] @transacting_signature = values[11] @threshold = values[12] @sbat_start = values[13] @num_sbat = values[14] @mbat_start = values[15] @num_mbat = values[16] end |
#validate! ⇒ Object
Validate header structure
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/omnizip/formats/ole/header.rb', line 173 def validate! unless @magic == MAGIC raise ArgumentError, "Invalid OLE magic signature" end if @num_bat.zero? raise ArgumentError, "Invalid OLE: no BAT blocks" end if @s_shift > @b_shift || @b_shift <= 6 || @b_shift >= 31 raise ArgumentError, "Invalid block shift values" end unless @byte_order == BYTE_ORDER_LE raise ArgumentError, "Only little-endian OLE files are supported" end if @threshold != DEFAULT_THRESHOLD # Warning, not error end true end |