Class: OfflineAddressBook::Parser
- Inherits:
-
Object
- Object
- OfflineAddressBook::Parser
- Defined in:
- lib/exchange-offline-address-book/parser.rb
Instance Attribute Summary collapse
-
#header ⇒ Object
readonly
Returns the value of attribute header.
-
#serialNumber ⇒ Object
readonly
Returns the value of attribute serialNumber.
-
#totalRecords ⇒ Object
readonly
Returns the value of attribute totalRecords.
Instance Method Summary collapse
- #_header ⇒ Object
- #_integer ⇒ Object
- #_property(prop) ⇒ Object
- #_propertyTypes ⇒ Object
- #_record(headerRecord = false) ⇒ Object
- #_scalar(type) ⇒ Object
- #_ubyte ⇒ Object
- #_uint32 ⇒ Object
-
#initialize(oab) ⇒ Parser
constructor
A new instance of Parser.
- #pos ⇒ Object
- #records ⇒ Object
- #typeof(type) ⇒ Object
Constructor Details
#initialize(oab) ⇒ Parser
Returns a new instance of Parser.
618 619 620 621 |
# File 'lib/exchange-offline-address-book/parser.rb', line 618 def initialize(oab) @oab = open(oab) @header = _header end |
Instance Attribute Details
#header ⇒ Object (readonly)
Returns the value of attribute header.
630 631 632 |
# File 'lib/exchange-offline-address-book/parser.rb', line 630 def header @header end |
#serialNumber ⇒ Object (readonly)
Returns the value of attribute serialNumber.
630 631 632 |
# File 'lib/exchange-offline-address-book/parser.rb', line 630 def serialNumber @serialNumber end |
#totalRecords ⇒ Object (readonly)
Returns the value of attribute totalRecords.
630 631 632 |
# File 'lib/exchange-offline-address-book/parser.rb', line 630 def totalRecords @totalRecords end |
Instance Method Details
#_header ⇒ Object
673 674 675 676 677 678 679 680 681 682 683 684 685 |
# File 'lib/exchange-offline-address-book/parser.rb', line 673 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 = _uint32 @headerProperties = _propertyTypes @oabProperties = _propertyTypes return _record(true) end |
#_integer ⇒ Object
639 640 641 642 643 644 645 646 647 648 649 650 651 |
# File 'lib/exchange-offline-address-book/parser.rb', line 639 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) ⇒ Object
687 688 689 690 691 692 693 694 695 696 697 698 699 |
# File 'lib/exchange-offline-address-book/parser.rb', line 687 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 ⇒ Object
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
# File 'lib/exchange-offline-address-book/parser.rb', line 653 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) ⇒ Object
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 |
# File 'lib/exchange-offline-address-book/parser.rb', line 718 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) ⇒ Object
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
# File 'lib/exchange-offline-address-book/parser.rb', line 701 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 ⇒ Object
635 636 637 |
# File 'lib/exchange-offline-address-book/parser.rb', line 635 def _ubyte return @oab.read(1).unpack('C*')[0] end |
#_uint32 ⇒ Object
632 633 634 |
# File 'lib/exchange-offline-address-book/parser.rb', line 632 def _uint32 return @oab.read(4).unpack('V*')[0] end |
#pos ⇒ Object
623 624 625 |
# File 'lib/exchange-offline-address-book/parser.rb', line 623 def pos return sprintf('%08o', @oab.pos) end |
#records ⇒ Object
739 740 741 742 743 744 |
# File 'lib/exchange-offline-address-book/parser.rb', line 739 def records @records = Enumerator.new(@totalRecords) do |y| @totalRecords.times { y.yield _record } end return @records end |
#typeof(type) ⇒ Object
626 627 628 |
# File 'lib/exchange-offline-address-book/parser.rb', line 626 def typeof(type) return MapiPropertyDataType[type.to_s.to_sym] end |