parens_serializer.hpp
Go to the documentation of this file.00001 #ifndef parens_SERIALIZER_H_INCLUDED
00002 #define parens_SERIALIZER_H_INCLUDED 1
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <s11n.net/s11n/io/data_node_format.hpp>
00012 #include <s11n.net/s11n/traits.hpp>
00013
00014 #define MAGIC_COOKIE_PARENS "(s11n::parens)"
00015 #define INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00016
00017 namespace s11n {
00018 namespace io {
00019
00020 namespace sharing {
00021
00022
00023
00024 struct parens_sharing_context {};
00025 }
00026
00027
00028
00029
00030
00031 entity_translation_map & parens_serializer_translations();
00032
00033
00034
00035
00036 template <typename NodeType>
00037 class parens_serializer : public tree_builder_lexer<NodeType,sharing::parens_sharing_context>
00038 {
00039 public:
00040 typedef NodeType node_type;
00041
00042 typedef parens_serializer<node_type> this_type;
00043 typedef tree_builder_lexer<node_type,sharing::parens_sharing_context> parent_type;
00044
00045 parens_serializer() : parent_type( "parens_data_nodeFlexLexer" ),
00046 m_depth(0)
00047 {
00048 this->magic_cookie( MAGIC_COOKIE_PARENS );
00049 }
00050
00051 virtual ~parens_serializer() {}
00052
00053 typedef entity_translation_map translation_map;
00054
00055
00056
00057
00058
00059 virtual const translation_map & entity_translations() const
00060 {
00061 return parens_serializer_translations();
00062 }
00063
00064
00065
00066
00067 virtual bool serialize( const node_type & src, std::ostream & dest )
00068 {
00069 try
00070 {
00071 return this->serialize_impl( src, dest );
00072 }
00073 catch(...)
00074 {
00075 this->m_depth = 0;
00076 throw;
00077 }
00078 return false;
00079 }
00080
00081
00082 private:
00083
00084
00085
00086 bool serialize_impl( const node_type & src, std::ostream & dest )
00087 {
00088 typedef ::s11n::node_traits<node_type> NT;
00089 size_t depth = this->m_depth++;
00090 if( 0 == depth )
00091 {
00092 dest << this->magic_cookie()
00093
00094
00095
00096
00097 << "\n";
00098 }
00099
00100 std::string indent;
00101 std::string implclass = NT::class_name(src);
00102
00103
00104
00105
00106 std::string quote =
00107 (std::string::npos != implclass.find('<'))
00108 ? "\""
00109 : "";
00110 dest << NT::name(src) << "=" << this->m_open
00111 << quote << implclass << quote;
00112
00113 typename NT::property_map_type::const_iterator beg = NT::properties(src).begin(),
00114 end = NT::properties(src).end();
00115 if( end != beg )
00116 {
00117
00118 std::for_each(beg, end,
00119 key_value_serializer<node_type>(
00120 &(this->entity_translations()),
00121 dest,
00122 ' ' + this->m_open ,
00123 " ",
00124 this->m_close )
00125 );
00126 }
00127 typename NT::child_list_type::const_iterator chbeg = NT::children(src).begin(),
00128 chend = NT::children(src).end();
00129 if( chend != chbeg )
00130 {
00131 dest << '\n';
00132 INDENT(1,0);
00133 for( ; chend != chbeg; ++chbeg )
00134 {
00135 dest << indent;
00136 this->serialize_impl( *(*chbeg), dest );
00137 }
00138 INDENT(0,1);
00139 }
00140
00141 dest << this->m_close << '\n';
00142
00143 if( 0 == depth )
00144 {
00145 dest.flush();
00146 }
00147 --this->m_depth;
00148 return true;
00149 }
00150
00151
00152
00153 private:
00154 size_t m_depth;
00155 static const std::string m_open;
00156 static const std::string m_close;
00157 };
00158 template <typename NodeType>
00159 const std::string parens_serializer<NodeType>::m_open = "(";
00160 template <typename NodeType>
00161 const std::string parens_serializer<NodeType>::m_close = ")";
00162
00163 }
00164 }
00165
00166 #undef PARENS_VERSION
00167 #undef INDENT
00168
00169 #endif // parens_SERIALIZER_H_INCLUDED