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 node_type * deserialize( std::istream & src )
00075 {
00076 return deserialize_lex_forwarder<node_type,sharing::funxml_sharing_context>( "funxml_data_nodeFlexLexer", src );
00077
00078 }
00079
00080 virtual node_type * deserialize( const std::string & src )
00081 {
00082
00083
00084 return this->parent_type::deserialize( src );
00085 }
00086
00087
00088
00089
00090
00091 virtual bool serialize( const node_type & src, std::ostream & dest )
00092 {
00093 try
00094 {
00095 return this->serialize_impl( src, dest );
00096 }
00097 catch(...)
00098 {
00099 this->m_depth = 0;
00100 throw;
00101 }
00102 return false;
00103 }
00104
00105
00106 private:
00107
00108
00109
00110 bool serialize_impl( const node_type & src, std::ostream & dest )
00111 {
00112
00113 typedef ::s11n::node_traits<node_type> NT;
00114
00115 #define INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00116 size_t depth = this->m_depth++;
00117 if ( 0 == depth )
00118 {
00119 dest << this->magic_cookie() << '\n';
00120 }
00121
00122
00123 std::string nname = NT::name(src);
00124 std::string impl = NT::class_name(src);
00125 strtool::translate_entities( impl, this->entity_translations(), false );
00126
00127 std::string indent;
00128
00129
00130 dest << "<" << nname << " class=\"" << impl << "\">\n";
00131 typename NT::property_map_type::const_iterator pit = NT::properties(src).begin(),
00132 pet = NT::properties(src).end();
00133
00134
00135 std::string propval;
00136 std::string key;
00137
00138 INDENT(1,0);
00139 for ( ; pet != pit; ++pit )
00140 {
00141 key = ( *pit ).first;
00142 propval = ( *pit ).second;
00143 strtool::translate_entities( propval, this->entity_translations(), false );
00144 dest << indent;
00145 dest << "<" << key << ">";
00146 dest << propval;
00147 dest << "</" << key << ">\n";
00148 }
00149 INDENT(1,0);
00150
00151 typedef typename NT::child_list_type CLT;
00152 typedef typename CLT::const_iterator CLIT;
00153 CLIT cit = NT::children(src).begin();
00154 CLIT cet = NT::children(src).end();
00155 for( ; cet != cit; ++cit )
00156 {
00157 dest << indent;
00158 this->serialize_impl( *(*cit), dest );
00159 }
00160
00161 INDENT(0,1);
00162 dest << "</" << nname << ">\n";
00163 if( 0 == depth )
00164 {
00165 dest.flush();
00166
00167 }
00168 --this->m_depth;
00169 return true;
00170 #undef INDENT
00171 }
00172
00173 private:
00174 size_t m_depth;
00175 };
00176
00177 }
00178 }
00179
00180 #endif // funxml_SERIALIZER_H_INCLUDED