6#ifndef PSTSDK_LTP_HEAP_H
7#define PSTSDK_LTP_HEAP_H
11#include <boost/noncopyable.hpp>
12#include <boost/iostreams/concepts.hpp>
15#pragma warning(disable:4244)
17#include <boost/iostreams/stream.hpp>
31#pragma warning(disable:4250)
40template<
typename K,
typename V>
41class bth_nonleaf_node;
43template<
typename K,
typename V>
46template<
typename K,
typename V>
63 std::streamsize
read(
char* pbuffer, std::streamsize n);
65 std::streampos
seek(boost::iostreams::stream_offset off, std::ios_base::seekdir way);
71 std::streamsize m_pos;
79typedef boost::iostreams::stream<hid_stream_device>
hid_stream;
90class heap_impl :
public std::enable_shared_from_this<heap_impl>
160 template<
typename K,
typename V>
172 : m_node(other.m_node) { }
210 : m_pheap(new
heap_impl(n, client_sig)) { }
220 : m_pheap(new
heap_impl(*(other.m_pheap))) { }
224 : m_pheap(other.m_pheap) { }
226#ifndef BOOST_NO_RVALUE_REFERENCES
230 : m_pheap(std::move(other.m_pheap)) { }
235 {
return m_pheap->size(
id); }
238 {
return m_pheap->get_root_id(); }
241 {
return m_pheap->get_client_signature(); }
244 {
return m_pheap->read(buffer,
id, offset); }
247 {
return m_pheap->read(
id); }
250 {
return m_pheap->open_stream(
id); }
254 {
return m_pheap->get_node(); }
257 {
return m_pheap->get_node(); }
260 template<
typename K,
typename V>
262 {
return m_pheap->open_bth<K,V>(root); }
290template<
typename K,
typename V>
293 private boost::noncopyable
317 :
m_heap(h), m_id(id), m_level(level) { }
360template<
typename K,
typename V>
371#ifndef BOOST_NO_RVALUE_REFERENCES
373 :
bth_node<K,V>(h, id, level), m_bth_info(std::move(bth_info)), m_child_nodes(m_bth_info.size()) { }
376 :
bth_node<K,V>(h, id, level), m_bth_info(bth_info), m_child_nodes(m_bth_info.size()) { }
379 const K&
get_key(
uint pos)
const {
return m_bth_info[pos].first; }
385 std::vector<std::pair<K, heap_id> > m_bth_info;
386 mutable std::vector<std::shared_ptr<bth_node<K,V> > > m_child_nodes;
394template<
typename K,
typename V>
404#ifndef BOOST_NO_RVALUE_REFERENCES
406 :
bth_node<K,V>(h, id, 0), m_bth_data(std::move(data)) { }
409 :
bth_node<K,V>(h, id, 0), m_bth_data(data) { }
416 {
return m_bth_data[pos].second; }
418 {
return m_bth_data[pos].first; }
420 {
return m_bth_data.size(); }
423 std::vector<std::pair<K,V> > m_bth_data;
428template<
typename K,
typename V>
435 h->read(buffer, bth_root, 0);
437#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
442 throw std::logic_error(
"invalid key size");
445 throw std::logic_error(
"invalid entry size");
451 return open_leaf(h, pheader->
root);
454template<
typename K,
typename V>
458 std::vector<byte> buffer(h->size(
id));
460 std::vector<std::pair<K, heap_id> > child_nodes;
462 h->read(buffer,
id, 0);
464 child_nodes.reserve(num_entries);
466 for(
uint i = 0; i < num_entries; ++i)
468 child_nodes.push_back(std::make_pair(pbth_nonleaf_node->
entries[i].key, pbth_nonleaf_node->
entries[i].page));
471#ifndef BOOST_NO_RVALUE_REFERENCES
478template<
typename K,
typename V>
481 std::vector<std::pair<K, V> > entries;
486 std::vector<byte>
buffer(
h->size(
id));
491 entries.reserve(num_entries);
493 for(
uint i = 0;
i < num_entries; ++
i)
497#ifndef BOOST_NO_RVALUE_REFERENCES
498 return std::shared_ptr<bth_leaf_node<K,V> >(
new bth_leaf_node<K,V>(
h,
id, std::move(entries)));
510template<
typename K,
typename V>
515 if(this->get_level() > 1)
521 return m_child_nodes[
pos].get();
524template<
typename K,
typename V>
529 if(this->get_level() > 1)
535 return m_child_nodes[
pos].get();
538inline pstsdk::heap_impl::heap_impl(
const node&
n)
544#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
550inline pstsdk::heap_impl::heap_impl(
const node& n, alias_tag)
551: m_node(n, alias_tag())
554 disk::heap_first_header first_header = m_node.read<disk::heap_first_header>(0);
556#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
558 throw sig_mismatch(
"invalid heap_sig", 0, n.get_id(), first_header.signature,
disk::heap_signature);
562inline pstsdk::heap_impl::heap_impl(
const node& n,
byte client_sig)
566 disk::heap_first_header first_header = m_node.read<disk::heap_first_header>(0);
568#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
570 throw sig_mismatch(
"invalid heap_sig", 0, n.get_id(), first_header.signature,
disk::heap_signature);
572 if(first_header.client_signature != client_sig)
573 throw sig_mismatch(
"invalid client_sig", 0, n.get_id(), first_header.client_signature, client_sig);
576inline pstsdk::heap_impl::heap_impl(
const node& n,
byte client_sig, alias_tag)
577: m_node(n, alias_tag())
580 disk::heap_first_header first_header = m_node.read<disk::heap_first_header>(0);
582#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
584 throw sig_mismatch(
"invalid heap_sig", 0, n.get_id(), first_header.signature,
disk::heap_signature);
586 if(first_header.client_signature != client_sig)
587 throw sig_mismatch(
"invalid client_sig", 0, n.get_id(), first_header.client_signature, client_sig);
609#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
611 throw std::length_error(
"page_map_offset > node size");
618#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
620 throw std::length_error(
"index > num_allocs");
630#ifdef PSTSDK_VALIDATION_LEVEL_WEAK
632 throw std::length_error(
"buffer.size() > size()");
635 throw std::length_error(
"offset > size()");
638 throw std::length_error(
"size + offset > size()");
659 if(m_hid && (
static_cast<size_t>(m_pos) +
n > m_pheap->size(m_hid)))
660 n = m_pheap->size(m_hid) - m_pos;
662 if(
n == 0 || m_hid == 0)
665 std::vector<byte>
buff(
static_cast<uint>(
n));
666 size_t read = m_pheap->read(
buff, m_hid,
static_cast<ulong>(m_pos));
677#if defined(_MSC_VER) && (_MSC_VER < 1600)
679#pragma warning(disable:4244)
681 if(
way == std::ios_base::beg)
683 else if(
way == std::ios_base::end)
684 m_pos = m_pheap->size(m_hid) +
off;
687#if defined(_MSC_VER) && (_MSC_VER < 1600)
693 else if(
static_cast<size_t>(m_pos) > m_pheap->size(m_hid))
694 m_pos = m_pheap->size(m_hid);
701 std::vector<byte>
result(size(
id));
706template<
typename K,
typename V>
Contains the actual key value pairs of the BTH.
const V & get_value(uint pos) const
Returns the value at the associated position on this leaf node.
uint num_values() const
Returns the number of entries in this btree_node.
const K & get_key(uint pos) const
Returns the key at the specified position.
bth_leaf_node(const heap_ptr &h, heap_id id, std::vector< std::pair< K, V > > data)
Construct a bth_leaf_node.
The object which forms the root of the BTH hierarchy.
node & get_node()
Get the node underlying this BTH.
static std::shared_ptr< bth_leaf_node< K, V > > open_leaf(const heap_ptr &h, heap_id id)
Open a leaf BTH node.
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.
size_t get_key_size() const
Return the key size of this bth.
bth_node(const heap_ptr &h, heap_id id, ushort level)
Construct a bth_node object.
static std::shared_ptr< bth_node< K, V > > open_root(const heap_ptr &h, heap_id bth_root)
Opens a BTH node from the specified heap at the given root.
heap_ptr get_heap_ptr()
Returns the heap this bth_node is in.
ushort get_level() const
Return the leve of this bth_node.
size_t get_value_size() const
Return the value size of this bth.
static std::shared_ptr< bth_nonleaf_node< K, V > > open_nonleaf(const heap_ptr &h, heap_id id, ushort level)
Open a non-leaf BTH node.
const node & get_node() const
Get the node underlying this BTH.
Contains references to other bth_node allocations.
const K & get_key(uint pos) const
Returns the key at the specified position.
bth_nonleaf_node(const heap_ptr &h, heap_id id, ushort level, std::vector< std::pair< K, heap_id > > bth_info)
Construct a bth_nonleaf_node.
uint num_values() const
Returns the number of entries in this btree_node.
bth_node< K, V > * get_child(uint pos)
Returns the child btree_node at the requested location.
Represents a leaf node in a BTree structure.
Represents a non-leaf node in a BTree structure.
std::shared_ptr< bth_node< K, V > > open_bth(heap_id root)
Opens a BTH from this heap with the given root id.
const node & get_node() const
Get the node underlying this heap.
byte get_client_signature() const
Returns the client signature of the heap.
uint get_page_count() const
Get the count of pages (..external blocks) in this heap.
hid_stream_device open_stream(heap_id id)
Creates a stream device over a specified heap allocation.
node & get_node()
Get the node underlying this heap.
size_t read(std::vector< byte > &buffer, heap_id id, ulong offset) const
Read data out of a specified allocation at the specified offset.
heap_id get_root_id() const
Returns the client root allocation out of this heap.
size_t size(heap_id id) const
Get the size of the given allocation.
Heap-on-Node implementation.
size_t read(std::vector< byte > &buffer, heap_id id, ulong offset) const
Read data out of a specified allocation at the specified offset.
heap(const node &n)
Open a heap object on a node.
heap_id get_root_id() const
Returns the client root allocation out of this heap.
byte get_client_signature() const
Returns the client signature of the heap.
hid_stream_device open_stream(heap_id id)
Creates a stream device over a specified heap allocation.
size_t size(heap_id id) const
Get the size of the given allocation.
node & get_node()
Get the node underlying this heap.
std::shared_ptr< bth_node< K, V > > open_bth(heap_id root)
Opens a BTH from this heap with the given root id.
heap(heap &&other)
Move constructor.
const node & get_node() const
Get the node underlying this heap.
heap(const node &n, byte client_sig, alias_tag)
Open a heap object on the specified node (alias), and validate the client sig.
heap(const node &n, alias_tag)
Open a heap object on a node alias.
heap(const heap &other, alias_tag)
Alias constructor.
std::vector< byte > read(heap_id id) const
Read an entire allocation.
heap(const node &n, byte client_sig)
Open a heap object on the specified node, and validate the client sig.
heap(const heap &other)
Copy constructor.
Defines a stream device for a heap allocation for use by boost iostream.
std::streampos seek(boost::iostreams::stream_offset off, std::ios_base::seekdir way)
Move the current position in the stream.
std::streamsize read(char *pbuffer, std::streamsize n)
Read data from this node into the buffer at the current position.
An in memory representation of the "node" concept in a PST data file.
uint get_page_count() const
Returns the number of pages in this node.
An unexpected signature was encountered.
Disk data structure definitions.
ulong get_heap_page(heap_id id)
Get the heap page from the heap id.
ulong get_heap_index(heap_id id)
Get the index from the heap id.
Contains the definition of all in memory representations of disk structures.
std::shared_ptr< heap_impl > heap_ptr
Node and Block definitions.
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...
EntryType entries[1]
Array of entries.
Entries which make up a "non-leaf" BTH allocation.
Provides a map of the allocations on a heap block.