*** empty log message ***

[SVN r23430]
This commit is contained in:
Robert Ramey
2004-07-11 00:30:45 +00:00
commit b7d6668e81
30 changed files with 3558 additions and 0 deletions

96
.gitattributes vendored Normal file
View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

56
src/basic_archive.cpp Normal file
View File

@@ -0,0 +1,56 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_archive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
//////////////////////////////////////////////////////////////////////
//
// objects are stored as
//
// class_id* // -1 for a null pointer
// if a new class id
// [
// exported key - class name*
// tracking level - always/never
// file version
// ]
//
// if tracking
// [
// object_id
// ]
//
// [ // if a new object id
// data...
// ]
//
// * required only for pointers - optional for objects
#include <boost/archive/basic_archive.hpp>
namespace boost {
namespace archive {
///////////////////////////////////////////////////////////////////////
// constants used in archive signature
//This should never ever change. note that is not an std::string
// string.
const char * ARCHIVE_SIGNATURE = "serialization::archive";
// this should change if the capabilities are added to the library
// such that archives can be created which can't be read by previous
// versions of this library
// 1 - initial version
// 2 - made address tracking optional
// 3 - numerous changes - can't guarentee compatibility with previous versions
const version_type ARCHIVE_VERSION(3);
const class_id_type null_pointer_tag(-1);
} // namespace archive
} // namespace boost

439
src/basic_iarchive.cpp Normal file
View File

@@ -0,0 +1,439 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_archive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc 6.0 needs this to suppress warnings
#include <cassert>
#include <set>
#include <list>
#include <vector>
#include <boost/limits.hpp>
#include <boost/state_saver.hpp>
#include <boost/throw_exception.hpp>
#include <boost/archive/detail/basic_iserializer.hpp>
#include <boost/archive/detail/basic_pointer_iserializer.hpp>
#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/archive/archive_exception.hpp>
using namespace boost::serialization;
namespace boost {
namespace archive {
namespace detail {
class basic_iserializer;
class basic_pointer_iserializer;
class basic_iarchive_impl
{
friend class basic_iarchive;
//////////////////////////////////////////////////////////////////////
// information about each serialized object loaded
// indexed on object_id
struct aobject
{
void * address;
class_id_type class_id;
aobject(
void *a,
class_id_type class_id_
) :
address(a),
class_id(class_id_)
{}
aobject() : address(NULL), class_id(-2) {}
};
typedef std::vector<aobject> object_id_vector_type;
object_id_vector_type object_id_vector;
//////////////////////////////////////////////////////////////////////
// used by load object to look up class id given basic_serializer
struct cobject_type
{
const basic_iserializer * bis;
const class_id_type class_id;
cobject_type(
size_t class_id_,
const basic_iserializer & bis_
) :
bis(& bis_),
class_id(class_id_)
{}
cobject_type(const cobject_type & rhs) :
bis(rhs.bis),
class_id(rhs.class_id)
{}
// the following cannot be defined because of the const
// member. This will generate a link error if an attempt
// is made to assign. This should never be necessary
cobject_type & operator=(const cobject_type & rhs);
bool operator<(const cobject_type &rhs) const
{
return *bis < *(rhs.bis);
}
};
typedef std::set<cobject_type> cobject_info_set_type;
cobject_info_set_type cobject_info_set;
//////////////////////////////////////////////////////////////////////
// information about each serialized class indexed on class_id
class cobject_id
{
public:
cobject_id & operator=(const cobject_id & rhs){
bis_ptr = rhs.bis_ptr;
bpis_ptr = rhs.bpis_ptr;
file_version = rhs.file_version;
tracking_level = rhs.tracking_level;
initialized = rhs.initialized;
return *this;
}
const basic_iserializer * bis_ptr;
const basic_pointer_iserializer * bpis_ptr;
version_type file_version;
tracking_type tracking_level;
bool initialized;
cobject_id(const basic_iserializer & bis_) :
bis_ptr(& bis_),
bpis_ptr(NULL),
file_version(0),
tracking_level(track_never),
initialized(false)
{}
cobject_id(const cobject_id &rhs):
bis_ptr(rhs.bis_ptr),
bpis_ptr(rhs.bpis_ptr),
file_version(rhs.file_version),
tracking_level(rhs.tracking_level),
initialized(rhs.initialized)
{}
};
typedef std::vector<cobject_id> cobject_id_vector_type;
cobject_id_vector_type cobject_id_vector;
// list of objects created by de-serialization. Used to implement
// clean up after exceptions.
class created_pointer_type
{
public:
created_pointer_type(
class_id_type class_id_,
void * address_
) :
class_id(class_id_),
address(address_)
{}
created_pointer_type(const created_pointer_type &rhs) :
class_id(rhs.class_id),
address(rhs.address)
{}
created_pointer_type & operator=(const created_pointer_type &){
assert(false);
return *this;
}
void * get_address() const {
return address;
}
// object to which this item refers
const class_id_type class_id;
private:
void * address;
};
std::list<created_pointer_type> created_pointers;
bool is_object; // pass forward indicater that we're saving an object
// directly rather than result of a pointer
basic_iarchive_impl()
: is_object(true)
{}
bool
track(
basic_iarchive & ar,
void * & t
);
void
load_preamble(
basic_iarchive & ar,
cobject_id & co
);
class_id_type register_type(
const basic_iserializer & bis
);
// redirect through virtual functions to load functions for this archive
template<class T>
void load(basic_iarchive & ar, T & t){
ar.vload(t);
}
public:
void delete_created_pointers();
class_id_type register_type(
const basic_pointer_iserializer & bpis
);
void load_object(
basic_iarchive & ar,
void * & t,
const basic_iserializer & bis
);
const basic_pointer_iserializer * load_pointer(
basic_iarchive & ar,
void * & t,
const basic_pointer_iserializer * bpis,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type
)
);
};
inline void
basic_iarchive_impl::delete_created_pointers()
{
while(created_pointers.size() > 0){
const created_pointer_type & cp = created_pointers.front();
// figure out the class of the object to be deleted
// note: extra line used to evand 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
){
cobject_type co(cobject_info_set.size(), 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());
}
const int id = result.first->class_id;
cobject_id & coid = cobject_id_vector[id];
coid.bpis_ptr = bis.get_bpis_ptr();
return result.first->class_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();
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
){
bool result = true;
const class_id_type cid = register_type(bis);
// note: extra line used to evand borland issue
const int id = cid;
cobject_id & co = cobject_id_vector[id];
if(is_object){
load_preamble(ar, co);
// note: extra line used to evand borland issue
const bool b = co.tracking_level;
if(b){
result = track(ar, t);
if(! result)
return;
object_id_vector.push_back(aobject(t, cid));
}
}
// read data if required
state_saver<bool> x(is_object);
is_object = true;
(bis.load_object_data)(ar, t, co.file_version);
}
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];
const basic_iserializer * bis_ptr = co.bis_ptr;
bpis_ptr = co.bpis_ptr;
load_preamble(ar, co);
bool track_object = true;
// extra line to evade borland issue
const bool b = co.tracking_level;
if(b)
track_object = track(ar, t);
// if required
if(track_object){
// read data
state_saver<bool> x(is_object);
is_object = false;
if(bis_ptr->tracking()){
// predict next object id to be created
const unsigned int i = object_id_vector.size();
// because the following operation could move the items
// don't use co after this
object_id_vector.push_back(aobject(t, cid));
bpis_ptr->load_object_ptr(
ar,
object_id_vector[i].address,
co.file_version
);
t = object_id_vector[i].address;
// and add to list of created pointers
created_pointers.push_back(created_pointer_type(cid, t));
}
else{
bpis_ptr->load_object_ptr(ar, t, co.file_version);
}
assert(NULL != t);
}
return bpis_ptr;
}
//////////////////////////////////////////////////////////////////////
// implementation of basic_iarchive functions
basic_iarchive::basic_iarchive() :
pimpl(new basic_iarchive_impl),
archive_library_version(ARCHIVE_VERSION)
{}
basic_iarchive::~basic_iarchive()
{
delete pimpl;
}
void basic_iarchive::load_object(
void *t,
const basic_iserializer & bis
){
pimpl->load_object(*this, t, bis);
}
// load a pointer object
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);
}
void basic_iarchive::register_basic_serializer(const basic_iserializer & bis){
pimpl->register_type(bis);
}
void basic_iarchive::delete_created_pointers()
{
pimpl->delete_created_pointers();
}
} // namespace detail
} // namespace archive
} // namespace boost

395
src/basic_oarchive.cpp Normal file
View File

