Fairport
v1.0.38
|
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