6#ifndef PSTSDK_LTP_TABLE_H
7#define PSTSDK_LTP_TABLE_H
11#include <unordered_map>
12#include <boost/iterator/iterator_facade.hpp>
56 : m_position(
other.m_position), m_table(
other.m_table) { }
76 byte get_value_1(
prop_id id)
const;
80 std::vector<byte> get_value_variable(
prop_id id)
const;
93class const_table_row_iter :
public boost::iterator_facade<const_table_row_iter, const_table_row, boost::random_access_traversal_tag, const_table_row>
104 : m_position(
pos), m_table(
table) { }
109 void increment() { ++m_position; }
111 {
return ((m_position ==
other.m_position) && (m_table ==
other.m_table)); }
112 const_table_row dereference()
const
113 {
return const_table_row(m_position, m_table); }
114 void decrement() { --m_position; }
115 void advance(
int off) { m_position += off; }
117 {
return (other.m_position - m_position); }
137class table_impl :
public std::enable_shared_from_this<table_impl>
207 virtual size_t size()
const = 0;
240 {
return m_prows->get_node(); }
242 {
return m_prows->get_node(); }
260 std::shared_ptr<bth_node<row_id, T> > m_prows;
263 std::vector<byte> m_vec_rowarray;
264 std::shared_ptr<node> m_pnode_rowarray;
266 std::unordered_map<prop_id, disk::column_description> m_columns;
267 typedef std::unordered_map<prop_id, disk::column_description>::iterator column_iter;
268 typedef std::unordered_map<prop_id, disk::column_description>::const_iterator const_column_iter;
281 ulong rows_per_page()
const {
return (m_pnode_rowarray ? m_pnode_rowarray->get_page_size(0) / cb_per_row() : m_vec_rowarray.
size() / cb_per_row()); }
286 template<
typename Val> Val read_raw_row(
ulong row,
ushort offset)
const;
289 std::vector<byte> read_exists_bitmap(
ulong row)
const;
322 : m_ptable(
other.m_ptable) { }
326 {
return (*m_ptable)[
row]; }
329 {
return m_ptable->begin(); }
332 {
return m_ptable->end(); }
336 {
return m_ptable->get_node(); }
339 {
return m_ptable->get_node(); }
342 {
return m_ptable->get_cell_value(
row,
id); }
345 {
return m_ptable->read_cell(
row,
id); }
348 {
return m_ptable->open_cell_stream(
row,
id); }
351 {
return m_ptable->get_prop_list(); }
354 {
return m_ptable->get_prop_type(
id); }
357 {
return m_ptable->get_row_id(
row); }
360 {
return m_ptable->lookup_row(
id); }
363 {
return m_ptable->size(); }
416 std::vector<prop_id> columns = m_table->get_prop_list();
417 std::vector<prop_id>
props;
419 for(
size_t i = 0;
i < columns.size(); ++
i)
422 props.push_back(columns[
i]);
430 return m_table->row_prop_size(m_position,
id);
435 return m_table->get_prop_type(
id);
440 return m_table->prop_exists(m_position,
id);
445 return m_table->get_row_id(m_position);
450 return (
byte)m_table->get_cell_value(m_position,
id);
455 return (
ushort)m_table->get_cell_value(m_position,
id);
460 return (
ulong)m_table->get_cell_value(m_position,
id);
465 return m_table->get_cell_value(m_position,
id);
468inline std::vector<pstsdk::byte> pstsdk::const_table_row::get_value_variable(
prop_id id)
const
470 return m_table->read_cell(m_position,
id);
475 return (std::const_pointer_cast<table_impl>(m_table))->open_cell_stream(m_position,
id);
486#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
514 std::vector<byte> table_info = h.read(h.get_root_id());
515 disk::tc_header* pheader = (disk::tc_header*)&table_info[0];
517#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
519 throw sig_mismatch(
"heap_sig_tc expected", 0, n.get_id(), pheader->signature,
disk::heap_sig_tc);
522 m_prows = h.open_bth<
row_id, T>(pheader->row_btree_id);
524 for(
int i = 0; i < pheader->num_columns; ++i)
525 m_columns[pheader->columns[i].id] = pheader->columns[i];
528 m_offsets[i] = pheader->size_offsets[i];
532 m_pnode_rowarray.reset(
new node(n.lookup(pheader->row_matrix_id)));
534 else if(pheader->row_matrix_id)
536 m_vec_rowarray = h.read(pheader->row_matrix_id);
545 return (m_pnode_rowarray->get_page_count()-1) * rows_per_page() + m_pnode_rowarray->get_page_size(m_pnode_rowarray->get_page_count()-1) / cb_per_row();
549 return m_vec_rowarray.size() / cb_per_row();
556 std::vector<prop_id>
props;
558 for(const_column_iter
i = m_columns.
begin();
i != m_columns.
end(); ++
i)
580 if(!prop_exists(
row,
id))
583 const_column_iter
column = m_columns.find(
id);
586 switch(
column->second.size)
626 node sub(get_node().lookup(
hid));
643 return get_node().
lookup(
hid).open_as_stream();
651 const_column_iter
iter = m_columns.find(
id);
666template<
typename Val>
670 throw std::out_of_range(
"row >= size()");
682 memcpy(&val, &m_vec_rowarray[ row * cb_per_row() + offset ],
sizeof(Val));
690 std::vector<byte> exists_bitmap(cb_per_row() - exists_bitmap_start());
693 throw std::out_of_range(
"row >= size()");
697 ulong page_num = row / rows_per_page();
698 ulong page_offset = (row % rows_per_page()) * cb_per_row();
700 m_pnode_rowarray->read(exists_bitmap, page_num, page_offset + exists_bitmap_start());
704 memcpy(&exists_bitmap[0], &m_vec_rowarray[ row * cb_per_row() + exists_bitmap_start() ], exists_bitmap.size());
707 return exists_bitmap;
713 const_column_iter
column = m_columns.find(
id);
Implementation of an ANSI TC (64k rows) and a unicode TC.
hnid_stream_device open_cell_stream(ulong row, prop_id id)
Open a stream over a property in a given row.
std::vector< byte > read_cell(ulong row, prop_id id) const
Get the contents of a indirect property in the specified row.
std::vector< prop_id > get_prop_list() const
Get all of the properties on this table.
friend table_ptr open_table(const node &n, alias_tag)
Open the specified node as a table.
prop_type get_prop_type(prop_id id) const
Get the type of a property.
size_t row_prop_size(ulong row, prop_id id) const
Return the size of a property for a given row.
friend table_ptr open_table(const node &n)
Open the specified node as a table.
size_t size() const
Get the number of rows in this table.
const node & get_node() const
Get the node backing this table.
ulonglong get_cell_value(ulong row, prop_id id) const
Get the contents of the specified cell in the specified row.
bool prop_exists(ulong row, prop_id id) const
Check to see if a property exists for a given row.
node & get_node()
Get the node backing this table.
row_id get_row_id(ulong row) const
Get the row id of a specified row.
ulong lookup_row(row_id id) const
Find the offset into the table of the given row_id.
const heap_ptr get_heap_ptr() const
Returns the heap this bth_node is in.
heap_id get_id() const
Return the heap_id of this bth_node.
const node & get_node() const
Get the node underlying this BTH.
Contains references to other bth_node allocations.
const V & lookup(const K &key) const
Looks up the associated value for a given key.
void first(btree_iter_impl< K, V > &iter) const
Positions the iterator at the first element on this tree.
const_iterator end() const
Returns a STL style iterator positioned at the "end" entry.
const_iterator begin() const
Returns a STL style iterator positioned at the first entry.
Property object base class.
The iterator type exposed by the table for row iteration.
const_table_row_iter(ulong pos, const const_table_ptr &table)
Construct an iterator from a position and table.
const_table_row_iter()
Default constructor.
friend class boost::iterator_core_access
An abstraction of a table row.
bool prop_exists(prop_id id) const
Indicates the existance of a given property on this object.
prop_type get_prop_type(prop_id id) const
Get the property type of a given prop_id.
std::vector< prop_id > get_prop_list() const
Get a list of all properties on this object.
size_t size(prop_id id) const
Returns the total size of a variable length property.
const_table_row(ulong position, const const_table_ptr &table)
Construct a const_table_row object from a table and row offset.
row_id get_row_id() const
Get the row_id of this row.
hnid_stream_device open_prop_stream(prop_id id)
Creates a stream device over a property on this object.
const_table_row(const const_table_row &other)
Copy construct this row.
Heap-on-Node implementation.
Defines a stream device which can wrap one of the two prop sources.
An in memory representation of the "node" concept in a PST data file.
size_t read(std::vector< byte > &buffer, ulong offset) const
Read data from this node.
size_t size() const
Returns the size of this node.
This function or method has not been implemented.
An unexpected signature was encountered.
virtual row_id get_row_id(ulong row) const =0
Get the row id of a specified row.
virtual size_t size() const =0
Get the number of rows in this table.
virtual prop_type get_prop_type(prop_id id) const =0
Get the type of a property.
virtual ulong lookup_row(row_id id) const =0
Find the offset into the table of the given row_id.
const_table_row_iter end() const
Get an end iterator for this table.
virtual node & get_node()=0
Get the node backing this table.
virtual std::vector< prop_id > get_prop_list() const =0
Get all of the properties on this table.
virtual const node & get_node() const =0
Get the node backing this table.
const_table_row operator[](ulong row) const
Get the requested table row.
virtual hnid_stream_device open_cell_stream(ulong row, prop_id id)=0
Open a stream over a property in a given row.
virtual std::vector< byte > read_cell(ulong row, prop_id id) const =0
Get the contents of a indirect property in the specified row.
virtual bool prop_exists(ulong row, prop_id id) const =0
Check to see if a property exists for a given row.
const_table_row_iter begin() const
Get an iterator pointing to the first row.
virtual size_t row_prop_size(ulong row, prop_id id) const =0
Return the size of a property for a given row.
virtual ulonglong get_cell_value(ulong row, prop_id id) const =0
Get the contents of the specified cell in the specified row.
The actual table object that clients reference.
std::vector< prop_id > get_prop_list() const
Get all of the properties on this table.
row_id get_row_id(ulong row) const
Get the row id of a specified row.
prop_type get_prop_type(prop_id id) const
Get the type of a property.
hnid_stream_device open_cell_stream(ulong row, prop_id id)
Open a stream over a property in a given row.
ulonglong get_cell_value(ulong row, prop_id id) const
Get the contents of the specified cell in the specified row.
size_t size() const
Get the number of rows in this table.
const_table_row_iter end() const
Get an end iterator for this table.
node & get_node()
Get the node backing this table.
table(const node &n, alias_tag)
Construct a table from this node.
ulong lookup_row(row_id id) const
Find the offset into the table of the given row_id.
std::vector< byte > read_cell(ulong row, prop_id id) const
Get the contents of a indirect property in the specified row.
table(const node &n)
Construct a table from this node.
const_table_row operator[](ulong row) const
Get the requested table row.
table(const table &other, alias_tag)
Alias constructor.
const_table_row_iter begin() const
Get an iterator pointing to the first row.
const node & get_node() const
Get the node backing this table.
boost::uint64_t ulonglong
bool is_subnode_id(heapnode_id id)
Inspects a heapnode_id (also known as a HNID) to determine if it is a node_id (NID)
prop_type
The different property types as defined by MAPI.
@ nid_all_message_search_contents
bool test_bit(const byte *pbytes, ulong bit)
Test to see if the specified bit in the buffer is set.
Heap-on-Node (HN) and BTree-on-Heap (BTH) implementation.
Contains the definition of all in memory representations of disk structures.
basic_table< ushort > small_table
basic_table< ulong > large_table
std::shared_ptr< const table_impl > const_table_ptr
std::shared_ptr< table_impl > table_ptr
Node and Block definitions.
Property access base class.
Primitive structures defined by MS-PST and MAPI.
Tag structure used to indicate a copy constructed class should be an alias (shallow copy) rather than...