@@ -0,0 +1,395 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <cassert>
#include <set>
#include <boost/limits.hpp>
#include <boost/state_saver.hpp>
#include <boost/throw_exception.hpp>
// including this here to work around an ICC in intel 7.0
// normally this would be part of basic_oarchive.hpp below.
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/basic_oserializer.hpp>
#include <boost/archive/detail/basic_pointer_oserializer.hpp>
#include <boost/archive/detail/basic_oarchive.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/archive/archive_exception.hpp>
using namespace boost::serialization;
namespace boost {
namespace archive {
namespace detail {
class basic_oserializer;
class basic_pointer_oserializer;
class basic_oarchive_impl
{
friend class basic_oarchive;
//////////////////////////////////////////////////////////////////////
// information about each serialized object saved
// keyed on address, class_id
struct aobject
{
const void * address;
class_id_type class_id;
object_id_type object_id;
bool operator<(const aobject &rhs) const
{
assert(NULL != address);
assert(NULL != rhs.address);
if( address < rhs.address )
return true;
if( address > rhs.address )
return false;
return class_id < rhs.class_id;
}
aobject & operator=(const aobject & rhs)
{
address = rhs.address;
class_id = rhs.class_id;
object_id = rhs.object_id;
return *this;
}
aobject(
const void *a,
class_id_type class_id_,
object_id_type object_id_
) :
address(a),
class_id(class_id_),
object_id(object_id_)
{}
aobject() : address(NULL){}
};
// keyed on class_id, address
typedef std::set<aobject> object_set_type;
object_set_type object_set;
//////////////////////////////////////////////////////////////////////
// information about each serialized class saved
// keyed on type_info
struct cobject_type
{
const basic_oserializer * bos_ptr;
const class_id_type class_id;
bool initialized;
cobject_type(
size_t class_id_,
const basic_oserializer & bos_
) :
bos_ptr(& bos_),
class_id(class_id_),
initialized(false)
{}
cobject_type(const basic_oserializer & bos_)
: bos_ptr(& bos_)
{}
cobject_type(
const cobject_type & rhs
) :
bos_ptr(rhs.bos_ptr),
class_id(rhs.class_id),
initialized(rhs.initialized)
{}
// the following cannot be defined because of the const
// member. This will generate a link error if an attempt
// is made to assign. This should never be necessary
// use this only for lookup argument
cobject_type & operator=(const cobject_type &rhs);
bool operator<(const cobject_type &rhs) const {
return *bos_ptr < *(rhs.bos_ptr);
}
};
// keyed on type_info
typedef std::set<cobject_type> cobject_info_set_type;
cobject_info_set_type cobject_info_set;
// list of objects initially stored as pointers - used to detect errors
// keyed on object id
std::set<object_id_type> stored_pointers;
bool is_object; // pass forward indicater that we're saving an object
// directly rather than result of a pointer
basic_oarchive_impl()
: is_object(true)
{}
const cobject_type &
find(const basic_oserializer & bos);
const basic_oserializer *
find(const serialization::extended_type_info &ti) const;
void
save_preamble(
basic_oarchive & ar,
const unsigned int file_version,
bool tracking
);
bool
track(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos,
const class_id_type cid,
bool is_object
);
public:
const cobject_type &
register_type(const basic_oserializer & bos);
void save_object(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos
);
void save_pointer(
basic_oarchive & ar,
const void * t,
const basic_pointer_oserializer * bpos
);
};
//////////////////////////////////////////////////////////////////////
// implementation of basic_oarchive implementation functions
// given a type_info - find its bos
// return NULL if not found
inline const basic_oserializer *
basic_oarchive_impl::find(const serialization::extended_type_info & ti) const {
class bosarg : public basic_oserializer
{
bool class_info() const {
assert(false);
return false;
}
// returns true if objects should be tracked
bool tracking() const {
assert(false);
return false;
}
// returns class version
unsigned int version() const {
assert(false);
return 0;
}
// returns true if this class is polymorphic
bool is_polymorphic() const{
assert(false);
return false;
}
void save_object_data(
basic_oarchive & ar, const void * x
) const {
assert(false);
}
public:
bosarg(const serialization::extended_type_info & type_) :
boost::archive::detail::basic_oserializer(type_)
{}
};
bosarg bos(ti);
cobject_info_set_type::const_iterator cit
= cobject_info_set.find(cobject_type(bos));
// it should already have been "registered" - see below
if(cit == cobject_info_set.end()){
// if an entry is not found in the table it is because a pointer
// of a derived class has been serialized through its base class
// but the derived class hasn't been "registered"
return NULL;
}
// return pointer to the real class
return cit->bos_ptr;
}
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);
}
void
basic_oarchive_impl::save_preamble(
basic_oarchive & ar,
const unsigned int file_version,
bool tracking
){
ar.vsave(tracking_type(tracking));
ar.vsave(version_type(file_version));
}
// return true if this is a new object and should be serialized
// false if it can be skipped.
bool
basic_oarchive_impl::track(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos,
const class_id_type cid,
bool is_object
){
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, cid, oid);
std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool>
aresult = object_set.insert(ao);
oid = aresult.first->object_id;
// if its aready there
if(! aresult.second){
ar.vsave(object_reference_type(oid));
// and its an object
if(is_object
// but it was originally stored through a pointer
&& stored_pointers.end() != stored_pointers.find(oid)){
// this has to be a user error. loading such an archive
// would create duplicate objects
boost::throw_exception(
archive_exception(archive_exception::pointer_conflict)
);
}
return false;
}
ar.vsave(oid);
if(! is_object)
// add to the set of object initially stored through pointers
stored_pointers.insert(oid);
return true;
}
inline void
basic_oarchive_impl::save_object(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos
){
bool new_object = true;
if(is_object){
const cobject_type & co = register_type(bos);
if(bos.class_info()){
if( ! co.initialized){
ar.vsave(class_id_optional_type(co.class_id));
save_preamble(ar, bos.version(), bos.tracking());
(const_cast<cobject_type &>(co)).initialized = true;
}
}
if(bos.tracking())
new_object = track(ar, t, bos, co.class_id, true);
ar.end_preamble();
}
if(new_object){
state_saver<bool> x(is_object);
is_object = true;
(bos.save_object_data)(ar, t);
}
}
// 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();
unsigned int original_count = cobject_info_set.size();
const cobject_type & co = register_type(bos);
if(! co.initialized){
ar.vsave(co.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.type;
const char * key = NULL;
if(NULL != eti)
key = eti->key;
if(NULL != key)
// write out the external class identifier
ar.vsave(class_name_type(key));
else
// without an external class name
// we won't be able to de-serialize it so bail now
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
}
}
if(bos.class_info())
save_preamble(ar, bos.version(), bos.tracking());
(const_cast<cobject_type &>(co)).initialized = true;
}
else{
ar.vsave(class_id_reference_type(co.class_id));
}
bool result = true;
if(bos.tracking())
result = track(ar, t, bos, co.class_id, false);
ar.end_preamble();
if(result){
state_saver<bool> x(is_object);
is_object = false;
bpos_ptr->save_object_ptr(ar, t);
}
}
//////////////////////////////////////////////////////////////////////
// implementation of basic_oarchive functions
basic_oarchive::basic_oarchive()
: pimpl(new basic_oarchive_impl)
{}
basic_oarchive::~basic_oarchive()
{
delete pimpl;
}
void basic_oarchive::save_object(
const void *x,
const basic_oserializer & bos
){
pimpl->save_object(*this, x, bos);
}
void basic_oarchive::save_pointer(
const void * t,
const basic_pointer_oserializer * bpos_ptr
){
pimpl->save_pointer(*this, t, bpos_ptr);
}
void basic_oarchive::register_basic_serializer(const basic_oserializer & bos){
pimpl->register_type(bos);
}
} // namespace detail
} // namespace archive
} // namespace boost

View File

@@ -0,0 +1,51 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// serializer_map.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <set>
#include <boost/archive/detail/basic_serializer.hpp>
#include <boost/archive/detail/basic_serializer_map.hpp>
namespace boost {
namespace serialization {
class extended_type_info;
}
namespace archive {
namespace detail {
bool basic_serializer_map::insert(const basic_serializer * bs){
return map.insert(bs).second;
}
class basic_serializer_arg : public basic_serializer {
public:
basic_serializer_arg(const serialization::extended_type_info & eti) :
basic_serializer(eti)
{}
};
const basic_serializer * basic_serializer_map::tfind(
const boost::serialization::extended_type_info & type_
) const {
const basic_serializer_arg bs(type_);
map_type::const_iterator it;
it = map.find(& bs);
if(it == map.end())
return NULL;
return *it;
}
} // namespace detail
} // namespace archive
} // namespace boost

24
src/basic_xml_archive.cpp Normal file
View File

@@ -0,0 +1,24 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_archive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
namespace boost {
namespace archive {
const char * OBJECT_ID = "object_id";
const char * OBJECT_REFERENCE = "object_id_reference";
const char * CLASS_ID = "class_id";
const char * CLASS_ID_REFERENCE = "class_id_reference";
const char * CLASS_NAME = "class_name";
const char * TRACKING = "tracking_level";
const char * VERSION = "version";
const char * SIGNATURE = "signature";
}// namespace archive
}// namespace boost

26
src/binary_iarchive.cpp Normal file
View File

@@ -0,0 +1,26 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// binary_iarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class basic_binary_iprimitive<binary_iarchive, std::istream> ;
template class binary_iarchive_impl<binary_iarchive> ;
template class detail::archive_pointer_iserializer<binary_iarchive> ;
} // namespace archive
} // namespace boost

26
src/binary_oarchive.cpp Normal file
View File

@@ -0,0 +1,26 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// binary_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of binary stream
template class basic_binary_oprimitive<binary_oarchive, std::ostream> ;
template class binary_oarchive_impl<binary_oarchive> ;
template class detail::archive_pointer_oserializer<binary_oarchive> ;
} // namespace archive
} // namespace boost

35
src/binary_wiarchive.cpp Normal file
View File

@@ -0,0 +1,35 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// binary_wiarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <boost/archive/binary_wiarchive.hpp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of text stream
template class basic_binary_iprimitive<binary_wiarchive, std::wistream> ;
template class binary_wiarchive_impl<binary_wiarchive> ;
template class detail::archive_pointer_iserializer<binary_wiarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF

34
src/binary_woarchive.cpp Normal file
View File

@@ -0,0 +1,34 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// binary_woarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <boost/archive/binary_woarchive.hpp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of text stream
template class basic_binary_oprimitive<binary_woarchive, std::wostream> ;
template class binary_woarchive_impl<binary_woarchive> ;
template class detail::archive_pointer_oserializer<binary_woarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF

