Class: Mapi::Pst::RawPropertyStoreTable
- Inherits:
-
BlockParser
- Object
- BlockParser
- Mapi::Pst::RawPropertyStoreTable
- Includes:
- Enumerable
- Defined in:
- lib/mapi/pst.rb
Overview
RawPropertyStoreTable is kind of like a database table. it has a fixed set of columns. #[] is kind of like getting a row from the table. those rows are currently encapsulated by Row, which has #each like RawPropertyStore. only used for the recipients array, and the attachments array. completely lazy, doesn’t load any of the properties upon creation.
Defined Under Namespace
Constant Summary
Constants inherited from BlockParser
BlockParser::ID2_ATTACHMENTS, BlockParser::ID2_RECIPIENTS, BlockParser::IMMEDIATE_TYPES, BlockParser::INDIRECT_TYPES, BlockParser::PR_BODY_HTML, BlockParser::PR_SUBJECT, BlockParser::TYPES, BlockParser::USE_MAIN_DATA
Instance Attribute Summary collapse
-
#data2 ⇒ String
readonly
2.3.2 BTree-on-Heap (BTH).
-
#index_data ⇒ String
readonly
Array of TCOLDESC.
-
#length ⇒ Integer
readonly
Record count.
-
#rec_size ⇒ Integer
readonly
TCI_bm.
-
#rows_pages ⇒ Array<String>
readonly
2.3.4.4 Row Matrix.
- #rows_per_page ⇒ Integer readonly
Attributes inherited from BlockParser
Instance Method Summary collapse
-
#[](idx) ⇒ Row
return grid row.
- #each {|row| ... } ⇒ Object
-
#get_record(record_index) ⇒ String
get record data.
-
#initialize(node, local_node_id) ⇒ RawPropertyStoreTable
constructor
A new instance of RawPropertyStoreTable.
-
#schema ⇒ Array<Column>
for debug.
Methods inherited from BlockParser
#get_data_array, #get_data_indirect, #get_data_indirect_io, #handle_indirect_values, #load_page_header, #load_root_header
Constructor Details
#initialize(node, local_node_id) ⇒ RawPropertyStoreTable
Returns a new instance of RawPropertyStoreTable.
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 |
# File 'lib/mapi/pst.rb', line 1394 def initialize node, local_node_id super bTypeTC = 0x7c raise FormatError, "expected type 124 - got #{@heap_type}" unless @heap_type == bTypeTC header_data = get_data_indirect @offset1 # seven_c_blk # often: u1 == u2 and u3 == u2 + 2, then rec_size == u3 + 4. wtf # TCINFO seven_c, @num_list, u1, u2, u3, @rec_size, b_five_offset, rows_offset, u7, u8 = header_data[0, 22].unpack('CCv4V2v2') @index_data = header_data[22..-1] raise FormatError if @num_list != schema.length or seven_c != 0x7c # another check min_size = schema.inject(0) { |total, col| total + col.size } # seem to have at max, 8 padding bytes on the end of the record. not sure if it means # anything. maybe its just space that hasn't been reclaimed due to columns being # removed or something. probably should just check lower bound. range = (min_size..min_size + 8) warn "rec_size seems wrong (#{range} !=== #{rec_size})" unless range === rec_size header_data2 = get_data_indirect b_five_offset raise FormatError if header_data2.length < 8 signature, offset2 = header_data2.unpack 'V2' # ??? seems a bit iffy # there's probably more to the differences than this, and the data2 difference below expect = node.pst.header.version_2003? ? 0x000404b5 : 0x000204b5 raise FormatError, 'unhandled block signature 0x%08x' % signature if signature != expect # this holds all the row data # handle multiple block issue. if rows_offset != 0 #if RangesIOIdxChain === @rows_io # @data3_idxs = # # modify ranges # ranges = @rows_io.ranges.map { |offset, size| [offset, size / @rec_size * @rec_size] } # @rows_io.instance_variable_set :@ranges, ranges #end @rows_pages = get_data_array(rows_offset) else # table rows are empty, no data to be read @rows_pages = [""] end # there must be something to the data in data2. i think data2 is the array of objects essentially. # currently its only used to imply a length # actually, at size 6, its just some auxiliary data. i'm thinking either Vv/vV, for 97, and something # wider for 03. the second value is just the index (0...length), and the first value is # some kind of offset i expect. actually, they were all id2 values, in another case. # so maybe they're get_data_indirect values too? # actually, it turned out they were identical to the PR_ATTACHMENT_ID2 values... # id2_values = ie, data2.unpack('v*').to_enum(:each_slice, 3).transpose[0] # table[i].assoc(PR_ATTACHMENT_ID2).last == id2_values[i], for all i. @data2 = get_data_indirect(offset2) rescue nil #if data2 # @length = (data2.length / 6.0).ceil #else # the above / 6, may have been ok for 97 files, but the new 0x0004 style block must have # different size records... just use this instead: # hmmm, actually, we can still figure it out: @rows_per_page = @rows_pages.first.length / @rec_size @length = @rows_pages.map { |data| data.length / @rec_size }.sum #end # lets try and at least use data2 for a warning for now #if data2 # data2_rec_size = node.pst.header.version_2003? ? 8 : 6 # warn 'somthing seems wrong with data3' unless @length == (data2.length / data2_rec_size) #end end |
Instance Attribute Details
#data2 ⇒ String (readonly)
Returns 2.3.2 BTree-on-Heap (BTH).
1384 1385 1386 |
# File 'lib/mapi/pst.rb', line 1384 def data2 @data2 end |
#index_data ⇒ String (readonly)
Returns Array of TCOLDESC.
1382 1383 1384 |
# File 'lib/mapi/pst.rb', line 1382 def index_data @index_data end |
#length ⇒ Integer (readonly)
Returns record count.
1380 1381 1382 |
# File 'lib/mapi/pst.rb', line 1380 def length @length end |
#rec_size ⇒ Integer (readonly)
Returns TCI_bm.
1388 1389 1390 |
# File 'lib/mapi/pst.rb', line 1388 def rec_size @rec_size end |
#rows_pages ⇒ Array<String> (readonly)
Returns 2.3.4.4 Row Matrix.
1386 1387 1388 |
# File 'lib/mapi/pst.rb', line 1386 def rows_pages @rows_pages end |
#rows_per_page ⇒ Integer (readonly)
1390 1391 1392 |
# File 'lib/mapi/pst.rb', line 1390 def rows_per_page @rows_per_page end |
Instance Method Details
#[](idx) ⇒ Row
return grid row
1480 1481 1482 1483 |
# File 'lib/mapi/pst.rb', line 1480 def [] idx # handle funky rounding Row.new self, idx end |
#each {|row| ... } ⇒ Object
1487 1488 1489 |
# File 'lib/mapi/pst.rb', line 1487 def each length.times { |i| yield self[i] } end |
#get_record(record_index) ⇒ String
get record data
1496 1497 1498 1499 1500 |
# File 'lib/mapi/pst.rb', line 1496 def get_record record_index page_index = record_index / @rows_per_page heap_index = record_index % @rows_per_page (@rows_pages[page_index])[@rec_size * heap_index, @rec_size] end |