class Exchange::OfflineAddressBook::Parser
Attributes
header[R]
serialNumber[R]
totalRecords[R]
Public Class Methods
new(oab)
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 631 def initialize(oab) @oab = open(oab) @header = _header end
Public Instance Methods
_header()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 686 def _header # Read OAB_HDR version = _uint32 raise "Version not found, got #{version.inspect}" unless version == 0x20 # version @serialNumber = _uint32 @totalRecords = _uint32 # Read OAB_META_DATA metadataSize = _uint32 @headerProperties = _propertyTypes @oabProperties = _propertyTypes return _record(true) end
_integer()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 652 def _integer firstByte = _ubyte return firstByte if firstByte < 0x80 case firstByte when 0x81 then return _ubyte when 0x82 then return _ubyte + (_ubyte << 8) when 0x83 then return _ubyte + (_ubyte << 8) + (_ubyte << 16) when 0x84 then return _ubyte + (_ubyte << 8) + (_ubyte << 16) + (_ubyte << 24) end raise "Unexpected first byte #{sprintf('%x', firstByte)} of integer" end
_property(prop)
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 700 def _property(prop) if prop.array valueCount = _integer value = [] valueCount.times{ value << _scalar(prop.type) } else value = _scalar(prop.type) end p = OpenStruct.new(type: prop.type, id: prop.id, name: prop.name, value: value) return p end
_propertyTypes()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 666 def _propertyTypes n = _uint32 return 1.upto(n).collect{|i| prop = OpenStruct.new prop.pos = pos id = _uint32 prop._id = id.to_s(16) prop.id = sprintf('%04x', id >> 16).upcase prop.name = MapiPropertyName[prop.id] throw prop.id unless prop.name && prop.name != '' type = id & 0xffff prop.type = typeof(type & ~MapiPropertyDataType.Mv) prop._type = sprintf('%04x', (type & ~MapiPropertyDataType.Mv)) prop.array = ((type & MapiPropertyDataType.Mv) != 0) prop.flags = _uint32 prop } end
_record(headerRecord = false)
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 731 def _record(headerRecord = false) initialPosition = @oab.pos recordSize = 0 record = Record.new begin properties = headerRecord ? @headerProperties : @oabProperties recordSize = _uint32 recordPresence = @oab.read((properties.length + 7) / 8).unpack("b*").join.split('').collect{|bit| bit.to_i != 0 } properties.each_with_index{|prop, i| next unless recordPresence[i + 7 - 2 * (i % 8)] p = _property(prop) pn = p.name.to_s record[pn] ||= [] record[pn] << p.value } ensure @oab.pos = initialPosition + recordSize end return record end
_scalar(type)
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 714 def _scalar(type) case type.to_sym when :Long then return _integer when :Boolean then return (_ubyte > 0) when :Binary then return @oab.read(_integer) when :AnsiString, :UnicodeString string = '' while (byte = @oab.read(1)) != "\x00" string << byte end # TODO: string.force_encoding(MapiPropertyDataType.UnicodeString ? 'UTF-8' : 'ASCII') string.force_encoding(type == :UnicodeString ? 'UTF-8' : 'ASCII') return string end raise "Unknown scalar type #{type}" end
_ubyte()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 648 def _ubyte return @oab.read(1).unpack('C*')[0] end
_uint32()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 645 def _uint32 return @oab.read(4).unpack('V*')[0] end
pos()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 636 def pos return sprintf('%08o', @oab.pos) end
records()
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 752 def records @records = Enumerator.new(@totalRecords) do |y| @totalRecords.times { y.yield _record } end return @records end
typeof(type)
click to toggle source
# File lib/exchange-offline-address-book/parser.rb, line 639 def typeof(type) return MapiPropertyDataType[type.to_s.to_sym] end