87
src/codecvt_null.cpp Normal file
View File

@@ -0,0 +1,87 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// codecvt_null.cpp
// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/archive/codecvt_null.hpp>
// codecvt implementation for passing wchar_t objects to char output
// without any translation whatever. Used to implement binary output
// of wchar_t objects.
namespace boost {
namespace archive {
std::codecvt_base::result
codecvt_null<wchar_t>::do_out(
mbstate_t & state,
const wchar_t * first1,
const wchar_t * last1,
const wchar_t * & next1,
char * first2,
char * last2,
char * & next2
) const {
for(;first1 != last1; ++first1){
// Per std::22.2.1.5.2/2, we can store no more that
// last2-first2 characters. If we need to more encode
// next internal char type, return 'partial'.
if(static_cast<int>(sizeof(wchar_t)) > (last2 - first2)){
next1 = first1;
next2 = first2;
return std::codecvt_base::partial;
}
unsigned int i;
for(i = sizeof(wchar_t); i > 0;)
*first2++ = (* first1 >> (8 * --i)) & 0xff;
}
next1 = first1;
next2 = first2;
return std::codecvt_base::ok;
}
std::codecvt_base::result
codecvt_null<wchar_t>::do_in(
mbstate_t & state,
const char * first1,
const char * last1,
const char * & next1,
wchar_t * first2,
wchar_t * last2,
wchar_t * & next2
) const {
// Process input characters until we've run of them,
// or the number of remaining characters is not
// enough to construct another output character,
// or we've run out of place for output characters.
while(first2 != last2){
// Have we converted all input characters?
// Return with 'ok', if so.
if (first1 == last1)
break;
// Do we have less input characters than needed
// for a single output character?
if(static_cast<int>(sizeof(wchar_t)) > (last1 - first1)){
next1 = first1;
next2 = first2;
return std::codecvt_base::partial;
}
*first2 = static_cast<unsigned char>(*first1++);
int i = sizeof(wchar_t) - 1;
do{
*first2 <<= 8;
*first2 |= static_cast<unsigned char>(*first1++);
}while(--i > 0);
++first2;
}
next1 = first1;
next2 = first2;
return std::codecvt_base::ok;
}
} // namespace archive
} // namespace boost

179
src/extended_type_info.cpp Normal file
View File

@@ -0,0 +1,179 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// extended_type_info.cpp: implementation for portable version of type_info
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc needs this to suppress warning
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{ using ::strcmp; }
#endif
#include <set>
#include <cassert>
#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace serialization {
namespace { // anonymous
struct type_info_compare
{
bool
operator()(const extended_type_info * lhs, const extended_type_info * rhs) const
{
return *lhs < *rhs;
}
};
struct key_compare
{
bool
operator()(const extended_type_info * lhs, const extended_type_info * rhs) const
{
// shortcut to exploit string pooling
if(lhs->key == rhs->key)
return false;
if(NULL == lhs->key)
return true;
if(NULL == rhs->key)
return false;
return std::strcmp(lhs->key, rhs->key) < 0;
}
};
// use static local variables to ensure that collections are
// initialized before being used.
typedef std::set<const extended_type_info *, type_info_compare> tkmap_type;
static tkmap_type &
tkmap(){
static tkmap_type map;
return map;
}
typedef std::set<const extended_type_info *, key_compare> ktmap_type;
static ktmap_type &
ktmap(){
static ktmap_type map;
return map;
}
} // anonymous
void extended_type_info::self_register()
{
tkmap().insert(this);
}
void extended_type_info::key_register(const char *key_) {
if(NULL == key_)
return;
key = key_;
ktmap().insert(this);
}
namespace {
class extended_type_info_arg : public extended_type_info
{
public:
extended_type_info_arg(const char * search_key_)
: extended_type_info(NULL)
{
key = search_key_;
}
virtual bool
less_than(const extended_type_info &rhs) const
{
assert(false);
return false; // to prevent a syntax error
}
virtual bool
equal_to(const extended_type_info &rhs) const{
assert(false);
return false; // to prevent a syntax error
}
virtual bool
not_equal_to(const extended_type_info &rhs) const{
assert(false);
return false; // to prevent a syntax error
}
};
} // anonymous
const extended_type_info * extended_type_info::find(const char *key)
{
extended_type_info_arg arg(key);
ktmap_type::const_iterator it;
it = ktmap().find(&arg);
if(it == ktmap().end())
return NULL;
return *it;
}
const extended_type_info * extended_type_info::find(const extended_type_info * t)
{
tkmap_type::const_iterator it;
it = tkmap().find(t);
if(it == tkmap().end())
return NULL;
return *it;
}
namespace { // anonymous
int type_info_key_cmp(
const extended_type_info & lhs,
const extended_type_info & rhs
) {
if(lhs.type_info_key == rhs.type_info_key)
return 0;
//return strcmp(lhs.type_info_key, rhs.type_info_key);
// all we require is that the type_info_key be unique
// so just compare the addresses
return lhs.type_info_key < rhs.type_info_key ? -1 : 1;
}
} // anonymous
bool operator<(
const extended_type_info &lhs,
const extended_type_info &rhs
){
int i = type_info_key_cmp(lhs, rhs);
if(i < 0)
return true;
if(i > 0)
return false;
return lhs.less_than(rhs);
}
bool operator==(
const extended_type_info &lhs,
const extended_type_info &rhs
){
int i = type_info_key_cmp(lhs, rhs);
if(i != 0)
return false;
return lhs.equal_to(rhs);
}
bool operator!=(
const extended_type_info &lhs,
const extended_type_info &rhs
){
int i = type_info_key_cmp(lhs, rhs);
if(i != 0)
return true;
return lhs.not_equal_to(rhs);
}
} // namespace serialization
} // namespace boost

View File

@@ -0,0 +1,21 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// extended_type_info_no_rtti.cpp: specific implementation of type info
// that is NOT based on typeid
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/serialization/extended_type_info_no_rtti.hpp>
namespace boost {
namespace serialization {
const char * extended_type_info_no_rtti_base::type_info_key
= "extended_type_info_no_rtti";
} // namespace serialization
} // namespace boost

View File

@@ -0,0 +1,23 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// extended_type_info_typeid.cpp: specific implementation of type info
// that is based on typeid
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/serialization/extended_type_info_typeid.hpp>
namespace boost {
namespace serialization {
namespace detail {
const char * extended_type_info_typeid_0::type_info_key
= "extended_type_info_typeid";
} // namespace detail
} // namespace serialization
} // namespace boost

View File

@@ -0,0 +1,28 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_iarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <istream>
#include <boost/archive/polymorphic_iarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
template class detail::archive_pointer_iserializer<polymorphic_iarchive> ;
} // namespace serialization
} // namespace boost

View File

@@ -0,0 +1,28 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <ostream>
#include <boost/archive/polymorphic_oarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
template class detail::archive_pointer_oserializer<polymorphic_oarchive> ;
} // namespace serialization
} // namespace boost

30
src/text_iarchive.cpp Normal file
View File

@@ -0,0 +1,30 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// text_iarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <boost/archive/text_iarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_text_iprimitive.ipp>
#include <boost/archive/impl/basic_text_iarchive.ipp>
#include <boost/archive/impl/text_iarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_iprimitive<std::istream> ;
template class basic_text_iarchive<text_iarchive> ;
template class text_iarchive_impl<text_iarchive> ;
template class detail::archive_pointer_iserializer<text_iarchive> ;
} // namespace archive
} // namespace boost

32
src/text_oarchive.cpp Normal file
View File

@@ -0,0 +1,32 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// text_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <ostream>
#include <boost/archive/text_oarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_text_oprimitive.ipp>
#include <boost/archive/impl/text_oarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_oprimitive<std::ostream> ;
template class text_oarchive_impl<text_oarchive> ;
template class detail::archive_pointer_oserializer<text_oarchive> ;
} // namespace serialization
} // namespace boost

40
src/text_wiarchive.cpp Normal file
View File

@@ -0,0 +1,40 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// text_wiarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <istream>
#include <boost/archive/text_wiarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_text_iprimitive.ipp>
#include <boost/archive/impl/basic_text_iarchive.ipp>
#include <boost/archive/impl/text_wiarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_iprimitive<std::wistream> ;
template class basic_text_iarchive<text_wiarchive> ;
template class text_wiarchive_impl<text_wiarchive> ;
template class detail::archive_pointer_iserializer<text_wiarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF

37
src/text_woarchive.cpp Normal file
View File

@@ -0,0 +1,37 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// text_woarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <ostream>
#include <boost/archive/text_woarchive.hpp>
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_text_oprimitive.ipp>
#include <boost/archive/impl/text_woarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_oprimitive<std::wostream> ;
template class text_woarchive_impl<text_woarchive> ;
template class detail::archive_pointer_oserializer<text_woarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF

344
src/utf8_codecvt_facet.cpp Normal file
View File

