Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

funxml_serializer.h

00001 #ifndef funxml_SERIALIZER_H_INCLUDED
00002 #define funxml_SERIALIZER_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // data_node_serializers.h: some file parsers for the s11n framework
00006 //
00007 // License: Public Domain
00008 // Author: stephan@s11n.net
00009 ////////////////////////////////////////////////////////////////////////
00010 
00011 
00012 #include <s11n/debuggering_macros.h> // COUT/CERR
00013 #include <s11n/to_string.h> // to/from_string()
00014 #include <s11n/file_util.h> // get_i/ostream()
00015 #include <s11n/string_util.h> // translate_entities()
00016 #include <s11n/s11n_core.h> // classload()
00017 
00018 #include "data_node_functor.h"
00019 #include "data_node_io.h" // data_node_serializer<> and friends
00020 
00021 #define MAGIC_COOKIE_FUNXML "<!DOCTYPE SerialTree>"
00022 
00023 namespace s11n {
00024     namespace io {
00025                 namespace sharing {
00026                         /**
00027                            Sharing context used by funxml_serializer.
00028                          */
00029                         struct funxml_sharing_context {};
00030 
00031                 }
00032                 /** convenience typedef */
00033                 typedef std::map<std::string,std::string> entity_translation_map;
00034 
00035 
00036                 /**
00037                    The entity translations map used by funxml_serializer.
00038                  */
00039                 entity_translation_map & funxml_serializer_translations();
00040 
00041 
00042 
00043                 /**
00044                    De/serializes objects from/to a simple XML grammar,
00045                    with all properties and children stored as subnodes.
00046                 */
00047                 template <typename NodeType>
00048                 class funxml_serializer : public tree_builder_lexer<NodeType,sharing::funxml_sharing_context>
00049                 {
00050                 public:
00051                         typedef NodeType node_type;
00052 
00053                         typedef funxml_serializer<node_type> this_type; // convenience typedef
00054                         typedef tree_builder_lexer<node_type,sharing::funxml_sharing_context> parent_type; // convenience typedef
00055 
00056                         funxml_serializer() : parent_type( "funxml_data_nodeFlexLexer" ), m_depth(0)
00057                         {
00058                                 this->magic_cookie( MAGIC_COOKIE_FUNXML );
00059                         }
00060 
00061                         virtual ~funxml_serializer() {}
00062 
00063                         /**
00064                            Reimplemented to return this type's entity
00065                            translation map.
00066                          */
00067                         virtual const entity_translation_map & entity_translations() const
00068                         {
00069                                 return funxml_serializer_translations();
00070                         }
00071 
00072 
00073                         /**
00074                            Writes src out to dest.
00075                         */
00076                         virtual bool serialize( const node_type & src, std::ostream & dest )
00077                         {
00078 
00079 // TAB() is a helper macro for some serializers.
00080 #define TAB(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00081                                 size_t depth = this->m_depth++;
00082                                 if ( 0 == depth )
00083                                 {
00084                                         dest << this->magic_cookie() << '\n';
00085                                 }
00086 
00087 
00088                                 std::string nname = src.name();
00089                                 std::string impl = src.impl_class();
00090                                 s11n::translate_entities( impl, this->entity_translations(), false ); // handle class templates
00091 
00092                                 std::string indent;
00093 
00094 
00095                                 dest << "<" << nname << " class=\"" << impl << "\">\n";
00096                                 typename node_type::const_iterator cit = src.begin();
00097                                 std::string propval;
00098                                 std::string key;
00099                                 TAB(1,0);
00100                                 for ( ; src.end() != cit; ++cit )
00101                                 {
00102                                         key = ( *cit ).first;
00103                                         propval = ( *cit ).second;
00104                                         s11n::translate_entities( propval, this->entity_translations(), false );
00105                                         dest << indent;
00106                                         dest << "<" << key << ">";
00107                                         dest << propval;
00108                                         dest << "</" << key << ">\n";
00109                                 }
00110                                 TAB(1,0);
00111                                 std::for_each( src.children().begin(),
00112                                                src.children().end(),
00113                                                node_child_simple_formatter<this_type>( *this,
00114                                                                                  dest,
00115                                                                                  indent,
00116                                                                                  "" )
00117                                                );
00118 
00119                                 TAB(0,1);
00120                                 dest << "</" << nname << ">\n";
00121                                 if( 0 == depth )
00122                                 {
00123                                         dest.flush();
00124                                         // if we don't do this then the client is possibly forced to flush() the stream :/
00125                                 }
00126                                 --this->m_depth;
00127                                 return true;
00128 #undef TAB
00129                         }
00130 
00131 
00132                         /**
00133                            Overridden to parse src using this object's grammar rules.
00134                         */
00135                         virtual node_type * deserialize( std::istream & src )
00136                         {
00137                                 return deserialize_lex_forwarder<node_type,sharing::funxml_sharing_context>( "funxml_data_nodeFlexLexer", src );
00138                                 //CERR << "deserialize() returning " << std::hex << ret << "\n";
00139                         }
00140 
00141                 private:
00142                         size_t m_depth;
00143                 };
00144 
00145     } // namespace io
00146 } // namespace s11n
00147 
00148 #endif // funxml_SERIALIZER_H_INCLUDED

Generated on Tue Oct 26 18:25:59 2004 for s11n by  doxygen 1.3.9.1