Fairport  v1.0.38
fairport/pst/pstutil.h
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #ifndef FAIRPORT_PST_PSTUTIL_H
00009 #define FAIRPORT_PST_PSTUTIL_H
00010 
00011 #include <vector>
00012 
00013 #include "fairport/ndb/database_iface.h"
00014 #include "fairport/ndb/node.h"
00015 
00016 #include "fairport/ltp/propbag.h"
00017 #include "fairport/ltp/table.h"
00018 
00019 namespace fairport
00020 {
00021 
00024 
00030 std::vector<byte> calculate_entry_id(const shared_db_ptr& db, node_id nid);
00031 
00032 namespace detail
00033 {
00034 
00035 class itembase
00036 {
00037 public:
00040     explicit itembase(const node& n)
00041         : m_bag(n) { }
00042 
00045     node_id get_id() const
00046         { return m_bag.get_node().get_id(); }
00047 
00050     std::vector<byte> get_entry_id() const;
00051 
00052     // lower layer access
00055     property_bag& get_property_bag()
00056         { return m_bag; }
00058     const property_bag& get_property_bag() const
00059         { return m_bag; }
00060 
00063     shared_db_ptr get_db() const 
00064         { return m_bag.get_node().get_db(); }
00065 
00066 private:
00067     property_bag m_bag;
00068 };
00069 
00070 template<node_id Type>
00071 struct is_nid_type
00072 {
00073     bool operator()(const node_info& info)
00074         { return get_nid_type(info.id) == Type; }
00075     bool operator()(const const_table_row& row)
00076         { return get_nid_type(row.get_row_id()) == Type; }
00077 };
00078 
00079 struct is_item_type
00080 {
00081     is_item_type(std::wstring message_class) 
00082         : m_message_class(message_class) { }
00083 
00084     bool operator()(const const_property_object& po)
00085         { return m_message_class == po.read_prop<std::wstring>(0x1a); }
00086 
00087     std::wstring m_message_class;
00088 };
00089 
00090 template<typename T>
00091 class item_transform_row : public std::unary_function<const_table_row, T>
00092 {
00093 public:
00094     item_transform_row(const shared_db_ptr& db) 
00095         : m_db(db) { }
00096     T operator()(const const_table_row& row) const
00097         { return T(m_db->lookup_node(row.get_row_id())); }
00098 
00099 private:
00100     shared_db_ptr m_db;
00101 };
00102 
00103 template<typename T>
00104 class item_transform_info : public std::unary_function<node_info, T>
00105 {
00106 public:
00107     item_transform_info(const shared_db_ptr& db) 
00108         : m_db(db) { }
00109     T operator()(const node_info& info) const
00110         { return T(node(m_db, info)); }
00111 
00112 private:
00113     shared_db_ptr m_db;
00114 };
00115 } // end namespace detail
00116 } // end namespace fairport
00117 
00118 inline std::vector<fairport::byte> fairport::calculate_entry_id(const shared_db_ptr& db, node_id nid)
00119 {
00120     using namespace std;
00121 
00122     // This function doesn't know how to handle anything other than vanilla
00123     // PSTs.  OSTs, for example, require a more complex calculation.
00124     if (!db->is_pst())
00125         throw key_not_found<prop_id>(0x0fff);
00126 
00127     // A MAPI entry id contains 4 leading 0 bytes, the data store ID, and
00128     // the node ID (in little-endian byte order).
00129     vector<byte> entry_id(4, 0);
00130 
00131     node store(db->lookup_node(nid_message_store));
00132     property_bag store_props(store);
00133     vector<byte> store_id(store_props.read_prop<vector<byte> >(0x0ff9));
00134     copy(store_id.begin(), store_id.end(),
00135          insert_iterator<vector<byte> >(entry_id, entry_id.end()));
00136 
00137     for (size_t i = 0; i < sizeof(node_id); ++i)
00138         entry_id.push_back((nid >> 8*i) & 0xff);
00139 
00140     return entry_id;
00141 }
00142 
00143 inline std::vector<fairport::byte> fairport::detail::itembase::get_entry_id() const
00144 {
00145     if (m_bag.get_node().is_subnode())
00146     {
00147         // subitems should not have PidTagEntryId.
00148         throw key_not_found<prop_id>(0x0fff);
00149     }
00150     else
00151     {
00152         return calculate_entry_id(m_bag.get_node().get_db(), get_id());
00153     }
00154 }
00155 #endif