@@ -0,0 +1,344 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// utf8_codecvt_facet.cpp
// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//#include <cstdlib> // for multi-byte converson routines
#include <cassert>
#include <boost/integer_traits.hpp>
#include <boost/utf8_codecvt_facet.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation for wchar_t
// Translate incoming UTF-8 into UCS-4
std::codecvt_base::result utf8_codecvt_facet_wchar_t::do_in(
mbstate_t& state,
const char * from,
const char * from_end,
const char * & from_next,
wchar_t * to,
wchar_t * to_end,
wchar_t * & to_next
) const {
// Basic algorithm: The first octet determines how many
// octets total make up the UCS-4 character. The remaining
// "continuing octets" all begin with "10". To convert, subtract
// the amount that specifies the number of octets from the first
// octet. Subtract 0x80 (1000 0000) from each continuing octet,
// then mash the whole lot together. Note that each continuing
// octet only uses 6 bits as unique values, so only shift by
// multiples of 6 to combine.
while (from != from_end && to != to_end) {
// Error checking on the first octet
if (invalid_leading_octet(*from)){
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
// The first octet is adjusted by a value dependent upon
// the number of "continuing octets" encoding the character
const int cont_octet_count = get_cont_octet_count(*from);
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
// The unsigned char conversion is necessary in case char is
// signed (I learned this the hard way)
wchar_t ucs_result =
(unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
// Invariants :
// 1) At the start of the loop, 'i' continuing characters have been
// processed
// 2) *from points to the next continuing character to be processed.
int i = 0;
while(i != cont_octet_count && from != from_end) {
// Error checking on continuing characters
if (invalid_continuing_octet(*from)) {
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
ucs_result *= (1 << 6);
// each continuing character has an extra (10xxxxxx)b attached to
// it that must be removed.
ucs_result += (unsigned char)(*from++) - 0x80;
++i;
}
// If the buffer ends with an incomplete unicode character...
if (from == from_end && i != cont_octet_count) {
// rewind "from" to before the current character translation
from_next = from - (i+1);
to_next = to;
return std::codecvt_base::partial;
}
*to++ = ucs_result;
}
from_next = from;
to_next = to;
// Were we done converting or did we run out of destination space?
if(from == from_end) return std::codecvt_base::ok;
else return std::codecvt_base::partial;
}
std::codecvt_base::result utf8_codecvt_facet_wchar_t::do_out(
mbstate_t & state,
const wchar_t * from,
const wchar_t * from_end,
const wchar_t * & from_next,
char * to,
char * to_end,
char * & to_next
) const
{
// RG - consider merging this table with the other one
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
while (from != from_end && to != to_end) {
// Check for invalid UCS-4 character
if (*from > std::numeric_limits<wchar_t>::max()) {
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
int cont_octet_count = get_cont_octet_out_count(*from);
// RG - comment this formula better
int shift_exponent = (cont_octet_count) * 6;
// Process the first character
*to++ = octet1_modifier_table[cont_octet_count] +
(unsigned char)(*from / (1 << shift_exponent));
// Process the continuation characters
// Invariants: At the start of the loop:
// 1) 'i' continuing octets have been generated
// 2) '*to' points to the next location to place an octet
// 3) shift_exponent is 6 more than needed for the next octet
int i = 0;
while (i != cont_octet_count && to != to_end) {
shift_exponent -= 6;
*to++ = 0x80 + ((*from / (1 << shift_exponent)) % (1 << 6));
++i;
}
// If we filled up the out buffer before encoding the character
if(to == to_end && i != cont_octet_count) {
from_next = from;
to_next = to - (i+1);
return std::codecvt_base::partial;
}
*from++;
}
from_next = from;
to_next = to;
// Were we done or did we run out of destination space
if(from == from_end) return std::codecvt_base::ok;
else return std::codecvt_base::partial;
}
// How many char objects can I process to get <= max_limit
// wchar_t objects?
int utf8_codecvt_facet_wchar_t::do_length(
const mbstate_t &,
const char * from,
const char * from_end,
size_t max_limit
) const throw()
{
// RG - this code is confusing! I need a better way to express it.
// and test cases.
// Invariants:
// 1) last_octet_count has the size of the last measured character
// 2) char_count holds the number of characters shown to fit
// within the bounds so far (no greater than max_limit)
// 3) from_next points to the octet 'last_octet_count' before the
// last measured character.
int last_octet_count=0;
size_t char_count = 0;
const char* from_next = from;
// Use "<" because the buffer may represent incomplete characters
while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
from_next += last_octet_count;
last_octet_count = (get_octet_count(*from_next));
++char_count;
}
return from_next-from_end;
}
unsigned int utf8_codecvt_facet_wchar_t::get_octet_count(
unsigned char lead_octet
){
// if the 0-bit (MSB) is 0, then 1 character
if (lead_octet <= 0x7f) return 1;
// Otherwise the count number of consecutive 1 bits starting at MSB
assert(0xc0 <= lead_octet && lead_octet <= 0xfd);
if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2;
else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3;
else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4;
else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5;
else return 6;
}
namespace {
template<size_t s>
int get_cont_octet_out_count_impl(wchar_t word){
if (word < 0x80) {
return 0;
}
if (word < 0x800) {
return 1;
}
return 2;
}
// note the following code will generate on some platforms where
// wchar_t is defined as UCS2. The warnings are superfluous as
// the specialization is never instantitiated with such compilers.
template<>
int get_cont_octet_out_count_impl<4>(wchar_t word){
if (word < 0x80) {
return 0;
}
if (word < 0x800) {
return 1;
}
if (word < 0x10000) {
return 2;
}
if (word < 0x200000) {
return 3;
}
if (word < 0x4000000) {
return 4;
}
return 5;
}
} // namespace anonymous
// How many "continuing octets" will be needed for this word
// == total octets - 1.
int utf8_codecvt_facet_wchar_t::get_cont_octet_out_count(
wchar_t word
) const {
return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
}
#if 0 // not used?
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation for char
std::codecvt_base::result utf8_codecvt_facet_char::do_in(
mbstate_t & state,
const char * from,
const char * from_end,
const char * & from_next,
char * to,
char * to_end,
char * & to_next
) const
{
while(from_next < from_end){
wchar_t w;
wchar_t *wnext = & w;
utf8_codecvt_facet_wchar_t::result ucs4_result;
ucs4_result = base_class::do_in(
state,
from, from_end, from_next,
wnext, wnext + 1, wnext
);
if(codecvt_base::ok != ucs4_result)
return ucs4_result;
// if the conversion succeeds.
int length = std::wctomb(to_next, w);
assert(-1 != length);
to_next += length;
}
return codecvt_base::ok;
}
std::codecvt_base::result utf8_codecvt_facet_char::do_out(
mbstate_t & state,
const char * from,
const char * from_end,
const char * & from_next,
char * to,
char * to_end,
char * & to_next
) const
{
while(from_next < from_end){
wchar_t w;
int result = std::mbtowc(&w, from_next, MB_LENGTH_MAX);
assert(-1 != result);
from_next += result;
utf8_codecvt_facet_wchar_t::result ucs4_result;
const wchar_t *wptr = & w;
ucs4_result = base_class::do_out(
state,
wptr, wptr+1, wptr,
to_next, to_end, to_next
);
if(codecvt_base::ok != ucs4_result)
return ucs4_result;
}
return codecvt_base::ok;
}
// How many bytes objects can I process to get <= max_limit
// char objects?
int utf8_codecvt_facet_char::do_length(
const utf8_codecvt_facet_wchar_t::mbstate_t & initial_state,
const char * from_next,
const char * from_end,
size_t max_limit
) const
{
int total_length = 0;
const char *from = from_next;
mbstate_t state = initial_state;
while(from_next < from_end){
wchar_t w;
wchar_t *wnext = & w;
utf8_codecvt_facet_wchar_t::result ucs4_result;
ucs4_result = base_class::do_in(
state,
from_next, from_end, from_next,
wnext, wnext + 1, wnext
);
if(codecvt_base::ok != ucs4_result)
break;
char carray[MB_LENGTH_MAX];
size_t count = wctomb(carray, w);
if(count > max_limit)
break;
max_limit -= count;
total_length = from_next - from;
}
return total_length;
}
#endif

194
src/void_cast.cpp Normal file
View File

@@ -0,0 +1,194 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// void_cast.cpp: implementation of run-time casting of void pointers
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// <gennadiy.rozental@tfn.com>
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc needs this to suppress warning
// STL
#include <set>
#include <functional>
#include <algorithm>
#include <cassert>
// BOOST
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/extended_type_info.hpp>
namespace boost {
namespace serialization {
namespace void_cast_detail {
struct void_caster_compare
{
bool
operator()( void_caster const* lhs, void_caster const* rhs ) const
{
if( lhs->m_derived_type < rhs->m_derived_type )
return true;
if( rhs->m_derived_type < lhs->m_derived_type)
return false;
if( lhs->m_base_type < rhs->m_base_type )
return true;
return false;
}
};
struct void_caster_registry
{
typedef std::set<void_caster*,void_caster_compare> set_type;
typedef set_type::iterator iterator;
set_type m_set;
};
// note: using accessing through this singleton guarentees that the
// constructor for the set is invoked before any entries are added to it.
void_caster_registry &
global_registry()
{
static void_caster_registry instance;
return instance;
}
void
void_caster::self_register()
{
// from/to pairs are registered when created
// and there should only be one instance of each pair
if(! global_registry().m_set.insert(this).second)
assert(false);
}
} // void_cast_detail
// Given a void *, assume that it really points to an instance of one type
// and alter it so that it would point to an instance of a related type.
// Return the altered pointer. If there exists no sequence of casts that
// can transform from_type to to_type, return a NULL.
const void *
void_upcast(
const extended_type_info & derived_type,
const extended_type_info & base_type,
const void * t,
bool top
){
// same types - trivial case
if (derived_type == base_type)
return t;
// check to see if base/derived pair is found in the registry
void_cast_detail::void_caster ca(derived_type, base_type );
void_cast_detail::void_caster_registry::iterator it;
it = void_cast_detail::global_registry().m_set.find( &ca );
// if so
if (it != void_cast_detail::global_registry().m_set.end())
// we're done
return (*it)->upcast(t);
const void * t_new = NULL;
// try to find a chain that gives us what we want
for(
it = void_cast_detail::global_registry().m_set.begin();
it != void_cast_detail::global_registry().m_set.end();
++it
){
// if the current candidate doesn't cast to the desired target type
if ((*it)->m_base_type == base_type){
// if the current candidate casts from the desired source type
if ((*it)->m_derived_type == derived_type){
// we have a base/derived match - we're done
// cast to the intermediate type
t_new = (*it)->upcast(t);
break;
}
t_new = void_upcast(derived_type, (*it)->m_derived_type, t, false);
if (NULL != t_new){
t_new = (*it)->upcast(t_new);
if(top){
// register the this pair so we will have to go through
// keep this expensive search process more than once.
new void_cast_detail::void_caster_derived(
derived_type,
base_type,
static_cast<const char*>(t_new) - static_cast<const char*>(t)
);
}
break;
}
}
}
return t_new;
}
const void *
void_downcast(
const extended_type_info & derived_type,
const extended_type_info & base_type,
const void * t,
bool top
){
// same types - trivial case
if (derived_type == base_type)
return t;
// check to see if base/derived pair is found in the registry
void_cast_detail::void_caster ca(derived_type, base_type );
void_cast_detail::void_caster_registry::iterator it;
it = void_cast_detail::global_registry().m_set.find( &ca );
// if so
if (it != void_cast_detail::global_registry().m_set.end())
// we're done
return (*it)->downcast(t);
const void * t_new = NULL;
// try to find a chain that gives us what we want
for(
it = void_cast_detail::global_registry().m_set.begin();
it != void_cast_detail::global_registry().m_set.end();
++it
){
// if the current candidate doesn't cast from the desired target type
if ((*it)->m_base_type == base_type){
// if the current candidate casts to the desired source type
if ((*it)->m_derived_type == derived_type){
// we have a base/derived match - we're done
// cast to the intermediate type
t_new = (*it)->downcast(t);
break;
}
t_new = void_downcast(derived_type, (*it)->m_derived_type, t, false);
if (NULL != t_new){
t_new = (*it)->downcast(t_new);
if(top){
// register the this pair so we will have to go through
// keep this expensive search process more than once.
new void_cast_detail::void_caster_derived(
derived_type,
base_type,
static_cast<const char*>(t) - static_cast<const char*>(t_new)
);
}
break;
}
}
}
return t_new;
}
} // namespace serialization
} // namespace boost
// EOF

454
src/xbasic_iarchive.cpp Normal file
View File

@@ -0,0 +1,454 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_archive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc 6.0 needs this to suppress warnings
#include <cassert>
#include <set>
#include <list>
#include <vector>
#include <boost/limits.hpp>
#include <boost/state_saver.hpp>
#include <boost/throw_exception.hpp>
#include <boost/archive/detail/basic_iserializer.hpp>
#include <boost/archive/detail/basic_pointer_iserializer.hpp>
#include <boost/archive/detail/basic_iarchive.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/archive/archive_exception.hpp>
using namespace boost::serialization;
namespace boost {
namespace archive {
namespace detail {
class basic_iarchive_impl
{
friend class basic_iarchive;
//////////////////////////////////////////////////////////////////////
// information about each serialized object loaded
// indexed on object_id
struct aobject
{
void * address;
class_id_type class_id;
aobject(
void *a,
class_id_type class_id_
) :
address(a),
class_id(class_id_)
{}
aobject() : address(NULL), class_id(-2) {}
};
typedef std::vector<aobject> object_id_vector_type;
object_id_vector_type object_id_vector;
//////////////////////////////////////////////////////////////////////
// used by load object to look up class id given basic_serializer
class cobject_type
{
private:
friend class basic_iarchive;
const basic_iserializer * bis;
public:
const class_id_type class_id;
cobject_type(
size_t class_id_,
const basic_iserializer & bis_
) :
bis(& bis_),
class_id(class_id_)
{}
cobject_type(const cobject_type & rhs) :
bis(rhs.bis),
class_id(rhs.class_id)
{}
// the following cannot be defined because of the const
// member. This will generate a link error if an attempt
// is made to assign. This should never be necessary
cobject_type & operator=(const cobject_type & rhs);
bool operator<(const cobject_type &rhs) const
{
return *bis < *(rhs.bis);
}
};
typedef std::set<cobject_type> cobject_info_set_type;
cobject_info_set_type cobject_info_set;
//////////////////////////////////////////////////////////////////////
// information about each serialized class indexed on class_id
class cobject_id
{
public:
cobject_id & operator=(const cobject_id & rhs){
bis_ptr = rhs.bis_ptr;
bpis_ptr = rhs.bpis_ptr;
file_version = rhs.file_version;
tracking_level = rhs.tracking_level;
initialized = rhs.initialized;
return *this;
}
const basic_iserializer * bis_ptr;
// const basic_pointer_iserializer * bpis_ptr;
version_type file_version;
tracking_type tracking_level;
bool initialized;
cobject_id(const basic_iserializer & bis_) :
bis_ptr(& bis_),
// bpis_ptr(NULL),
file_version(0),
tracking_level(track_never),
initialized(false)
{}
cobject_id(const cobject_id &rhs):
bis_ptr(rhs.bis_ptr),
// bpis_ptr(rhs.bpis_ptr),
file_version(rhs.file_version),
tracking_level(rhs.tracking_level),
initialized(rhs.initialized)
{}
};
typedef std::vector<cobject_id> cobject_id_vector_type;
cobject_id_vector_type cobject_id_vector;
// list of objects created by de-serialization. Used to implement
// clean up after exceptions.
class created_pointer_type
{
public:
created_pointer_type(
class_id_type class_id_,
void * address_
) :
class_id(class_id_),
address(address_)
{}
created_pointer_type(const created_pointer_type &rhs) :
class_id(rhs.class_id),
address(rhs.address)
{}
created_pointer_type & operator=(const created_pointer_type &){
assert(false);
return *this;
}
void * get_address() const {
return address;
}
// object to which this item refers
const class_id_type class_id;
private:
void * address;
};
std::list<created_pointer_type> created_pointers;
bool is_object; // pass forward indicater that we're saving an object
// directly rather than result of a pointer
basic_iarchive_impl()
: is_object(true)
{}
bool
track(
basic_iarchive & ar,
void * & t
);
void
load_preamble(
basic_iarchive & ar,
cobject_id & co,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type_
) = NULL
);
class_id_type register_type(
const basic_iserializer & bis
);
// redirect through virtual functions to load functions for this archive
template<class T>
void load(basic_iarchive & ar, T & t){
ar.vload(t);
}
public:
void delete_created_pointers();
class_id_type register_type(
const basic_pointer_iserializer & bpis
);
void load_object(
basic_iarchive & ar,
void * & t,
const basic_iserializer & bis
);
const basic_pointer_iserializer * load_pointer(
basic_iarchive & ar,
void * & t,
const basic_pointer_iserializer * bpis,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type
)
);
};
inline void
basic_iarchive_impl::delete_created_pointers()
{
while(created_pointers.size() > 0){
const created_pointer_type & cp = created_pointers.front();
// figure out the class of the object to be deleted
// note: extra line used to evand 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
){
cobject_type co(cobject_info_set.size(), 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());
}
return result.first->class_id;
}
inline class_id_type
basic_iarchive_impl::register_type(
const basic_pointer_iserializer & bpis
){
const basic_iserializer & bis = bpis.get_basic_serializer();
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];
co.bpis_ptr = & bpis;
return cid;
}
void
basic_iarchive_impl::load_preamble(
basic_iarchive & ar,
cobject_id & co,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type_
)
){
if(! co.initialized){
const basic_iserializer & bis = * co.bis_ptr;
if(NULL == co.bpis_ptr){
if(bis.serialized_as_pointer()){
// 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)
);
co.bpis_ptr = (*finder)(*eti);
}
}
if(bis.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 = bis.tracking();
co.file_version = version_type(bis.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
){
bool result = true;
const class_id_type cid = register_type(bis);
// note: extra line used to evand borland issue
const int id = cid;
cobject_id & co = cobject_id_vector[id];
if(is_object){
load_preamble(ar, co);
// note: extra line used to evand borland issue
const bool b = co.tracking_level;
if(b){
result = track(ar, t);
if(! result)
return;
object_id_vector.push_back(aobject(t, cid));
}
}
// read data if required
state_saver<bool> x(is_object);
is_object = true;
(bis.load_object_data)(ar, t, co.file_version);
}
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){
class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer());
assert(new_cid == cid);
}
// borland won't find class_id_type->int->unsigned int so use a cast
int icid = cid;
cobject_id & co = cobject_id_vector[icid];
load_preamble(ar, co, finder);
bool new_object = true;
// extra line to evade borland issue
const bool b = co.tracking_level;
if(b)
new_object = track(ar, t);
// we update this because its going to be returned and it has to
// reflect that TRUE type recovered rather than the base type
bpis_ptr = co.bpis_ptr;
// if required
if(new_object){
// read data
state_saver<bool> x(is_object);
is_object = false;
if(co.bis_ptr->tracking()){
// predict next object id to be created
const unsigned int i = object_id_vector.size();
// because the following operation could move the items
// don't use co after this
object_id_vector.push_back(aobject(t, cid));
bpis_ptr->load_object_ptr(
ar,
object_id_vector[i].address,
co.file_version
);
t = object_id_vector[i].address;
// and add to list of created pointers
created_pointers.push_back(created_pointer_type(cid, t));
}
else{
bpis_ptr->load_object_ptr(ar, t, co.file_version);
}
assert(NULL != t);
}
return bpis_ptr;
}
//////////////////////////////////////////////////////////////////////
// implementation of basic_iarchive functions
basic_iarchive::basic_iarchive() :
pimpl(new basic_iarchive_impl),
archive_library_version(ARCHIVE_VERSION)
{}
basic_iarchive::~basic_iarchive()
{
delete pimpl;
}
void basic_iarchive::delete_created_pointers()
{
pimpl->delete_created_pointers();
}
void basic_iarchive::register_pointer_iserializer(
const basic_pointer_iserializer & bpis
){
pimpl->register_type(bpis);
}
void basic_iarchive::load_object(
void *t,
const basic_iserializer &bis
){
pimpl->load_object(*this, t, bis);
}
// load a pointer object
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);
}
} // namespace detail
} // namespace archive
} // namespace boost

391
src/xbasic_oarchive.cpp Normal file
View File

@@ -0,0 +1,391 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
#include <cassert>
#include <set>
#include <boost/limits.hpp>
#include <boost/state_saver.hpp>
#include <boost/throw_exception.hpp>
// including this here to work around an ICC in intel 7.0
// normally this would be part of basic_oarchive.hpp below.
#include <boost/archive/basic_archive.hpp>
#include <boost/archive/detail/basic_oserializer.hpp>
#include <boost/archive/detail/basic_pointer_oserializer.hpp>
#include <boost/archive/detail/basic_oarchive.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <boost/archive/archive_exception.hpp>
using namespace boost::serialization;
namespace boost {
namespace archive {
namespace detail {
class basic_oarchive_impl
{
friend class basic_oarchive;
//////////////////////////////////////////////////////////////////////
// information about each serialized object saved
// keyed on address, class_id
struct aobject
{
const void * address;
class_id_type class_id;
object_id_type object_id;
bool operator<(const aobject &rhs) const
{
assert(NULL != address);
assert(NULL != rhs.address);
if( address < rhs.address )
return true;
if( address > rhs.address )
return false;
return class_id < rhs.class_id;
}
aobject & operator=(const aobject & rhs)
{
address = rhs.address;
class_id = rhs.class_id;
object_id = rhs.object_id;
return *this;
}
aobject(
const void *a,
class_id_type class_id_,
object_id_type object_id_
) :
address(a),
class_id(class_id_),
object_id(object_id_)
{}
aobject() : address(NULL){}
};
// keyed on class_id, address
typedef std::set<aobject> object_set_type;
object_set_type object_set;
//////////////////////////////////////////////////////////////////////
// information about each serialized class saved
// keyed on type_info
struct cobject_type
{
const basic_oserializer * bos_ptr;
const class_id_type class_id;
bool initialized;
cobject_type(
size_t class_id_,
const basic_oserializer & bos_
) :
bos_ptr(& bos_),
class_id(class_id_),
initialized(false)
{}
cobject_type(const basic_oserializer & bos_)
: bos_ptr(& bos_)
{}
cobject_type(
const cobject_type & rhs
) :
bos_ptr(rhs.bos_ptr),
class_id(rhs.class_id),
initialized(rhs.initialized)
{}
// the following cannot be defined because of the const
// member. This will generate a link error if an attempt
// is made to assign. This should never be necessary
// use this only for lookup argument
cobject_type & operator=(const cobject_type &rhs);
bool operator<(const cobject_type &rhs) const {
return *bos_ptr < *(rhs.bos_ptr);
}
};
// keyed on type_info
typedef std::set<cobject_type> cobject_info_set_type;
cobject_info_set_type cobject_info_set;
// list of objects initially stored as pointers - used to detect errors
// keyed on object id
std::set<object_id_type> stored_pointers;
bool is_object; // pass forward indicater that we're saving an object
// directly rather than result of a pointer
basic_oarchive_impl()
: is_object(true)
{}
const cobject_type &
find(const basic_oserializer & bos);
const basic_oserializer *
find(const serialization::extended_type_info &ti) const;
void
save_preamble(
basic_oarchive & ar,
cobject_type & co
);
bool
track(
basic_oarchive & ar,
const void *t,
const class_id_type cid,
bool is_object
);
public:
cobject_type &
register_type(const basic_oserializer & bos);
void save_object(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos
);
void save_pointer(
basic_oarchive & ar,
const void * t,
const basic_pointer_oserializer & bpos
);
};
//////////////////////////////////////////////////////////////////////
// implementation of basic_oarchive implementation functions
// given a type_info - find its bos
// return NULL if not found
inline const basic_oserializer *
basic_oarchive_impl::find(const serialization::extended_type_info & ti) const {
class bosarg : public boost::archive::detail::basic_oserializer
{
bool class_info() const {
assert(false);
return false;
}
// returns true if objects should be tracked
bool tracking() const {
assert(false);
return false;
}
// returns class version
unsigned int version() const {
assert(false);
return 0;
}
// returns true if this class is polymorphic
bool is_polymorphic() const{
assert(false);
return false;
}
void save_object_data(
basic_oarchive & ar, const void * x
) const {
assert(false);
}
public:
bosarg(const serialization::extended_type_info & type_) :
boost::archive::detail::basic_oserializer(type_)
{}
};
bosarg bos(ti);
cobject_info_set_type::const_iterator cit
= cobject_info_set.find(cobject_type(bos));
// it should already have been "registered" - see below
if(cit == cobject_info_set.end()){
// if an entry is not found in the table it is because a pointer
// of a derived class has been serialized through its base class
// but the derived class hasn't been "registered"
return NULL;
}
// return pointer to the real class
return cit->bos_ptr;
}
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 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 const_cast<cobject_type &>(*(result.first));
}
void
basic_oarchive_impl::save_preamble(
basic_oarchive & ar,
cobject_type & co
){
if(! co.initialized){
if(is_object)
ar.vsave(class_id_optional_type(co.class_id));
else
ar.vsave(co.class_id);
const basic_oserializer & bos = * co.bos_ptr;
if(bos.serialized_as_pointer
&& bos.is_polymorphic()){
if(bos.is_polymorphic()){
const serialization::extended_type_info *eti = & bos.type;
const char * key = NULL;
if(NULL != eti)
key = eti->key;
if(NULL != key)
// write out the external class identifier
ar.vsave(class_name_type(key));
else
// without an external class name
// we won't be able to de-serialize it so bail now
boost::throw_exception(
archive_exception(archive_exception::unregistered_class)
);
}
}
if(bos.class_info()){
ar.vsave(tracking_type(bos.tracking()));
ar.vsave(version_type(bos.version()));
}
(const_cast<cobject_type &>(co)).initialized = true;
}
else{
ar.vsave(class_id_reference_type(co.class_id));
}
ar.end_preamble();
}
// return true if this is a new object and should be serialized
// false if it can be skipped.
bool
basic_oarchive_impl::track(
basic_oarchive & ar,
const void *t,
const class_id_type cid,
bool is_object
){
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, cid, oid);
std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool>
aresult = object_set.insert(ao);
oid = aresult.first->object_id;
// if its aready there
if(! aresult.second){
ar.vsave(object_reference_type(oid));
// and its an object
if(is_object
// but it was originally stored through a pointer
&& stored_pointers.end() != stored_pointers.find(oid)){
// this has to be a user error. loading such an archive
// would create duplicate objects
boost::throw_exception(
archive_exception(archive_exception::pointer_conflict)
);
}
return false;
}
ar.vsave(oid);
if(! is_object)
// add to the set of object initially stored through pointers
stored_pointers.insert(oid);
return true;
}
inline void
basic_oarchive_impl::save_object(
basic_oarchive & ar,
const void *t,
const basic_oserializer & bos
){
bool new_object = true;
if(is_object){
cobject_type & co = register_type(bos);
save_preamble(ar, co);
if(bos.tracking())
new_object = track(ar, t, co.class_id, true);
ar.end_preamble();
}
if(new_object){
state_saver<bool> x(is_object);
is_object = true;
(bos.save_object_data)(ar, t);
}
}
// 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
){
const basic_oserializer & bos = bpos.get_basic_serializer();
unsigned int original_count = cobject_info_set.size();
cobject_type & co = register_type(bos);
is_object = false;
save_preamble(ar, co);
bool new_object = true;
if(bos.tracking())
new_object = track(ar, t, co.class_id, false);
if(new_object){
state_saver<bool> x(is_object);
bpos.save_object_ptr(ar, t);
}
}
//////////////////////////////////////////////////////////////////////
// implementation of basic_oarchive functions
basic_oarchive::basic_oarchive()
: pimpl(new basic_oarchive_impl)
{}
basic_oarchive::~basic_oarchive()
{
delete pimpl;
}
void basic_oarchive::register_pointer_oserializer(
const basic_pointer_oserializer & bosp
){
pimpl->register_type(bosp.get_basic_serializer());
}
void basic_oarchive::save_object(
const void *x,
const basic_oserializer & bos
){
pimpl->save_object(*this, x, bos);
}
void basic_oarchive::save_pointer(
const void * t,
const basic_pointer_oserializer & bpos
){
pimpl->save_pointer(*this, t, bpos);
}
} // namespace detail
} // namespace archive
} // namespace boost

71
src/xml_grammar.cpp Normal file
View File

@@ -0,0 +1,71 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_grammar.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <boost/archive/impl/basic_xml_grammar.hpp>
using namespace boost::spirit;
#include <boost/config.hpp>
// fixup for borland
// The following code will be put into Boost.Config in a later revision
#if defined(_RWSTD_VER) && ! defined(__SGI_STL_PORT)
#include <string>
namespace std {
template<>
inline string &
string::replace (
char * first1,
char * last1,
const char * first2,
const char * last2
){
replace(first1-begin(),last1-first1,first2,last2-first2,0,last2-first2);
return *this;
}
} // namespace std
#endif
namespace boost {
namespace archive {
typedef basic_xml_grammar<char> xml_grammar;
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// specific definitions for char based XML
template<>
void xml_grammar::init_chset(){
Char = chset_t("\x9\xA\xD\x20-\xFF");
Letter = chset_t("\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF");
Digit = chset_t("0-9");
Extender = chset_t('\xB7');
Sch = chset_t("\x20\x9\xD\xA");
NameChar = Letter | Digit | chset_p("._:-") | Extender ;
}
} // namespace archive
} // namespace boost
#include "basic_xml_grammar.ipp"
namespace boost {
namespace archive {
// explicit instantiation of xml for 8 bit characters
template class basic_xml_grammar<char>;
} // namespace archive
} // namespace boost

