Class: Ole::Types::PropertySet
- Inherits:
-
Object
- Object
- Ole::Types::PropertySet
- Includes:
- Enumerable, Constants
- Defined in:
- lib/ole/types/property_set.rb
Overview
The PropertySet class currently supports readonly access to the properties serialized in “property set” streams, such as the file “005SummaryInformation”, in OLE files.
Think it has its roots in MFC property set serialization.
See poi.apache.org/hpsf/internals.html for details
Defined Under Namespace
Modules: Constants Classes: Section
Constant Summary collapse
- HEADER_SIZE =
28
- HEADER_PACK =
"vvVa#{Clsid::SIZE}V"
- OS_MAP =
{ 0 => :win16, 1 => :mac, 2 => :win32, 0x20001 => :ooffice, # open office on linux... }
- DATA =
define a smattering of the property set guids.
YAML.load_file(File.dirname(__FILE__) + '/../../../data/propids.yaml'). inject({}) { |hash, (key, value)| hash.update Clsid.parse(key) => value }
- PROPERTY_MAP =
create an inverted map of names to guid/key pairs
DATA.inject({}) do |h1, (guid, data)| data[1].inject(h1) { |h2, (id, name)| h2.update name => [guid, id] } end
Instance Attribute Summary collapse
-
#guid ⇒ Object
readonly
Returns the value of attribute guid.
-
#io ⇒ Object
readonly
Returns the value of attribute io.
-
#os ⇒ Object
readonly
Returns the value of attribute os.
-
#sections ⇒ Object
readonly
Returns the value of attribute sections.
-
#signature ⇒ Object
readonly
Returns the value of attribute signature.
-
#unknown ⇒ Object
readonly
Returns the value of attribute unknown.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
- #each ⇒ Object
-
#initialize(io) ⇒ PropertySet
constructor
A new instance of PropertySet.
- #load_header(str) ⇒ Object
- #load_section_list(str) ⇒ Object
- #method_missing(name, *args, &block) ⇒ Object
- #to_h ⇒ Object
Methods included from Enumerable
Constructor Details
#initialize(io) ⇒ PropertySet
Returns a new instance of PropertySet.
107 108 109 110 111 112 113 |
# File 'lib/ole/types/property_set.rb', line 107 def initialize io @io = io load_header io.read(HEADER_SIZE) load_section_list io.read(@num_sections * Section::SIZE) # expect no gap between last section and start of data. #Log.warn "gap between section list and property data" unless io.pos == @sections.map(&:offset).min end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ole/types/property_set.rb', line 138 def method_missing name, *args, &block if name.to_s =~ /(.*)=$/ return super unless args.length == 1 return super unless PROPERTY_MAP[$1] self[$1] = args.first else return super unless args.length == 0 return super unless PROPERTY_MAP[name.to_s] self[name] end end |
Instance Attribute Details
#guid ⇒ Object (readonly)
Returns the value of attribute guid.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def guid @guid end |
#io ⇒ Object (readonly)
Returns the value of attribute io.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def io @io end |
#os ⇒ Object (readonly)
Returns the value of attribute os.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def os @os end |
#sections ⇒ Object (readonly)
Returns the value of attribute sections.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def sections @sections end |
#signature ⇒ Object (readonly)
Returns the value of attribute signature.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def signature @signature end |
#unknown ⇒ Object (readonly)
Returns the value of attribute unknown.
105 106 107 |
# File 'lib/ole/types/property_set.rb', line 105 def unknown @unknown end |
Instance Method Details
#[](key) ⇒ Object
126 127 128 129 130 |
# File 'lib/ole/types/property_set.rb', line 126 def [] key pair = PROPERTY_MAP[key.to_s] or return nil section = @sections.find { |s| s.guid == pair.first } or return nil section[pair.last] end |
#[]=(key, value) ⇒ Object
132 133 134 135 136 |
# File 'lib/ole/types/property_set.rb', line 132 def []= key, value pair = PROPERTY_MAP[key.to_s] or return nil section = @sections.find { |s| s.guid == pair.first } or return nil section[pair.last] = value end |
#each ⇒ Object
150 151 152 153 154 155 156 157 158 159 |
# File 'lib/ole/types/property_set.rb', line 150 def each @sections.each do |section| next unless pair = DATA[section.guid] map = pair.last section.each do |id, value| name = map[id] or next yield name, value end end end |
#load_header(str) ⇒ Object
115 116 117 118 119 120 |
# File 'lib/ole/types/property_set.rb', line 115 def load_header str @signature, @unknown, @os_id, @guid, @num_sections = str.unpack HEADER_PACK # should i check that unknown == 0? it usually is. so is the guid actually @guid = Clsid.load @guid @os = OS_MAP[@os_id] || Log.warn("unknown operating system id #{@os_id}") end |
#load_section_list(str) ⇒ Object
122 123 124 |
# File 'lib/ole/types/property_set.rb', line 122 def load_section_list str @sections = str.to_enum(:each_chunk, Section::SIZE).map { |s| Section.new s, self } end |
#to_h ⇒ Object
161 162 163 |
# File 'lib/ole/types/property_set.rb', line 161 def to_h inject({}) { |hash, (name, value)| hash.update name.to_sym => value } end |