wesnoth_serializer.hpp
Go to the documentation of this file.00001 #ifndef wesnoth_SERIALIZER_H_INCLUDED
00002 #define wesnoth_SERIALIZER_H_INCLUDED 1
00003
00004
00005
00006
00007
00008
00009 #include <s11n.net/s11n/io/data_node_format.hpp>
00010 #include <s11n.net/s11n/traits.hpp>
00011 #include <s11n.net/s11n/io/strtool.hpp>
00012 #define MAGIC_COOKIE_WESNOTH "#s11n::io::wesnoth_serializer"
00013
00014 #define INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00015
00016 namespace s11n { namespace io {
00017 namespace sharing {
00018
00019
00020
00021 struct wesnoth_sharing_context {};
00022
00023 }
00024
00025
00026 typedef std::map<std::string,std::string> entity_translation_map;
00027
00028
00029
00030
00031 entity_translation_map & wesnoth_serializer_translations();
00032
00033
00034
00035
00036
00037
00038 template <typename NodeType>
00039 class wesnoth_serializer : public tree_builder_lexer<NodeType,sharing::wesnoth_sharing_context>
00040 {
00041 public:
00042 typedef NodeType node_type;
00043
00044 typedef wesnoth_serializer<node_type> this_type;
00045 typedef tree_builder_lexer<node_type,sharing::wesnoth_sharing_context> parent_type;
00046
00047 wesnoth_serializer() : parent_type( "wesnoth_data_nodeFlexLexer" ), m_depth(0)
00048 {
00049 this->magic_cookie( MAGIC_COOKIE_WESNOTH );
00050 }
00051
00052 virtual ~wesnoth_serializer() {}
00053
00054
00055
00056
00057
00058 virtual const entity_translation_map & entity_translations() const
00059 {
00060 return wesnoth_serializer_translations();
00061 }
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 private:
00082
00083
00084
00085 bool serialize_impl( const node_type & src, std::ostream & dest )
00086 {
00087 typedef ::s11n::node_traits<node_type> NT;
00088 size_t depth = this->m_depth++;
00089 if ( 0 == depth )
00090 {
00091 dest << this->magic_cookie() << '\n';
00092 }
00093 const static char open = '[';
00094 const static char close = ']';
00095
00096 std::string nname = NT::name(src);
00097 std::string impl = NT::class_name(src);
00098 dest << open << nname << "=" << impl << close <<"\n";
00099
00100 std::string indent;
00101 std::string propval;
00102 std::string key;
00103
00104 INDENT(0,0);
00105 typedef typename NT::property_map_type::const_iterator PCIT;
00106 PCIT pit = NT::properties(src).begin();
00107 PCIT pet = NT::properties(src).end();
00108 std::string val;
00109 const static std::string nonquoted = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00110 for( ; pet != pit; ++pit )
00111 {
00112 dest << indent << (*pit).first << "=";
00113 val = (*pit).second;
00114 ::s11n::io::strtool::translate_entities( val, this->entity_translations(), false );
00115 if( std::string::npos != val.find_first_not_of( nonquoted ) )
00116 {
00117 dest << "\"" << val << "\"";
00118 }
00119 else
00120 {
00121 dest << val;
00122 }
00123 dest << "\n";
00124 }
00125 typedef typename NT::child_list_type CLT;
00126 typedef typename CLT::const_iterator CLIT;
00127 CLIT cit = NT::children(src).begin();
00128 CLIT cet = NT::children(src).end();
00129 if( cet != cit )
00130 {
00131 INDENT(1,0);
00132 for( ; cet != cit; ++cit )
00133 {
00134 dest << indent;
00135 this->serialize_impl( *(*cit), dest );
00136 }
00137 }
00138 INDENT(0,1);
00139 dest << open << "/"<< nname << close <<"\n";
00140 if( 0 == depth )
00141 {
00142 dest.flush();
00143
00144 }
00145 --this->m_depth;
00146 return true;
00147 }
00148
00149 private:
00150 size_t m_depth;
00151 };
00152
00153
00154
00155
00156
00157 } }
00158
00159 #undef INDENT
00160 #endif // wesnoth_SERIALIZER_H_INCLUDED