funtxt_serializer.hpp

Go to the documentation of this file.
00001 #ifndef funtxt_SERIALIZER_H_INCLUDED
00002 #define funtxt_SERIALIZER_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // data_node_serializers.hpp: some file parsers for the s11n framework
00006 //
00007 // License: Public Domain
00008 // Author: stephan@s11n.net
00009 ////////////////////////////////////////////////////////////////////////
00010 
00011 #include <s11n.net/s11n/io/data_node_format.hpp>
00012 #include <s11n.net/s11n/traits.hpp> // node_traits
00013 
00014 #define MAGIC_COOKIE_FUNTXT "#SerialTree 1"
00015 
00016 #define INDENT(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00017 
00018 namespace s11n {
00019     namespace io {
00020                 namespace sharing {
00021                         /**
00022                            Sharing context used by funtxt_serializer.
00023                          */
00024                         struct funtxt_sharing_context {};
00025 
00026                 }
00027 
00028                 /**
00029                    The entity translations map used by funtxt_serializer.
00030                  */
00031                 entity_translation_map & funtxt_serializer_translations();
00032 
00033 
00034                 /**
00035                    De/serializes objects from/to this class' config-file-like grammar.
00036                 */
00037                 template <typename NodeType>
00038                 class funtxt_serializer : public tree_builder_lexer<NodeType,sharing::funtxt_sharing_context>
00039                 {
00040                 public:
00041                         typedef NodeType node_type;
00042 
00043                         typedef funtxt_serializer<node_type> this_type; // convenience typedef
00044                         typedef tree_builder_lexer<node_type,sharing::funtxt_sharing_context> parent_type; // convenience typedef
00045 
00046                         funtxt_serializer() : parent_type( "funtxt_data_nodeFlexLexer" ), m_depth(0)
00047                         {
00048                                 this->magic_cookie( MAGIC_COOKIE_FUNTXT );
00049                         }
00050 
00051                         virtual ~funtxt_serializer() {}
00052 
00053                         /**
00054                            Reimplemented to return this type's entity
00055                            translation map.
00056                          */
00057                         virtual const entity_translation_map & entity_translations() const
00058                         {
00059                                 return funtxt_serializer_translations();
00060                         }
00061 
00062 
00063                         /**
00064                            Writes src out to dest.
00065                         */
00066                         virtual bool serialize( const node_type & src, std::ostream & dest )
00067             {
00068                 try
00069                 {
00070                     return this->serialize_impl( src, dest );
00071                 }
00072                 catch(...)
00073                 {
00074                     this->m_depth = 0;
00075                     throw;
00076                 }
00077                 return false; // can't get this far.
00078             }
00079 
00080         private:
00081                         /**
00082                            Writes src out to dest.
00083                         */
00084                         bool serialize_impl( const node_type & src, std::ostream & dest )
00085                         {
00086                                 typedef ::s11n::node_traits<node_type> NT;
00087                                 size_t depth = this->m_depth++;
00088                                 if ( 0 == depth )
00089                                 {
00090                                         dest << this->magic_cookie() << '\n';
00091                                 }
00092 
00093                                 std::string nname = NT::name(src);
00094                                 std::string impl = NT::class_name(src);
00095                                 std::string indent;
00096                                 std::string quote =
00097                                         (std::string::npos != impl.find('<'))
00098                                         ? "\""
00099                                         : "";
00100 
00101                                 dest << nname << " class=" << quote << impl << quote <<"\n";
00102                                 INDENT(0,1);
00103                                 dest <<"{\n";
00104                                 std::string propval;
00105                                 std::string key;
00106 
00107                                 INDENT(1,0);
00108                                 std::for_each(NT::properties(src).begin(),
00109                                               NT::properties(src).end(),
00110                                               key_value_serializer<node_type>(
00111                                                                               &(this->entity_translations()),
00112                                                                               dest,
00113                                                                               indent,
00114                                                                               " ",
00115                                                                               "\n" )
00116                                               );
00117 
00118                                 INDENT(1,0);
00119 
00120                 typedef typename NT::child_list_type CLT;
00121                 typedef typename CLT::const_iterator CLIT;
00122                 CLIT cit = NT::children(src).begin();
00123                 CLIT cet = NT::children(src).end();
00124                 for( ; cet != cit; ++cit )
00125                 {
00126                     dest << indent;
00127                     this->serialize_impl( *(*cit), dest );
00128                 }
00129                                 INDENT(0,1);
00130                                 dest << "}\n";
00131                                 if( 0 == depth )
00132                                 {
00133                                         dest.flush();
00134                                         // if we don't do this then the client is possibly forced to flush() the stream :/
00135                                 }
00136                                 --this->m_depth;
00137                                 return true;
00138                         }
00139 
00140                 private:
00141                         size_t m_depth;
00142                 };
00143     } // namespace io
00144 } // namespace s11n
00145 #undef INDENT
00146 #endif // funtxt_SERIALIZER_H_INCLUDED

Generated on Sun Apr 27 11:48:19 2008 for libs11n-1.2.6 by  doxygen 1.5.3