inline const basic_oarchive_impl::cobject_type & basic_oarchive_impl::find(const basic_oserializer & bos) { std::pair<cobject_info_set_type::iterator, bool> cresult = cobject_info_set.insert(cobject_type(cobject_info_set.size(), bos)); return *(cresult.first); }
inline const basic_oarchive_impl::cobject_type & basic_oarchive_impl::register_type( const basic_oserializer & bos ){ cobject_type co(cobject_info_set.size(), bos); std::pair<cobject_info_set_type::const_iterator, bool> result = cobject_info_set.insert(co); return *(result.first); }
inline class_id_type basic_iarchive_impl::register_type( const basic_iserializer & bis ){ class_id_type cid(cobject_info_set.size()); cobject_type co(cid, bis); std::pair<cobject_info_set_type::const_iterator, bool> result = cobject_info_set.insert(co); if(result.second){ cobject_id_vector.push_back(cobject_id(bis)); BOOST_ASSERT(cobject_info_set.size() == cobject_id_vector.size()); } cid = result.first->m_class_id; // borland complains without this minor hack const int tid = cid; cobject_id & coid = cobject_id_vector[tid]; coid.bpis_ptr = bis.get_bpis_ptr(); return cid; }
inline const basic_pointer_iserializer * basic_iarchive_impl::load_pointer( basic_iarchive &ar, void * & t, const basic_pointer_iserializer * bpis_ptr, const basic_pointer_iserializer * (*finder)( const boost::serialization::extended_type_info & type_ ) ){ m_moveable_objects.is_pointer = true; serialization::state_saver<bool> w(m_moveable_objects.is_pointer); class_id_type cid; load(ar, cid); if(NULL_POINTER_TAG == cid){ t = NULL; return bpis_ptr; } // if its a new class type - i.e. never been registered if(class_id_type(cobject_info_set.size()) <= cid){ // if its either abstract if(NULL == bpis_ptr // or polymorphic || bpis_ptr->get_basic_serializer().is_polymorphic()){ // is must have been exported char key[BOOST_SERIALIZATION_MAX_KEY_SIZE]; class_name_type class_name(key); load(ar, class_name); // if it has a class name const serialization::extended_type_info *eti = NULL; if(0 != key[0]) eti = serialization::extended_type_info::find(key); if(NULL == eti) boost::serialization::throw_exception( archive_exception(archive_exception::unregistered_class) ); bpis_ptr = (*finder)(*eti); } BOOST_ASSERT(NULL != bpis_ptr); // class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer()); BOOST_VERIFY(register_type(bpis_ptr->get_basic_serializer()) == cid); int i = cid; cobject_id_vector[i].bpis_ptr = bpis_ptr; } int i = cid; cobject_id & co = cobject_id_vector[i]; bpis_ptr = co.bpis_ptr; load_preamble(ar, co); // extra line to evade borland issue const bool tracking = co.tracking_level; // if we're tracking and the pointer has already been read if(tracking && ! track(ar, t)) // we're done return bpis_ptr; // save state serialization::state_saver<object_id_type> w_start(m_moveable_objects.start); // allocate space on the heap for the object - to be constructed later t = bpis_ptr->heap_allocation(); BOOST_ASSERT(NULL != t); if(! tracking){ bpis_ptr->load_object_ptr(ar, t, co.file_version); } else{ serialization::state_saver<void *> x(m_pending.object); serialization::state_saver<const basic_iserializer *> y(m_pending.bis); serialization::state_saver<version_type> z(m_pending.version); m_pending.bis = & bpis_ptr->get_basic_serializer(); m_pending.version = co.file_version; // predict next object id to be created const unsigned int ui = object_id_vector.size(); serialization::state_saver<object_id_type> w_end(m_moveable_objects.end); // add to list of serialized objects so that we can properly handle // cyclic strucures object_id_vector.push_back(aobject(t, cid)); // remember that that the address of these elements could change // when we make another call so don't use the address bpis_ptr->load_object_ptr( ar, t, m_pending.version ); object_id_vector[ui].loaded_as_pointer = true; } return bpis_ptr; }
// save a pointer to an object instance inline void basic_oarchive_impl::save_pointer( basic_oarchive & ar, const void * t, const basic_pointer_oserializer * bpos_ptr ){ const basic_oserializer & bos = bpos_ptr->get_basic_serializer(); std::size_t original_count = cobject_info_set.size(); const cobject_type & co = register_type(bos); if(! co.m_initialized){ ar.vsave(co.m_class_id); // if its a previously unregistered class if((cobject_info_set.size() > original_count)){ if(bos.is_polymorphic()){ const serialization::extended_type_info *eti = & bos.get_eti(); const char * key = NULL; if(NULL != eti) key = eti->get_key(); if(NULL != key){ // the following is required by IBM C++ compiler which // makes a copy when passing a non-const to a const. This // is permitted by the standard but rarely seen in practice const class_name_type cn(key); // write out the external class identifier ar.vsave(cn); } else // without an external class name // we won't be able to de-serialize it so bail now boost::serialization::throw_exception( archive_exception(archive_exception::unregistered_class) ); } } if(bos.class_info()){ ar.vsave(tracking_type(bos.tracking(m_flags))); ar.vsave(version_type(bos.version())); } (const_cast<cobject_type &>(co)).m_initialized = true; } else{ ar.vsave(class_id_reference_type(co.m_class_id)); } // if we're not tracking if(! bos.tracking(m_flags)){ // just save the data itself ar.end_preamble(); serialization::state_saver<const void *> x(pending_object); serialization::state_saver<const basic_oserializer *> y(pending_bos); pending_object = t; pending_bos = & bpos_ptr->get_basic_serializer(); bpos_ptr->save_object_ptr(ar, t); return; } object_id_type oid(object_set.size()); // lookup to see if this object has already been written to the archive basic_oarchive_impl::aobject ao(t, co.m_class_id, oid); std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool> aresult = object_set.insert(ao); oid = aresult.first->object_id; // if the saved object already exists if(! aresult.second){ // append the object id to he preamble ar.vsave(object_reference_type(oid)); // and windup. ar.end_preamble(); return; } // append id of this object to preamble ar.vsave(oid); ar.end_preamble(); // and save the object itself serialization::state_saver<const void *> x(pending_object); serialization::state_saver<const basic_oserializer *> y(pending_bos); pending_object = t; pending_bos = & bpos_ptr->get_basic_serializer(); bpos_ptr->save_object_ptr(ar, t); // add to the set of object initially stored through pointers stored_pointers.insert(oid); }