45
src/xml_iarchive.cpp Normal file
View File

@@ -0,0 +1,45 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_iarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <istream>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// the following works around an issue between spirit 1.61 and borland.
// it turns out the the certain spirit stuff must be defined before
// certain parts of mpl. including this here makes sure that happens
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564 )
#include <boost/archive/impl/basic_xml_grammar.hpp>
#endif
#include <boost/archive/xml_iarchive.hpp>
// explicitly instantiate for this type of xml stream
#include <boost/archive/impl/basic_text_iprimitive.ipp>
#include <boost/archive/impl/basic_xml_iarchive.ipp>
#include <boost/archive/impl/xml_iarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_iprimitive<std::istream> ;
template class basic_xml_iarchive<xml_iarchive> ;
template class xml_iarchive_impl<xml_iarchive> ;
template class detail::archive_pointer_iserializer<xml_iarchive> ;
} // namespace archive
} // namespace boost

34
src/xml_oarchive.cpp Normal file
View File

@@ -0,0 +1,34 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_oarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
#include <ostream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/impl/basic_text_oprimitive.ipp>
#include <boost/archive/impl/basic_xml_oarchive.ipp>
#include <boost/archive/impl/xml_oarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of xml stream
template class basic_text_oprimitive<std::ostream> ;
template class basic_xml_oarchive<xml_oarchive> ;
template class xml_oarchive_impl<xml_oarchive> ;
template class detail::archive_pointer_oserializer<xml_oarchive> ;
} // namespace archive
} // namespace boost

253
src/xml_wgrammar.cpp Normal file
View File

@@ -0,0 +1,253 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_wgrammar.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <boost/archive/impl/basic_xml_grammar.hpp>
using namespace boost::spirit;
// fixup for RogueWave
#include <boost/config.hpp>
#if defined(_RWSTD_VER) && ! defined(__SGI_STL_PORT)
#include <string>
namespace std {
template<>
inline wstring &
wstring::replace (
wchar_t * first1,
wchar_t * last1,
const wchar_t * first2,
const wchar_t * last2
){
replace(first1-begin(),last1-first1,first2,last2-first2,0,last2-first2);
return *this;
}
} // namespace std
#endif
namespace boost {
namespace archive {
typedef basic_xml_grammar<wchar_t> xml_wgrammar;
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// specific definitions for wchar_t based XML
#if 0
template<>
const xml_wgrammar::chset_t xml_wgrammar::
#if defined(__GNUC__) && defined(linux)
Char(L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD\x10000-\x10FFFF");
#else
Char(L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD");
#endif
template<>
const xml_wgrammar::chset_t xml_wgrammar::Sch(L"\x20\x9\xD\xA");
template<>
const xml_wgrammar::chset_t xml_wgrammar::BaseChar (
L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E"
L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217"
L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE"
L"\x3D0-\x3D6\x3DA\x3DC\x3DE\x3E0\x3E2-\x3F3\x401-\x40C\x40E-\x44F"
L"\x451-\x45C\x45E-\x481\x490-\x4C4\x4C7-\x4C8\x4CB-\x4CC\x4D0-\x4EB"
L"\x4EE-\x4F5\x4F8-\x4F9\x531-\x556\x559\x561-\x586\x5D0-\x5EA"
L"\x5F0-\x5F2\x621-\x63A\x641-\x64A\x671-\x6B7\x6BA-\x6BE\x6C0-\x6CE"
L"\x6D0-\x6D3\x6D5\x6E5-\x6E6\x905-\x939\x93D\x958-\x961\x985-\x98C"
L"\x98F-\x990\x993-\x9A8\x9AA-\x9B0\x9B2\x9B6-\x9B9\x9DC-\x9DD"
L"\x9DF-\x9E1\x9F0-\x9F1\xA05-\xA0A\xA0F-\xA10\xA13-\xA28\xA2A-\xA30"
L"\xA32-\xA33\xA35-\xA36\xA38-\xA39\xA59-\xA5C\xA5E\xA72-\xA74"
L"\xA85-\xA8B\xA8D\xA8F-\xA91\xA93-\xAA8\xAAA-\xAB0\xAB2-\xAB3"
L"\xAB5-\xAB9\xABD\xAE0\xB05-\xB0C\xB0F-\xB10\xB13-\xB28\xB2A-\xB30"
L"\xB32-\xB33\xB36-\xB39\xB3D\xB5C-\xB5D\xB5F-\xB61\xB85-\xB8A"
L"\xB8E-\xB90\xB92-\xB95\xB99-\xB9A\xB9C\xB9E-\xB9F\xBA3-\xBA4"
L"\xBA8-\xBAA\xBAE-\xBB5\xBB7-\xBB9\xC05-\xC0C\xC0E-\xC10\xC12-\xC28"
L"\xC2A-\xC33\xC35-\xC39\xC60-\xC61\xC85-\xC8C\xC8E-\xC90\xC92-\xCA8"
L"\xCAA-\xCB3\xCB5-\xCB9\xCDE\xCE0-\xCE1\xD05-\xD0C\xD0E-\xD10"
L"\xD12-\xD28\xD2A-\xD39\xD60-\xD61\xE01-\xE2E\xE30\xE32-\xE33"
L"\xE40-\xE45\xE81-\xE82\xE84\xE87-\xE88\xE8A\xE8D\xE94-\xE97"
L"\xE99-\xE9F\xEA1-\xEA3\xEA5\xEA7\xEAA-\xEAB\xEAD-\xEAE\xEB0"
L"\xEB2-\xEB3\xEBD\xEC0-\xEC4\xF40-\xF47\xF49-\xF69\x10A0-\x10C5"
L"\x10D0-\x10F6\x1100\x1102-\x1103\x1105-\x1107\x1109\x110B-\x110C"
L"\x110E-\x1112\x113C\x113E\x1140\x114C\x114E\x1150\x1154-\x1155"
L"\x1159\x115F-\x1161\x1163\x1165\x1167\x1169\x116D-\x116E"
L"\x1172-\x1173\x1175\x119E\x11A8\x11AB\x11AE-\x11AF\x11B7-\x11B8"
L"\x11BA\x11BC-\x11C2\x11EB\x11F0\x11F9\x1E00-\x1E9B\x1EA0-\x1EF9"
L"\x1F00-\x1F15\x1F18-\x1F1D\x1F20-\x1F45\x1F48-\x1F4D\x1F50-\x1F57"
L"\x1F59\x1F5B\x1F5D\x1F5F-\x1F7D\x1F80-\x1FB4\x1FB6-\x1FBC\x1FBE"
L"\x1FC2-\x1FC4\x1FC6-\x1FCC\x1FD0-\x1FD3\x1FD6-\x1FDB\x1FE0-\x1FEC"
L"\x1FF2-\x1FF4\x1FF6-\x1FFC\x2126\x212A-\x212B\x212E\x2180-\x2182"
L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3");
template<>
const xml_wgrammar::chset_t xml_wgrammar::Ideographic(
L"\x4E00-\x9FA5\x3007\x3021-\x3029");
template<>
const xml_wgrammar::chset_t xml_wgrammar::Letter = BaseChar | Ideographic;
template<>
const xml_wgrammar::chset_t xml_wgrammar::CombiningChar(
L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9"
L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670"
L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED"
L"\x0901-\x0903\x093C\x093E-\x094C\x094D\x0951-\x0954\x0962-\x0963"
L"\x0981-\x0983\x09BC\x09BE\x09BF\x09C0-\x09C4\x09C7-\x09C8"
L"\x09CB-\x09CD\x09D7\x09E2-\x09E3\x0A02\x0A3C\x0A3E\x0A3F"
L"\x0A40-\x0A42\x0A47-\x0A48\x0A4B-\x0A4D\x0A70-\x0A71\x0A81-\x0A83"
L"\x0ABC\x0ABE-\x0AC5\x0AC7-\x0AC9\x0ACB-\x0ACD\x0B01-\x0B03\x0B3C"
L"\x0B3E-\x0B43\x0B47-\x0B48\x0B4B-\x0B4D\x0B56-\x0B57\x0B82-\x0B83"
L"\x0BBE-\x0BC2\x0BC6-\x0BC8\x0BCA-\x0BCD\x0BD7\x0C01-\x0C03"
L"\x0C3E-\x0C44\x0C46-\x0C48\x0C4A-\x0C4D\x0C55-\x0C56\x0C82-\x0C83"
L"\x0CBE-\x0CC4\x0CC6-\x0CC8\x0CCA-\x0CCD\x0CD5-\x0CD6\x0D02-\x0D03"
L"\x0D3E-\x0D43\x0D46-\x0D48\x0D4A-\x0D4D\x0D57\x0E31\x0E34-\x0E3A"
L"\x0E47-\x0E4E\x0EB1\x0EB4-\x0EB9\x0EBB-\x0EBC\x0EC8-\x0ECD"
L"\x0F18-\x0F19\x0F35\x0F37\x0F39\x0F3E\x0F3F\x0F71-\x0F84"
L"\x0F86-\x0F8B\x0F90-\x0F95\x0F97\x0F99-\x0FAD\x0FB1-\x0FB7\x0FB9"
L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A");
template<>
const xml_wgrammar::chset_t xml_wgrammar::Digit(
L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF"
L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F"
L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29");
template<>
const xml_wgrammar::chset_t xml_wgrammar::Extender(
L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035"
L"\x309D-\x309E\x30FC-\x30FE");
template<>
const xml_wgrammar::chset_t xml_wgrammar::NameChar =
Letter
| Digit
| L'.'
| L'-'
| L'_'
| L':'
| CombiningChar
| Extender;
#endif
template<>
void xml_wgrammar::init_chset(){
Char = chset_t(
#if defined(__GNUC__) && defined(linux)
L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD\x10000-\x10FFFF"
#else
L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD"
#endif
);
Sch = chset_t(L"\x20\x9\xD\xA");
BaseChar = chset_t(
L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E"
L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217"
L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE"
L"\x3D0-\x3D6\x3DA\x3DC\x3DE\x3E0\x3E2-\x3F3\x401-\x40C\x40E-\x44F"
L"\x451-\x45C\x45E-\x481\x490-\x4C4\x4C7-\x4C8\x4CB-\x4CC\x4D0-\x4EB"
L"\x4EE-\x4F5\x4F8-\x4F9\x531-\x556\x559\x561-\x586\x5D0-\x5EA"
L"\x5F0-\x5F2\x621-\x63A\x641-\x64A\x671-\x6B7\x6BA-\x6BE\x6C0-\x6CE"
L"\x6D0-\x6D3\x6D5\x6E5-\x6E6\x905-\x939\x93D\x958-\x961\x985-\x98C"
L"\x98F-\x990\x993-\x9A8\x9AA-\x9B0\x9B2\x9B6-\x9B9\x9DC-\x9DD"
L"\x9DF-\x9E1\x9F0-\x9F1\xA05-\xA0A\xA0F-\xA10\xA13-\xA28\xA2A-\xA30"
L"\xA32-\xA33\xA35-\xA36\xA38-\xA39\xA59-\xA5C\xA5E\xA72-\xA74"
L"\xA85-\xA8B\xA8D\xA8F-\xA91\xA93-\xAA8\xAAA-\xAB0\xAB2-\xAB3"
L"\xAB5-\xAB9\xABD\xAE0\xB05-\xB0C\xB0F-\xB10\xB13-\xB28\xB2A-\xB30"
L"\xB32-\xB33\xB36-\xB39\xB3D\xB5C-\xB5D\xB5F-\xB61\xB85-\xB8A"
L"\xB8E-\xB90\xB92-\xB95\xB99-\xB9A\xB9C\xB9E-\xB9F\xBA3-\xBA4"
L"\xBA8-\xBAA\xBAE-\xBB5\xBB7-\xBB9\xC05-\xC0C\xC0E-\xC10\xC12-\xC28"
L"\xC2A-\xC33\xC35-\xC39\xC60-\xC61\xC85-\xC8C\xC8E-\xC90\xC92-\xCA8"
L"\xCAA-\xCB3\xCB5-\xCB9\xCDE\xCE0-\xCE1\xD05-\xD0C\xD0E-\xD10"
L"\xD12-\xD28\xD2A-\xD39\xD60-\xD61\xE01-\xE2E\xE30\xE32-\xE33"
L"\xE40-\xE45\xE81-\xE82\xE84\xE87-\xE88\xE8A\xE8D\xE94-\xE97"
L"\xE99-\xE9F\xEA1-\xEA3\xEA5\xEA7\xEAA-\xEAB\xEAD-\xEAE\xEB0"
L"\xEB2-\xEB3\xEBD\xEC0-\xEC4\xF40-\xF47\xF49-\xF69\x10A0-\x10C5"
L"\x10D0-\x10F6\x1100\x1102-\x1103\x1105-\x1107\x1109\x110B-\x110C"
L"\x110E-\x1112\x113C\x113E\x1140\x114C\x114E\x1150\x1154-\x1155"
L"\x1159\x115F-\x1161\x1163\x1165\x1167\x1169\x116D-\x116E"
L"\x1172-\x1173\x1175\x119E\x11A8\x11AB\x11AE-\x11AF\x11B7-\x11B8"
L"\x11BA\x11BC-\x11C2\x11EB\x11F0\x11F9\x1E00-\x1E9B\x1EA0-\x1EF9"
L"\x1F00-\x1F15\x1F18-\x1F1D\x1F20-\x1F45\x1F48-\x1F4D\x1F50-\x1F57"
L"\x1F59\x1F5B\x1F5D\x1F5F-\x1F7D\x1F80-\x1FB4\x1FB6-\x1FBC\x1FBE"
L"\x1FC2-\x1FC4\x1FC6-\x1FCC\x1FD0-\x1FD3\x1FD6-\x1FDB\x1FE0-\x1FEC"
L"\x1FF2-\x1FF4\x1FF6-\x1FFC\x2126\x212A-\x212B\x212E\x2180-\x2182"
L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3"
);
Ideographic = chset_t(L"\x4E00-\x9FA5\x3007\x3021-\x3029");
Letter = BaseChar | Ideographic;
CombiningChar = chset_t(
L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9"
L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670"
L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED"
L"\x0901-\x0903\x093C\x093E-\x094C\x094D\x0951-\x0954\x0962-\x0963"
L"\x0981-\x0983\x09BC\x09BE\x09BF\x09C0-\x09C4\x09C7-\x09C8"
L"\x09CB-\x09CD\x09D7\x09E2-\x09E3\x0A02\x0A3C\x0A3E\x0A3F"
L"\x0A40-\x0A42\x0A47-\x0A48\x0A4B-\x0A4D\x0A70-\x0A71\x0A81-\x0A83"
L"\x0ABC\x0ABE-\x0AC5\x0AC7-\x0AC9\x0ACB-\x0ACD\x0B01-\x0B03\x0B3C"
L"\x0B3E-\x0B43\x0B47-\x0B48\x0B4B-\x0B4D\x0B56-\x0B57\x0B82-\x0B83"
L"\x0BBE-\x0BC2\x0BC6-\x0BC8\x0BCA-\x0BCD\x0BD7\x0C01-\x0C03"
L"\x0C3E-\x0C44\x0C46-\x0C48\x0C4A-\x0C4D\x0C55-\x0C56\x0C82-\x0C83"
L"\x0CBE-\x0CC4\x0CC6-\x0CC8\x0CCA-\x0CCD\x0CD5-\x0CD6\x0D02-\x0D03"
L"\x0D3E-\x0D43\x0D46-\x0D48\x0D4A-\x0D4D\x0D57\x0E31\x0E34-\x0E3A"
L"\x0E47-\x0E4E\x0EB1\x0EB4-\x0EB9\x0EBB-\x0EBC\x0EC8-\x0ECD"
L"\x0F18-\x0F19\x0F35\x0F37\x0F39\x0F3E\x0F3F\x0F71-\x0F84"
L"\x0F86-\x0F8B\x0F90-\x0F95\x0F97\x0F99-\x0FAD\x0FB1-\x0FB7\x0FB9"
L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A"
);
Digit = chset_t(
L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF"
L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F"
L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29"
);
Extender = chset_t(
L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035"
L"\x309D-\x309E\x30FC-\x30FE"
);
NameChar =
Letter
| Digit
| L'.'
| L'-'
| L'_'
| L':'
| CombiningChar
| Extender
;
}
} // namespace archive
} // namespace boost
#include "basic_xml_grammar.ipp"
namespace boost {
namespace archive {
// explicit instantiation of xml for wide characters
template class basic_xml_grammar<wchar_t>;
} // namespace archive
} // namespace boost
#endif

49
src/xml_wiarchive.cpp Normal file
View File

@@ -0,0 +1,49 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_wiarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <istream>
#include <boost/detail/workaround.hpp>
#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif
// the following works around an issue between spirit 1.61 and borland.
// it turns out the the certain spirit stuff must be defined before
// certain parts of mpl. including this here makes sure that happens
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564 )
#include <boost/archive/impl/basic_xml_grammar.hpp>
#endif
#include <boost/archive/xml_wiarchive.hpp>
// explicitly instantiate for this type of xml stream
#include <boost/archive/impl/basic_text_iprimitive.ipp>
#include <boost/archive/impl/basic_xml_iarchive.ipp>
#include <boost/archive/impl/xml_wiarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
namespace boost {
namespace archive {
template class basic_text_iprimitive<std::wistream> ;
template class basic_xml_iarchive<xml_wiarchive> ;
template class xml_wiarchive_impl<xml_wiarchive> ;
template class detail::archive_pointer_iserializer<xml_wiarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF

36
src/xml_woarchive.cpp Normal file
View File

@@ -0,0 +1,36 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// xml_woarchive.cpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
BOOST_STATIC_ASSERT(false);
#else
#include <ostream>
#include <boost/archive/xml_woarchive.hpp>
#include <boost/archive/impl/basic_text_oprimitive.ipp>
#include <boost/archive/impl/basic_xml_oarchive.ipp>
#include <boost/archive/impl/xml_woarchive_impl.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of xml stream
template class basic_text_oprimitive<std::wostream> ;
template class basic_xml_oarchive<xml_woarchive> ;
template class xml_woarchive_impl<xml_woarchive> ;
template class detail::archive_pointer_oserializer<xml_woarchive> ;
} // namespace archive
} // namespace boost
#endif // BOOST_NO_STD_WSTREAMBUF