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.
106 107 108 109 110 111 112 |
# File 'lib/ole/types/property_set.rb', line 106 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
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ole/types/property_set.rb', line 137 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.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def guid @guid end |
#io ⇒ Object (readonly)
Returns the value of attribute io.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def io @io end |
#os ⇒ Object (readonly)
Returns the value of attribute os.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def os @os end |
#sections ⇒ Object (readonly)
Returns the value of attribute sections.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def sections @sections end |
#signature ⇒ Object (readonly)
Returns the value of attribute signature.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def signature @signature end |
#unknown ⇒ Object (readonly)
Returns the value of attribute unknown.
104 105 106 |
# File 'lib/ole/types/property_set.rb', line 104 def unknown @unknown end |
Instance Method Details
#[](key) ⇒ Object
125 126 127 128 129 |
# File 'lib/ole/types/property_set.rb', line 125 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
131 132 133 134 135 |
# File 'lib/ole/types/property_set.rb', line 131 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
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/ole/types/property_set.rb', line 149 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
114 115 116 117 118 119 |
# File 'lib/ole/types/property_set.rb', line 114 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
121 122 123 |
# File 'lib/ole/types/property_set.rb', line 121 def load_section_list str @sections = str.to_enum(:each_chunk, Section::SIZE).map { |s| Section.new s, self } end |
#to_h ⇒ Object
160 161 162 |
# File 'lib/ole/types/property_set.rb', line 160 def to_h inject({}) { |hash, (name, value)| hash.update name.to_sym => value } end |