📄 basic_iarchive.cpp
字号:
// note: extra line used to evade borland issue
const int id = cp.class_id;
const cobject_id & co = cobject_id_vector[id];
// with the appropriate input serializer,
// delete the indicated object
co.bis_ptr->destroy(cp.get_address());
created_pointers.pop_front();
}
}
inline class_id_type
basic_iarchive_impl::register_type(
const basic_iserializer & bis
){
class_id_type id(static_cast<int>(cobject_info_set.size()));
cobject_type co(id, 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));
assert(cobject_info_set.size() == cobject_id_vector.size());
}
id = result.first->class_id;
// borland complains without this minor hack
const int tid = id;
cobject_id & coid = cobject_id_vector[tid];
coid.bpis_ptr = bis.get_bpis_ptr();
return id;
}
void
basic_iarchive_impl::load_preamble(
basic_iarchive & ar,
cobject_id & co
){
if(! co.initialized){
if(co.bis_ptr->class_info()){
class_id_optional_type cid;
load(ar, cid); // to be thrown away
load(ar, co.tracking_level);
load(ar, co.file_version);
}
else{
// override tracking with indicator from class information
co.tracking_level = co.bis_ptr->tracking(m_flags);
co.file_version = version_type(
co.bis_ptr->version()
);
}
co.initialized = true;
}
}
bool
basic_iarchive_impl::track(
basic_iarchive & ar,
void * & t
){
object_id_type oid;
load(ar, oid);
// if its a reference to a old object
if(object_id_type(object_id_vector.size()) > oid){
// we're done
t = object_id_vector[oid].address;
return false;
}
return true;
}
inline void
basic_iarchive_impl::load_object(
basic_iarchive & ar,
void * t,
const basic_iserializer & bis
){
// if its been serialized through a pointer and the preamble's been done
if(t == pending_object && & bis == pending_bis){
// read data
(bis.load_object_data)(ar, t, pending_version);
return;
}
const class_id_type cid = register_type(bis);
// note: extra line used to evade borland issue
const int id = cid;
cobject_id & co = cobject_id_vector[id];
load_preamble(ar, co);
// save the current move stack position in case we want to truncate it
boost::state_saver<object_id_type> w(moveable_objects_start);
// note: extra line used to evade borland issue
const bool tracking = co.tracking_level;
object_id_type this_id;
moveable_objects_start =
this_id = object_id_vector.size();
// if we tracked this object when the archive was saved
if(tracking){
// if it was already read
if(!track(ar, t))
// we're done
return;
// add a new enty into the tracking list
object_id_vector.push_back(aobject(t, cid));
// and add an entry for this object
moveable_objects_end = object_id_vector.size();
}
// read data
(bis.load_object_data)(ar, t, co.file_version);
moveable_objects_recent = this_id;
}
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_
)
){
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::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
bpis_ptr = (*finder)(*eti);
}
assert(NULL != bpis_ptr);
class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer());
int i = cid;
cobject_id_vector[i].bpis_ptr = bpis_ptr;
assert(new_cid == cid);
}
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
state_saver<object_id_type> w(moveable_objects_start);
if(! tracking){
bpis_ptr->load_object_ptr(ar, t, co.file_version);
}
else{
state_saver<void *> x(pending_object);
state_saver<const basic_iserializer *> y(pending_bis);
state_saver<version_type> z(pending_version);
pending_bis = & bpis_ptr->get_basic_serializer();
pending_version = co.file_version;
// predict next object id to be created
const unsigned int ui = object_id_vector.size();
state_saver<object_id_type> w(moveable_objects_end);
// because the following operation could move the items
// don't use co after this
// add to list of serialized objects so that we can properly handle
// cyclic strucures
object_id_vector.push_back(aobject(t, cid));
bpis_ptr->load_object_ptr(
ar,
object_id_vector[ui].address,
co.file_version
);
t = object_id_vector[ui].address;
assert(NULL != t);
// and add to list of created pointers
created_pointers.push_back(created_pointer_type(cid, t));
}
return bpis_ptr;
}
//////////////////////////////////////////////////////////////////////
// implementation of basic_iarchive functions
BOOST_ARCHIVE_DECL(void)
basic_iarchive::next_object_pointer(void *t){
pimpl->next_object_pointer(t);
}
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_iarchive::basic_iarchive(unsigned int flags) :
pimpl(new basic_iarchive_impl(flags))
{}
BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
basic_iarchive::~basic_iarchive()
{
delete pimpl;
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::set_library_version(unsigned int archive_library_version){
pimpl->set_library_version(archive_library_version);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::reset_object_address(
const void * new_address,
const void * old_address
){
pimpl->reset_object_address(new_address, old_address);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::load_object(
void *t,
const basic_iserializer & bis
){
pimpl->load_object(*this, t, bis);
}
// load a pointer object
BOOST_ARCHIVE_DECL(const basic_pointer_iserializer *)
basic_iarchive::load_pointer(
void * &t,
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type_
)
){
return pimpl->load_pointer(*this, t, bpis_ptr, finder);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::register_basic_serializer(const basic_iserializer & bis){
pimpl->register_type(bis);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::lookup_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
pimpl->lookup_helper(eti, sph);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::insert_basic_helper(
const boost::serialization::extended_type_info * const eti,
shared_ptr<void> & sph
){
pimpl->insert_helper(eti, sph);
}
BOOST_ARCHIVE_DECL(void)
basic_iarchive::delete_created_pointers()
{
pimpl->delete_created_pointers();
}
BOOST_ARCHIVE_DECL(unsigned int)
basic_iarchive::get_library_version() const{
return pimpl->m_archive_library_version;
}
BOOST_ARCHIVE_DECL(unsigned int)
basic_iarchive::get_flags() const{
return pimpl->m_flags;
}
} // namespace detail
} // namespace archive
} // namespace boost
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -