mirror of
https://github.com/boostorg/serialization.git
synced 2026-01-19 04:42:10 +00:00
*** empty log message ***
[SVN r23430]
This commit is contained in:
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal 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
56
src/basic_archive.cpp
Normal 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
439
src/basic_iarchive.cpp
Normal 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
395
src/basic_oarchive.cpp
Normal 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
|
||||
51
src/basic_serializer_map.cpp
Normal file
51
src/basic_serializer_map.cpp
Normal 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
24
src/basic_xml_archive.cpp
Normal 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
26
src/binary_iarchive.cpp
Normal 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
26
src/binary_oarchive.cpp
Normal 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
35
src/binary_wiarchive.cpp
Normal 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
34
src/binary_woarchive.cpp
Normal 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
87
src/codecvt_null.cpp
Normal 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
179
src/extended_type_info.cpp
Normal 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
|
||||
21
src/extended_type_info_no_rtti.cpp
Normal file
21
src/extended_type_info_no_rtti.cpp
Normal 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
|
||||
23
src/extended_type_info_typeid.cpp
Normal file
23
src/extended_type_info_typeid.cpp
Normal 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
|
||||
28
src/polymorphic_iarchive.cpp
Normal file
28
src/polymorphic_iarchive.cpp
Normal 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
|
||||
28
src/polymorphic_oarchive.cpp
Normal file
28
src/polymorphic_oarchive.cpp
Normal 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
30
src/text_iarchive.cpp
Normal 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
32
src/text_oarchive.cpp
Normal 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
40
src/text_wiarchive.cpp
Normal 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
37
src/text_woarchive.cpp
Normal 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
344
src/utf8_codecvt_facet.cpp
Normal 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
194
src/void_cast.cpp
Normal 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
454
src/xbasic_iarchive.cpp
Normal 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
391
src/xbasic_oarchive.cpp
Normal 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
71
src/xml_grammar.cpp
Normal 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
45
src/xml_iarchive.cpp
Normal 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
34
src/xml_oarchive.cpp
Normal 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
253
src/xml_wgrammar.cpp
Normal 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
49
src/xml_wiarchive.cpp
Normal 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
36
src/xml_woarchive.cpp
Normal 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
|
||||
Reference in New Issue
Block a user