basic_iarchive.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 572 行 · 第 1/2 页

CPP
572
字号
}inline class_id_typebasic_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;}voidbasic_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;    }}boolbasic_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 voidbasic_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);    const int i = cid;    cobject_id & co = cobject_id_vector[i];    load_preamble(ar, co);    // save the current move stack position in case we want to truncate it    boost::serialization::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::serialization::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    serialization::state_saver<object_id_type> w_start(moveable_objects_start);    if(! tracking){        bpis_ptr->load_object_ptr(ar, t, co.file_version);    }    else{        serialization::state_saver<void *> x(pending_object);        serialization::state_saver<const basic_iserializer *> y(pending_bis);        serialization::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();        serialization::state_saver<object_id_type> w_end(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;        object_id_vector[ui].loaded_as_pointer = true;        assert(NULL != t);    }    return bpis_ptr;}} // namespace detail} // namespace archive} // namespace boost//////////////////////////////////////////////////////////////////////// implementation of basic_iarchive functionsnamespace boost {namespace archive {namespace detail {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 objectBOOST_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::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 + =
减小字号Ctrl + -
显示快捷键?