Fairport  v1.0.38
fairport/pst/pst.h
Go to the documentation of this file.
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