From: stephan b. <sg...@us...> - 2004-12-29 19:54:56
|
Update of /cvsroot/pclasses/pclasses2/src/SIO In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13760/src/SIO Added Files: Makefile.toc registrations.cpp S11nNode.cpp S11nNode.h SIO.cpp SIO.h Log Message: Moved SIO & S11nNode to SIO module, to a) keep deps correct, b) make the intended client-side interface clearer (hide more of s11n from it), c) ease porting of code between s11n.net and pclasses.com. --- NEW FILE: S11nNode.h --- #ifndef s11n_S11NNODE_HPP_INCLUDED #define s11n_S11NNODE_HPP_INCLUDED 1 #include <list> #include <string> #include <pclasses/Util/SimplePropertyStore.h> #include <pclasses/s11n/traits.h> #include <pclasses/s11n/data_node_serialize.h> namespace P { namespace SIO { /** The concrete "data node" type used by serialization operations. Note that it is considered poor form to use an S11nNode's API directly, as it's type and interface may change. The only guaranty the SIO API gives regarding S11nNode's API is that NodeTraits::funcname(S11nNode &...) operations will work as expected/documented. More clearly: use NodeTraits to manipulate and query nodes, not the node API directly. In fact S11nNode's useful API is all private, so you CAN'T touch it without going through NodeTraits. :) Gotcha! The API for this class is documented in P::Util::SimplePropertyStore. The conventions for it's use in s11n are defined in the s11n library manual (http://s11n.net/download/). Reminder to the source maintainer: don't just go changing this API unless you also implement or change the node_traits type to accomodate it. */ class S11nNode : public ::P::Util::SimplePropertyStore { public: typedef ::P::s11n::node_traits<S11nNode> traits_type; typedef ::P::Util::SimplePropertyStore ParentType; /** Expected by s11n algos.*/ typedef ParentType::map_type map_type; /** Expected by s11n algos.*/ typedef map_type::key_type key; /** Expected by s11n algos.*/ typedef map_type::value_type value; /** Expected by s11n algos.*/ typedef map_type::mapped_type mapped; /** Expected by s11n algos.*/ typedef map_type::iterator iterator; /** Expected by s11n algos.*/ typedef map_type::const_iterator const_iterator; /** Expected by s11n algos.*/ typedef std::list<S11nNode *> child_list_type; S11nNode(); explicit S11nNode( const std::string & name ); virtual ~S11nNode(); S11nNode( const S11nNode & ); S11nNode & operator=( const S11nNode & ); child_list_type & children(); const child_list_type & children() const; std::string name() const; void name( const std::string & n ); void class_name( const std::string & n ); std::string class_name() const; void clear(); // WTF doesn't gcc see the inherited clear() without this??? iterator S11nNode::begin(); const_iterator S11nNode::begin() const; iterator S11nNode::end(); const_iterator S11nNode::end() const; template <typename SerializableT> bool serialize( const SerializableT & src ) { return ::P::s11n::serialize<S11nNode,SerializableT>( *this, src ); } template <typename SerializableType> SerializableType * deserialize() const { return ::P::s11n::deserialize<S11nNode,SerializableType>( *this ); } template <typename DeserializableT> bool deserialize( DeserializableT & target ) const { return ::P::s11n::deserialize<S11nNode,DeserializableT>( *this, target ); } template <typename SerializableType> bool serializeSubnode( const std::string & subnodename, const SerializableType & src ) { return ::P::s11n::serialize_subnode<S11nNode,SerializableType>( *this, subnodename, src ); } template <typename DeserializableT> DeserializableT * deserializeSubnode( const std::string & subnodename ) const { return ::P::s11n::deserialize_subnode<S11nNode,DeserializableT>( *this, subnodename ); } template <typename DeserializableT> bool deserializeSubnode(const std::string & subnodename, DeserializableT & target ) const { return ::P::s11n::deserialize_subnode<S11nNode,DeserializableT>( *this, subnodename, target ); } protected: void copy( const S11nNode & rhs ); void clear_properties(); void clear_children(); std::string m_name; // name of this node std::string m_iname; // class_name name of this node child_list_type m_children; // holds child pointers }; } } // namespace P::SIO #endif // s11n_S11NNODE_HPP_INCLUDED --- NEW FILE: registrations.cpp --- //////////////////////////////////////////////////////////////////////// // This file hard-registers the Serializers available in ps11n, // until i get them fully integrated into the dynamic load system. //////////////////////////////////////////////////////////////////////// #include <pclasses/pclasses-config.h> // PCLASSES_HAVE_LIBEXPAT #include <pclasses/SIO/SIO.h> #include <pclasses/SIO/S11nNode.h> #ifdef PCLASSES_HAVE_LIBEXPAT // KLUDGE until i get S11nNode fully integrated... # include "../s11n/io/expat/expat_serializer.h" #endif # include "../s11n/io/parens/parens_serializer.h" //////////////////////////////////////////////////////////////////////// #define SIO_KEY_DEFAULT_SERIALIZER "/P/SIO/DefaultSerializerClass" /// ^^^^^^^^^^^^^ ACHTUNG: this #define is duplicated in SIO. /// Neither of these files knows about the other, though, /// so we can't refer to it here. //////////////////////////////////////////////////////////////////////// namespace P { namespace SIO { void s11n_io_init() { #define PM SerializerPluginManager::instance() #define SREG(S,N,A) \ registerSerializer< ::P::s11n::io:: S ## _serializer< S11nNode > >( N, A ); // @fixme: be more dynamic here, autoloading // libdir/pclasses/*_serializer.so. #ifdef PCLASSES_HAVE_LIBEXPAT SREG(expat,"s11n::io::expat_serializer","expat" ); PM.alias( "P::s11n::io::expat_serializer", "s11n::io::expat_serializer" ); PM.alias( SIO_KEY_DEFAULT_SERIALIZER, "expat" ); #endif SREG(parens, "s11n::io::parens_serializer", "parens" ); PM.alias( "P::s11n::io::parens_serializer", "s11n::io::parens_serializer" ); #undef SREG #undef PM } int s11n_io_init_placeholder = (s11n_io_init(),0); }} // P::SIO --- NEW FILE: SIO.h --- #ifndef p_SIO_H_INCLUDED #define p_SIO_H_INCLUDED 1 //////////////////////////////////////////////////////////////////////// // PCLASSES_SIO_INCLUDED is the "official" way for P code to know if // SIO is included yet. #define PCLASSES_SIO_INCLUDED 1 //////////////////////////////////////////////////////////////////////// // SIO.h: // Author: stephan beal <st...@s1...> // License: LGPL, copyright(c) 2004, 2005 stephan beal // // This header is intended to provide the standard P::s11n interface, // in particular the client-side interface. // // // Reminder to maintainers of this code: it is perfectly fine for this // code to depend on any P::s11n-related code, but it is NEVER // acceptable for ANY non-SIO code in the P::s11n namespace to depend // on P::SIO!!! NEVER, EVER! // (EVER! Don't even consider it!) //////////////////////////////////////////////////////////////////////// #include <string> #include <pclasses/s11n/s11n.h> #include <pclasses/s11n/io/serializers.h> #include <pclasses/Plugin/Plugin.h> #include <pclasses/SIO/S11nNode.h> namespace P { /** The SIO namespace encapsulates the entire client-side P::s11n-related API. Clients using s11n proxies and implementing serialization code may need to use the classes in P::s11n or possibly even P::s11n::io as well. SIO is a fork/port of the s11n project: http://s11n.net It was forked specifically to take advantage of the amazing super powers which the combination of P and s11n imply :). Forks are normally evil, but this fork was done by s11n's author :). SIO is mostly API-compatible with s11nlite, but uses a different data node type, so it is not 100% usage-compable. Data files/streams should be freely exchangeable between SIO and s11nlite, however, provided a compatible parser exists on both sides of the transaction (this is likely to be the case for most available Serializers, since i currently maintain both SIO and s11n :). */ namespace SIO { /** NodeTraits provide the interface for fetching and manipulating S11nNode data. */ typedef ::P::s11n::node_traits<S11nNode> NodeTraits; /** The parent type of Serializers supported by this interface. */ typedef ::P::s11n::io::data_node_serializer<S11nNode> SerializerInterface; /** A plugin manager type for loading SerializerInterface objects. */ typedef ::P::Plugin::PluginManager<SerializerInterface> SerializerPluginManager; /** See ::P::s11n::serialize(). */ template <typename SerializableT> bool serialize( S11nNode & dest, const SerializableT & src ) { return ::P::s11n::serialize<S11nNode,SerializableT>( dest, src ); } /** See ::P::s11n::derialize(). The caller owns the returned object, which may be NULL. */ template <typename SerializableType> SerializableType * deserialize( const S11nNode & src ) { return ::P::s11n::deserialize<S11nNode,SerializableType>( src ); } /** See ::P::s11n::deserialize(). */ template <typename DeserializableT> bool deserialize( const S11nNode & src, DeserializableT & target ) { return ::P::s11n::deserialize<S11nNode,DeserializableT>( src, target ); } /** See ::P::s11n::serialize_subnode(). */ template <typename SerializableType> bool serializeSubnode( S11nNode & dest, const std::string & subnodename, const SerializableType & src ) { return ::P::s11n::serialize_subnode<S11nNode,SerializableType>( dest, subnodename, src ); } /** See ::P::s11n::deserialize_subnode(). The caller owns the returned object, which may be NULL. */ template <typename DeserializableT> DeserializableT * deserializeSubnode( const S11nNode & src, const std::string & subnodename ) { return ::P::s11n::deserialize_subnode<S11nNode,DeserializableT>( src, subnodename ); } /** See ::P::s11n::deserialize_subnode(). */ template <typename DeserializableT> bool deserializeSubnode( const S11nNode & src, const std::string & subnodename, DeserializableT & target ) { return ::P::s11n::deserialize_subnode<S11nNode,DeserializableT>( src, subnodename, target ); } /** See ::P::s11n::io::load_node(). The caller owns the returned object, which may be NULL. */ S11nNode * loadNode( std::istream & src ); /** See ::P::s11n::io::load_node(src). The caller owns the returned object, which may be NULL. */ S11nNode * loadNode( const std::string & src ); /** See ::P::s11n::io::load_serializable(). */ template <typename SerializableType> SerializableType * loadSerializable( std::istream & src ) { return ::P::s11n::io::load_serializable<S11nNode,SerializableType>( src ); } /** See ::P::s11n::io::create_serializer(). In short: it looks at the given file to determine what Serializer should be able to read it. Once IOManager support is completed this will also support URL-based lookups. The caller owns the returned object, which may be NULL. */ SerializerInterface * serializerFor( const std::string & url ); /** Saves src to dest using the default serializerClass(). Returns true on success, false on error. */ bool save( const S11nNode & src, const std::string & dest ); /** Saves src to dest using the default serializerClass(). Returns true on success, false on error. */ bool save( const S11nNode & src, std::ostream & dest ); /** Uses SerializerPluginManager to load the Serializer set via serializerClass() The caller owns the returned object, which may be NULL. */ SerializerInterface * createSerializer(); /** Uses SerializerPluginManager to load a Serializer. The caller owns the returned object, which may be NULL. */ SerializerInterface * createSerializer( const std::string & ); /** Uses serialize(src,node) to serialize src to a S11nNode then calls save(node,dest). Returns true on success, false on error. */ template <typename SerializableT> bool save( const SerializableT & src, std::ostream & dest ) { S11nNode n; return (serialize( n, src ) && save( n, dest )); } /** Serializes src to a S11nNode && returns serialize(node,url). Returns true on success, false on error. */ template <typename SerializableT> bool save( const SerializableT & src, const std::string & url ) { S11nNode n; if( ! serialize( n, src ) ) return false; return serialize( n, url ); } /** Sets the current Serializer class used by createSerializer(). Pass it a class name of a SerializerInterface type. */ void serializerClass( const std::string & ); /** Gets the name of the current default Serializer type. */ std::string serializerClass(); /** Serializes fromobj and deserializes the data by passing it to toobj. Returns false if either operation fails. SerializableT1 and SerializableT must of course be Serializables for this to work. See ::P::s11n::s11n_cast() for full details, including tips on how to use this to easily convert containers to different types. */ template <typename SerializableT1, typename SerializableT2> bool s11n_cast( const SerializableT1 & fromobj, SerializableT2 & toobj ) { return ::P::s11n::s11n_cast<S11nNode,SerializableT1,SerializableT2>( fromobj, toobj ); } /** Registers a Serializer (i/o handler) with the library. SerializerImplT must be-a SerializerInterface type. */ template <typename SerializerImplT> void registerSerializer( const std::string & classname, const std::string & alias ) { ::P::s11n::io::register_serializer< SerializerImplT >( classname, alias ); } } // namespace SIO } // namespace P #endif // p_SIO_H_INCLUDED --- NEW FILE: Makefile.toc --- #!/usr/bin/make -f include toc.make SOURCES = \ registrations.cpp \ S11nNode.cpp \ SIO.cpp HEADERS = $(wildcard *.h) OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES)) INSTALL_PACKAGE_HEADERS = $(HEADERS) INSTALL_PACKAGE_HEADERS_DEST = $(INSTALL_PACKAGE_HEADERS_BASE)/SIO DIST_FILES += $(wildcard *.at) $(SOURCES) $(HEADERS) SYMLINK_HEADERS = $(INSTALL_PACKAGE_HEADERS) SYMLINK_HEADERS_DEST = $(top_srcdir)/include/pclasses/SIO include $(TOC_MAKESDIR)/SYMLINK_HEADERS.make S11NIO_DIR = $(top_srcdir)/src/s11n/io S11NIO_OBJECTS = $(S11NIO_DIR)/data_node_io.o ifeq (1,$(PCLASSES_HAVE_LIBEXPAT)) S11NIO_OBJECTS += $(S11NIO_DIR)/expat/expat_serializer.o endif S11NIO_OBJECTS += $(S11NIO_DIR)/parens/parens_serializer.o LIBNAME = lib$(LIBPSIO_BASENAME) SHARED_LIBS = $(LIBNAME) $(LIBNAME)_so_LDADD = $(P_BACKLINK_LDADD) $(LIBPSIO_LDADD) $(LIBEXPAT_CLIENT_LDADD) $(LIBNAME)_so_OBJECTS = $(OBJECTS) $(S11NIO_OBJECTS) $(LIBNAME)_so_VERSION = $(PACKAGE_VERSION) include $(TOC_MAKESDIR)/SHARED_LIBS.make all: SYMLINK_HEADERS SHARED_LIBS --- NEW FILE: S11nNode.cpp --- #include "S11nNode.h" #include <pclasses/s11n/functor.h> // object_deleter, child_pointer_deep_copier namespace P { namespace SIO { #define NODE_CLASS_NAME "S11nNode" #define NODE_DEFAULT_NAME "S11nNode" S11nNode::S11nNode() : ::P::Util::SimplePropertyStore(), m_name(NODE_DEFAULT_NAME), m_iname(NODE_CLASS_NAME) { } S11nNode::S11nNode( const std::string & name ) : ::P::Util::SimplePropertyStore(), m_name(NODE_DEFAULT_NAME), m_iname(NODE_CLASS_NAME) { } #undef NODE_CLASS_NAME #undef NODE_DEFAULT_NAME S11nNode::S11nNode( const S11nNode &rhs ) { if( &rhs == this ) return; this->copy( rhs ); } S11nNode::~S11nNode() { this->clear(); } S11nNode & S11nNode::operator=( const S11nNode & rhs ) { if( &rhs == this ) return *this; this->copy( rhs ); return *this; } S11nNode::child_list_type & S11nNode::children() { return this->m_children; } const S11nNode::child_list_type & S11nNode::children() const { return this->m_children; } void S11nNode::copy( const S11nNode & rhs ) { if ( &rhs == this ) return; this->clear(); this->name( rhs.name() ); this->class_name( rhs.class_name() ); std::copy( rhs.begin(), rhs.end(), std::insert_iterator<map_type>( this->getMap(), this->getMap().begin() ) ); std::for_each( rhs.children().begin(), rhs.children().end(), ::P::s11n::child_pointer_deep_copier<child_list_type>( this->children() ) ); } void S11nNode::clear() { this->clear_children(); this->clear_properties(); } void S11nNode::class_name( const std::string & n ) { this->m_iname = n; } std::string S11nNode::class_name()const { return this->m_iname; } void S11nNode::name( const std::string & n ) { this->m_name = n; } std::string S11nNode::name() const { return this->m_name; } void S11nNode::clear_properties() { if ( getMap().empty() ) return; getMap().erase( getMap().begin(), getMap().end() ); } void S11nNode::clear_children() { std::for_each( this->children().begin(), this->children().end(), ::P::s11n::object_deleter() ); this->children().clear(); } S11nNode::iterator S11nNode::begin() { return this->getMap().begin(); } S11nNode::const_iterator S11nNode::begin() const { return this->getMap().begin(); } S11nNode::iterator S11nNode::end() { return this->getMap().end(); } S11nNode::const_iterator S11nNode::end() const { return this->getMap().end(); } }} // P::SIO --- NEW FILE: SIO.cpp --- //////////////////////////////////////////////////////////////////////// // SIO.cpp - implementation code for SIO.h // author: st...@s1... // License: LGPL, copyright(c) 2004, 2005 stephan beal //////////////////////////////////////////////////////////////////////// #include "SIO.h" #include <pclasses/s11n/s11n_debuggering_macros.h> #define SIO_KEY_DEFAULT_SERIALIZER "/P/SIO/DefaultSerializerClass" namespace P { /** */ namespace SIO { std::string m_serializer_class = SIO_KEY_DEFAULT_SERIALIZER; SerializerInterface * serializerFor( const std::string & url ) { // @fixme: be more dynamic here: // todo: port in IManager support from "original" ps11n // once IOM is re-implemented in P2. return ::P::s11n::io::create_serializer<S11nNode>( m_serializer_class ); } SerializerInterface * createSerializer( const std::string & c ) { return SerializerPluginManager::instance().create( c ); } SerializerInterface * createSerializer() { return SerializerPluginManager::instance().create( m_serializer_class ); } bool save( const S11nNode & src, std::ostream & dest ) { typedef std::auto_ptr<SerializerInterface> SAP; SAP ser = SAP(createSerializer()); if( ! ser.get() ) { CERR << "Could not load Serializer!\n"; return false; } return ser->serialize( src, dest ); } bool save( const S11nNode & src, const std::string & dest ) { std::ofstream os(dest.c_str()); if( ! os ) return false; return save( src, os ); } S11nNode * loadNode( std::istream & src ) { return ::P::s11n::io::load_node<S11nNode>( src ); } S11nNode * loadNode( const std::string & src ) { return ::P::s11n::io::load_node<S11nNode>( src ); } void serializerClass( const std::string & c ) { m_serializer_class = c; } std::string serializerClass() { return m_serializer_class; } }} // P::SIO |