Fairport
v1.0.38
|
00001 00002 00003 00004 00005 00006 #ifndef FAIRPORT_LTP_PROPBAG_H 00007 #define FAIRPORT_LTP_PROPBAG_H 00008 00009 #include <vector> 00010 #include <algorithm> 00011 00012 #include "fairport/util/primitives.h" 00013 #include "fairport/util/errors.h" 00014 00015 #include "fairport/ndb/node.h" 00016 00017 #include "fairport/ltp/object.h" 00018 #include "fairport/ltp/heap.h" 00019 00020 namespace fairport 00021 { 00022 00024 00025 typedef bth_node<prop_id, disk::prop_entry> pc_bth_node; 00026 typedef bth_nonleaf_node<prop_id, disk::prop_entry> pc_bth_nonleaf_node; 00027 typedef bth_leaf_node<prop_id, disk::prop_entry> pc_bth_leaf_node; 00029 00040 class property_bag : public const_property_object 00041 { 00042 public: 00045 explicit property_bag(const node& n); 00048 explicit property_bag(const heap& h); 00051 property_bag(const property_bag& other); 00052 00053 #ifndef BOOST_NO_RVALUE_REFERENCES 00054 00055 00056 property_bag(property_bag&& other) : m_pbth(std::move(other.m_pbth)) { } 00057 #endif 00058 00059 std::vector<prop_id> get_prop_list() const; 00060 prop_type get_prop_type(prop_id id) const 00061 { return (prop_type)m_pbth->lookup(id).type; } 00062 bool prop_exists(prop_id id) const; 00063 size_t size(prop_id id) const; 00064 hnid_stream_device open_prop_stream(prop_id id); 00065 00068 const node& get_node() const { return m_pbth->get_node(); } 00071 node& get_node() { return m_pbth->get_node(); } 00072 00073 private: 00074 property_bag& operator=(const property_bag& other); // = delete 00075 00076 byte get_value_1(prop_id id) const 00077 { return (byte)m_pbth->lookup(id).id; } 00078 ushort get_value_2(prop_id id) const 00079 { return (ushort)m_pbth->lookup(id).id; } 00080 ulong get_value_4(prop_id id) const 00081 { return (ulong)m_pbth->lookup(id).id; } 00082 ulonglong get_value_8(prop_id id) const; 00083 std::vector<byte> get_value_variable(prop_id id) const; 00084 void get_prop_list_impl(std::vector<prop_id>& proplist, const pc_bth_node* pbth_node) const; 00085 00086 std::tr1::shared_ptr<pc_bth_node> m_pbth; 00087 }; 00088 00089 } // end fairport namespace 00090 00091 inline fairport::property_bag::property_bag(const fairport::node& n) 00092 { 00093 heap h(n, disk::heap_sig_pc); 00094 00095 m_pbth = h.open_bth<prop_id, disk::prop_entry>(h.get_root_id()); 00096 } 00097 00098 inline fairport::property_bag::property_bag(const fairport::heap& h) 00099 { 00100 #ifdef FAIRPORT_VALIDATION_LEVEL_WEAK 00101 if(h.get_client_signature() != disk::heap_sig_pc) 00102 throw sig_mismatch("expected heap_sig_pc", 0, h.get_node().get_id(), h.get_client_signature(), disk::heap_sig_pc); 00103 #endif 00104 00105 heap my_heap(h); 00106 00107 m_pbth = my_heap.open_bth<prop_id, disk::prop_entry>(my_heap.get_root_id()); 00108 } 00109 00110 inline fairport::property_bag::property_bag(const property_bag& other) 00111 { 00112 heap h(other.m_pbth->get_node()); 00113 00114 m_pbth = h.open_bth<prop_id, disk::prop_entry>(h.get_root_id()); 00115 } 00116 00117 inline std::vector<fairport::prop_id> fairport::property_bag::get_prop_list() const 00118 { 00119 std::vector<prop_id> proplist; 00120 00121 get_prop_list_impl(proplist, m_pbth.get()); 00122 00123 return proplist; 00124 } 00125 00126 inline void fairport::property_bag::get_prop_list_impl(std::vector<prop_id>& proplist, const pc_bth_node* pbth_node) const 00127 { 00128 if(pbth_node->get_level() == 0) 00129 { 00130 // leaf 00131 const pc_bth_leaf_node* pleaf = static_cast<const pc_bth_leaf_node*>(pbth_node); 00132 00133 for(uint i = 0; i < pleaf->num_values(); ++i) 00134 proplist.push_back(pleaf->get_key(i)); 00135 } 00136 else 00137 { 00138 // non-leaf 00139 const pc_bth_nonleaf_node* pnonleaf = static_cast<const pc_bth_nonleaf_node*>(pbth_node); 00140 for(uint i = 0; i < pnonleaf->num_values(); ++i) 00141 get_prop_list_impl(proplist, pnonleaf->get_child(i)); 00142 } 00143 } 00144 00145 inline bool fairport::property_bag::prop_exists(prop_id id) const 00146 { 00147 try 00148 { 00149 (void)m_pbth->lookup(id); 00150 } 00151 catch(key_not_found<prop_id>&) 00152 { 00153 return false; 00154 } 00155 00156 return true; 00157 } 00158 00159 00160 inline fairport::ulonglong fairport::property_bag::get_value_8(prop_id id) const 00161 { 00162 std::vector<byte> buffer = get_value_variable(id); 00163 00164 return *(ulonglong*)&buffer[0]; 00165 } 00166 00167 inline std::vector<fairport::byte> fairport::property_bag::get_value_variable(prop_id id) const 00168 { 00169 heapnode_id h_id = (heapnode_id)get_value_4(id); 00170 std::vector<byte> buffer; 00171 00172 if(is_subnode_id(h_id)) 00173 { 00174 node sub(m_pbth->get_node().lookup(h_id)); 00175 buffer.resize(sub.size()); 00176 sub.read(buffer, 0); 00177 } 00178 else 00179 { 00180 buffer = m_pbth->get_heap_ptr()->read(h_id); 00181 } 00182 00183 return buffer; 00184 } 00185 00186 00187 inline size_t fairport::property_bag::size(prop_id id) const 00188 { 00189 heapnode_id h_id = (heapnode_id)get_value_4(id); 00190 00191 if(is_subnode_id(h_id)) 00192 return node(m_pbth->get_node().lookup(h_id)).size(); 00193 else 00194 return m_pbth->get_heap_ptr()->size(h_id); 00195 } 00196 00197 inline fairport::hnid_stream_device fairport::property_bag::open_prop_stream(prop_id id) 00198 { 00199 heapnode_id h_id = (heapnode_id)get_value_4(id); 00200 00201 if(h_id == 0) 00202 return m_pbth->get_heap_ptr()->open_stream(h_id); 00203 00204 if(is_subnode_id(h_id)) 00205 return m_pbth->get_node().lookup(h_id).open_as_stream(); 00206 else 00207 return m_pbth->get_heap_ptr()->open_stream(h_id); 00208 } 00209 #endif