From: stephan b. <sg...@us...> - 2004-12-26 17:29:07
|
Update of /cvsroot/pclasses/pclasses2/src/s11n/io/parens In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3758/src/s11n/io/parens Added Files: Makefile.toc parens_serializer.cpp parens_serializer.h Log Message: egg. write support works, but for reading i need to hand-implement the (previously lex-based) parser :(. --- NEW FILE: parens_serializer.cpp --- #include "parens_serializer.h" #include <pclasses/s11n/io/serializers.h> // register_serializer() #include <pclasses/Phoenix.h> namespace P { namespace s11n { namespace io { /** Internal-use initializer for setting up a Serializer translation map. */ struct paren_serializer_translations_initializer { template <typename MapT> void operator()( MapT & map ) { // The order of these escapes is // signifant. We only do // double-backslashes to accomodate // the case that the final chars in a // property is a backslash (yes, this // has happened, and it hosed the // data, because it inadvertently // escaped a control token.). map["\\"] = "\\\\"; map[")"] = "\\)"; map["("] = "\\("; // It is not strictly necessary to escape \(, // but we do so because Parens is intended to // be easy for hand-editing, and not escaping // them confuses emacs when we have escaped // closing parens. :) } }; /** Returns the translations map for parens_serializer. */ entity_translation_map & parens_serializer_translations() { typedef P::Phoenix< entity_translation_map, sharing::parens_sharing_context, paren_serializer_translations_initializer > TheMap; return TheMap::instance(); } void parens_serializer_registration_init() { #define SERINST(NodeT) \ register_serializer< parens_serializer< NodeT > > \ ( "s11n::io::parens_serializer", "parens" ); /// ^^^ WTF does gcc make me qualify those namespaces? SERINST(::P::s11n::data_node); SERINST(::P::s11n::s11n_node); #undef SERINST } int parens_reg_placeholder = ( parens_serializer_registration_init(), 1 ); } } } // namespace P::s11n::io --- NEW FILE: Makefile.toc --- #!/usr/bin/make -f include toc.make HEADERS = parens_serializer.h DIST_FILES += $(HEADERS) # INSTALL_PACKAGE_HEADERS_DEST = $(INSTALL_PACKAGE_HEADERS_BASE)/s11n/io # INSTALL_PACKAGE_HEADERS += $(HEADERS) SOURCES = parens_serializer.cpp DIST_FILES += $(SOURCES) OBJECTS = parens_serializer.o CLEAN_FILES += $(OBJECTS) build_libs = 1 LIBNAME = parens_serializer ifeq (1,$(build_libs)) SHARED_LIBS = $(LIBNAME) $(LIBNAME)_so_OBJECTS = $(OBJECTS) include $(TOC_MAKESDIR)/SHARED_LIBS.make endif build_bins = 0 BINNAME = mybin ifeq (1,$(build_bins)) BIN_PROGRAMS = $(BINNAME) $(BINNAME)_bin_OBJECTS = $(OBJECTS) # $(BINNAME)_bin_LDADD = include $(TOC_MAKESDIR)/BIN_PROGRAMS.make INSTALL_BINS += $(BIN_PROGRAMS) # Run target BIN_PROGRAMS to build these. endif all: SHARED_LIBS --- NEW FILE: parens_serializer.h --- #ifndef parens_SERIALIZER_H_INCLUDED #define parens_SERIALIZER_H_INCLUDED 1 //////////////////////////////////////////////////////////////////////// // data_node_serializers.hpp: some file parsers for the s11n framework // // License: Public Domain // Author: st...@s1... //////////////////////////////////////////////////////////////////////// #include <pclasses/s11n/s11n.h> #include <pclasses/s11n/io/data_node_io.h> // #include <pclasses/s11n/io/serializers.h> #include <map> #include <string> #define PARENS_VERSION "$Revision: 1.1 $" #define MAGIC_COOKIE_PARENS "(s11n::parens)" #define PARENS_INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; } namespace P { namespace s11n { namespace io { namespace sharing { /** Sharing context used by parens_serializer. */ struct parens_sharing_context {}; } typedef std::map<std::string,std::string> entity_translation_map; /** The entity translations map used by parens_serializer. */ entity_translation_map & parens_serializer_translations(); /** De/serializes objects from/to a lisp-like grammar. */ template <typename NodeType> class parens_serializer : public data_node_serializer<NodeType> { public: typedef NodeType node_type; typedef parens_serializer<node_type> this_type; // convenience typedef typedef data_node_serializer<node_type> parent_type; // convenience typedef parens_serializer() : m_depth(0) { this->magic_cookie( MAGIC_COOKIE_PARENS ); } virtual ~parens_serializer() {} typedef entity_translation_map translation_map; /** Reimplemented to return this type's entity translation map. */ virtual const translation_map & entity_translations() const { return parens_serializer_translations(); } virtual node_type * deserialize( std::ostream & dest ) { // NYI! return 0; } /** Writes src out to dest. */ virtual bool serialize( const node_type & src, std::ostream & dest ) { typedef ::P::s11n::node_traits<node_type> NT; size_t depth = this->m_depth++; if( 0 == depth ) { dest << this->magic_cookie() // << "\n(* serializer info: " // << "\n\t" << PARENS_VERSION // << "\n\tBuilt " << __TIME__ << " on " __DATE__ // << "\n*)" << "\n"; } std::string indent; std::string implclass = NT::class_name(src); // i know this quote check is fairly expensive, but 2 bytes per // object adds up. Consider: 10k objects would take up // 20k bytes just in classname quotes! std::string quote = (std::string::npos != implclass.find('<')) ? "\"" : ""; dest << NT::name(src) << "=" << this->m_open << quote << implclass << quote; typename NT::const_iterator beg = NT::begin(src), end = NT::end(src); if( end != beg ) { //PARENS_INDENT(1,0); std::for_each(beg, end, key_value_serializer<node_type>( this->entity_translations(), dest, /* indent + */ ' ' + this->m_open , " ", this->m_close ) ); } typename NT::child_const_iterator chbeg = NT::children(src).begin(), chend = NT::children(src).end(); if( chend != chbeg ) { // got children? dest << '\n'; PARENS_INDENT(1,0); std::for_each( chbeg, chend, node_child_simple_formatter<this_type>( *this, dest, indent, "" ) ); PARENS_INDENT(0,1); } dest << this->m_close << '\n'; if( 0 == depth ) { dest.flush(); // << std::endl; // else client may be forced to manually flush(). } --this->m_depth; return true; } private: size_t m_depth; static const std::string m_open; static const std::string m_close; }; template <typename NodeType> const std::string parens_serializer<NodeType>::m_open = "("; template <typename NodeType> const std::string parens_serializer<NodeType>::m_close = ")"; } } } // namespace P::s11n::io #undef PARENS_VERSION #undef PARENS_INDENT #endif // parens_SERIALIZER_H_INCLUDED |