Fairport
v1.0.38
|
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 #ifndef FAIRPORT_PST_PST_H 00014 #define FAIRPORT_PST_PST_H 00015 00016 #include <boost/noncopyable.hpp> 00017 #include <boost/iterator/filter_iterator.hpp> 00018 #include <boost/iterator/transform_iterator.hpp> 00019 00020 #include "fairport/ndb/database.h" 00021 #include "fairport/ndb/database_iface.h" 00022 #include "fairport/ndb/node.h" 00023 00024 #include "fairport/ltp/propbag.h" 00025 #include "fairport/ltp/nameid.h" 00026 00027 #include "fairport/pst/folder.h" 00028 #include "fairport/pst/message.h" 00029 #include "fairport/pst/pstutil.h" 00030 00031 namespace fairport 00032 { 00033 00036 00048 class pst : private boost::noncopyable 00049 { 00050 typedef boost::filter_iterator<detail::is_nid_type<nid_type_folder>, const_nodeinfo_iterator> folder_filter_iterator; 00051 typedef boost::filter_iterator<detail::is_nid_type<nid_type_message>, const_nodeinfo_iterator> message_filter_iterator; 00052 00053 public: 00055 typedef boost::transform_iterator<message_transform_info, message_filter_iterator> message_iterator; 00057 typedef boost::transform_iterator<folder_transform_info, folder_filter_iterator> folder_iterator; 00058 00061 pst(const std::wstring& filename) 00062 : m_db(open_database(filename)) { } 00063 00064 #ifndef BOOST_NO_RVALUE_REFERENCES 00065 00066 00067 pst(pst&& other) 00068 : m_db(std::move(other.m_db)), m_bag(std::move(other.m_bag)), m_map(std::move(other.m_map)) { } 00069 #endif 00070 00071 // subobject discovery/enumeration 00074 folder_iterator folder_begin() const 00075 { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_folder> >(m_db->read_nbt_root()->begin(), m_db->read_nbt_root()->end()), folder_transform_info(m_db) ); } 00078 folder_iterator folder_end() const 00079 { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_folder> >(m_db->read_nbt_root()->end(), m_db->read_nbt_root()->end()), folder_transform_info(m_db) ); } 00080 00083 message_iterator message_begin() const 00084 { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_message> >(m_db->read_nbt_root()->begin(), m_db->read_nbt_root()->end()), message_transform_info(m_db) ); } 00087 message_iterator message_end() const 00088 { return boost::make_transform_iterator(boost::make_filter_iterator<detail::is_nid_type<nid_type_message> >(m_db->read_nbt_root()->end(), m_db->read_nbt_root()->end()), message_transform_info(m_db) ); } 00089 00093 folder open_root_folder() const 00094 { return folder(m_db->lookup_node(nid_root_folder)); } 00099 folder open_folder(const std::wstring& name) const; 00100 00105 folder open_folder(node_id id) const 00106 { return folder(m_db->lookup_node(id)); } 00107 00112 search_folder open_search_folder(node_id id) const 00113 { return search_folder(m_db->lookup_node(id)); } 00114 00119 message open_message(node_id id) const 00120 { return message(m_db->lookup_node(id)); } 00121 00122 // property access 00125 std::wstring get_name() const 00126 { return get_property_bag().read_prop<std::wstring>(0x3001); } 00131 prop_id lookup_prop_id(const guid& g, const std::wstring& name) const 00132 { return get_name_id_map().lookup(g, name); } 00137 prop_id lookup_prop_id(const guid& g, long id) const 00138 { return get_name_id_map().lookup(g, id); } 00142 prop_id lookup_prop_id(const named_prop& n) 00143 { return get_name_id_map().lookup(n); } 00147 named_prop lookup_name_prop(prop_id id) const 00148 { return get_name_id_map().lookup(id); } 00149 00150 // lower layer access 00153 property_bag& get_property_bag(); 00156 name_id_map& get_name_id_map(); 00159 const property_bag& get_property_bag() const; 00162 const name_id_map& get_name_id_map() const; 00165 shared_db_ptr get_db() const 00166 { return m_db; } 00167 00168 private: 00169 shared_db_ptr m_db; 00170 mutable std::tr1::shared_ptr<property_bag> m_bag; 00171 mutable std::tr1::shared_ptr<name_id_map> m_map; 00172 }; 00173 00174 } // end fairport namespace 00175 00176 inline const fairport::property_bag& fairport::pst::get_property_bag() const 00177 { 00178 if(!m_bag) 00179 m_bag.reset(new property_bag(m_db->lookup_node(nid_message_store))); 00180 00181 return *m_bag; 00182 } 00183 00184 inline fairport::property_bag& fairport::pst::get_property_bag() 00185 { 00186 return const_cast<property_bag&>(const_cast<const pst*>(this)->get_property_bag()); 00187 } 00188 00189 inline const fairport::name_id_map& fairport::pst::get_name_id_map() const 00190 { 00191 if(!m_map) 00192 m_map.reset(new name_id_map(m_db)); 00193 00194 return *m_map; 00195 } 00196 00197 inline fairport::name_id_map& fairport::pst::get_name_id_map() 00198 { 00199 return const_cast<name_id_map&>(const_cast<const pst*>(this)->get_name_id_map()); 00200 } 00201 00202 inline fairport::folder fairport::pst::open_folder(const std::wstring& name) const 00203 { 00204 folder_iterator iter = std::find_if(folder_begin(), folder_end(), internal::folder_name_equal(name)); 00205 00206 if(iter != folder_end()) 00207 return *iter; 00208 00209 throw key_not_found<std::wstring>(name); 00210 } 00211 00212 #endif