00001 #ifndef funxml_SERIALIZER_H_INCLUDED
00002 #define funxml_SERIALIZER_H_INCLUDED 1
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <s11n.net/s11n/io/strtool.hpp>
00013
00014 #include <s11n.net/s11n/traits.hpp>
00015 #include <s11n.net/s11n/s11n_debuggering_macros.hpp>
00016 #include <s11n.net/s11n/io/data_node_format.hpp>
00017
00018
00019 #define MAGIC_COOKIE_FUNXML "<!DOCTYPE SerialTree>"
00020
00021 namespace s11n {
00022 namespace io {
00023 namespace sharing {
00024
00025
00026
00027 struct funxml_sharing_context {};
00028
00029 }
00030
00031 typedef std::map<std::string,std::string> entity_translation_map;
00032
00033
00034
00035
00036
00037 entity_translation_map & funxml_serializer_translations();
00038
00039
00040
00041
00042
00043
00044
00045 template <typename NodeType>
00046 class funxml_serializer : public tree_builder_lexer<NodeType,sharing::funxml_sharing_context>
00047 {
00048 public:
00049 typedef NodeType node_type;
00050
00051 typedef funxml_serializer<node_type> this_type;
00052 typedef tree_builder_lexer<node_type,sharing::funxml_sharing_context> parent_type;
00053
00054 funxml_serializer() : parent_type( "funxml_data_nodeFlexLexer" ), m_depth(0)
00055 {
00056 this->magic_cookie( MAGIC_COOKIE_FUNXML );
00057 }
00058
00059 virtual ~funxml_serializer() {}
00060
00061
00062
00063
00064
00065 virtual const entity_translation_map & entity_translations() const
00066 {
00067 return funxml_serializer_translations();
00068 }
00069
00070
00071
00072
00073
00074 virtual bool serialize( const node_type & src, std::ostream & dest )
00075 {
00076
00077 typedef ::s11n::node_traits<node_type> NT;
00078
00079 #define INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00080 size_t depth = this->m_depth++;
00081 if ( 0 == depth )
00082 {
00083 dest << this->magic_cookie() << '\n';
00084 }
00085
00086
00087 std::string nname = NT::name(src);
00088 std::string impl = NT::class_name(src);
00089 strtool::translate_entities( impl, this->entity_translations(), false );
00090
00091 std::string indent;
00092
00093
00094 dest << "<" << nname << " class=\"" << impl << "\">\n";
00095 typename NT::property_map_type::const_iterator cit = NT::properties(src).begin(),
00096 cet = NT::properties(src).end();
00097
00098
00099 std::string propval;
00100 std::string key;
00101
00102 INDENT(1,0);
00103 for ( ; cet != cit; ++cit )
00104 {
00105 key = ( *cit ).first;
00106 propval = ( *cit ).second;
00107 strtool::translate_entities( propval, this->entity_translations(), false );
00108 dest << indent;
00109 dest << "<" << key << ">";
00110 dest << propval;
00111 dest << "</" << key << ">\n";
00112 }
00113 INDENT(1,0);
00114 std::for_each( NT::children(src).begin(),
00115 NT::children(src).end(),
00116 node_child_simple_formatter<this_type>( *this,
00117 dest,
00118 indent,
00119 "" )
00120 );
00121
00122 INDENT(0,1);
00123 dest << "</" << nname << ">\n";
00124 if( 0 == depth )
00125 {
00126 dest.flush();
00127
00128 }
00129 --this->m_depth;
00130 return true;
00131 #undef INDENT
00132 }
00133
00134
00135
00136
00137
00138 virtual node_type * deserialize( std::istream & src )
00139 {
00140 return deserialize_lex_forwarder<node_type,sharing::funxml_sharing_context>( "funxml_data_nodeFlexLexer", src );
00141
00142 }
00143
00144 virtual node_type * deserialize( const std::string & src )
00145 {
00146
00147
00148 return this->parent_type::deserialize( src );
00149 }
00150
00151
00152
00153 private:
00154 size_t m_depth;
00155 };
00156
00157 }
00158 }
00159
00160 #endif // funxml_SERIALIZER_H_INCLUDED