Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 // License: Public Domain
00006 // Author: stephan@s11n.net
00007 ////////////////////////////////////////////////////////////////////////
00008 
00009 #include <s11n.net/s11n/io/data_node_format.hpp>
00010 #include <s11n.net/s11n/traits.hpp> // node_traits
00011 #include <s11n.net/s11n/io/strtool.hpp> // translate_entities()
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                    Sharing context used by wesnoth_serializer.
00020                 */
00021                 struct wesnoth_sharing_context {};
00022 
00023         }
00024 
00025         /** convenience typedef */
00026         typedef std::map<std::string,std::string> entity_translation_map;
00027 
00028         /**
00029            The entity translations map used by wesnoth_serializer.
00030         */
00031         entity_translation_map & wesnoth_serializer_translations();
00032 
00033         /**
00034            De/serializes objects from/to this class' config-file-like grammar.
00035        It gets its name, and most of its grammar, from the Open Source
00036        strategy/adventure game "The Battle for Wesnoth" (www.wesnoth.org).
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; // convenience typedef
00045                 typedef tree_builder_lexer<node_type,sharing::wesnoth_sharing_context> parent_type; // convenience typedef
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                    Reimplemented to return this type's entity
00056                    translation map.
00057                 */
00058                 virtual const entity_translation_map & entity_translations() const
00059                 {
00060                         return wesnoth_serializer_translations();
00061                 }
00062 
00063 
00064                 /**
00065                    Writes src out to dest.
00066                 */
00067                 virtual bool serialize( const node_type & src, std::ostream & dest )
00068                 {
00069                         typedef ::s11n::node_traits<node_type> NT;
00070                         size_t depth = this->m_depth++;
00071                         if ( 0 == depth )
00072                         {
00073                                 dest << this->magic_cookie() << '\n';
00074                         }
00075                         const static char open = '[';
00076                         const static char close = ']';
00077 
00078                         std::string nname = NT::name(src);
00079                         std::string impl = NT::class_name(src);
00080                         dest << open << nname << "=" << impl << close <<"\n";
00081 
00082                         std::string indent;
00083                         std::string propval;
00084                         std::string key;
00085 
00086                         INDENT(0,0);
00087                         typedef typename NT::property_map_type::const_iterator PCIT;
00088                         PCIT pit = NT::properties(src).begin();
00089             PCIT pet = NT::properties(src).end();
00090                         std::string val;
00091                         const static std::string nonquoted = "_0123456789abcdefghijklmnopqrstuvqxyxABCDEFGHIJKLMNOPQRSTUVQXYX";
00092                         for( ; pet != pit; ++pit )
00093                         {
00094                                 dest << indent << (*pit).first << "=";
00095                 val = (*pit).second;
00096                                 ::s11n::io::strtool::translate_entities( val, this->entity_translations(), false );
00097                                 if( std::string::npos != val.find_first_not_of( nonquoted ) )
00098                                 {
00099                                         dest << "\"" << val << "\"";
00100                                 }
00101                                 else
00102                                 {
00103                                         dest << val;
00104                                 }
00105                                 dest << "\n";
00106                         }
00107                         if( NT::children(src).end() != NT::children(src).begin() )
00108                         {
00109                                 INDENT(1,0);
00110                                 std::for_each( NT::children(src).begin(),
00111                                                NT::children(src).end(),
00112                                                node_child_simple_formatter<this_type>( *this,
00113                                                                                        dest,
00114                                                                                        indent,
00115                                                                                        "" )
00116                                                );
00117                         }
00118                         INDENT(0,1);
00119                         dest << open << "/"<< nname << close <<"\n";
00120                         if( 0 == depth )
00121                         {
00122                                 dest.flush();
00123                                 // if we don't do this then the client is possibly forced to flush() the stream :/
00124                         }
00125                         --this->m_depth;
00126                         return true;
00127                 }
00128 
00129         private:
00130                 size_t m_depth;
00131         };
00132 
00133 
00134 
00135 
00136 
00137 } } // namespace s11n::io
00138 
00139 #undef INDENT
00140 #endif // wesnoth_SERIALIZER_H_INCLUDED

Generated on Sun Dec 18 18:38:03 2005 for libs11n-1.2.2 by  doxygen 1.4.4