Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

parens_serializer.h

00001 #ifndef parens_SERIALIZER_H_INCLUDED
00002 #define parens_SERIALIZER_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // data_node_serializers.h: some file parsers for the s11n framework
00006 //
00007 // License: Public Domain
00008 // Author: stephan@s11n.net
00009 ////////////////////////////////////////////////////////////////////////
00010 
00011 #include "data_node_format.h" // base interfaces
00012 #define PARENS_VERSION "$Revision: 1.1.1.1 $"
00013 #define MAGIC_COOKIE_PARENS "(s11n::parens)"
00014 #define TAB(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00015 
00016 namespace s11n {
00017     namespace io {
00018 
00019                 namespace sharing {
00020                         /**
00021                            Sharing context used by parens_serializer.
00022                         */
00023                         struct parens_sharing_context {};
00024                 }
00025 
00026 
00027                 /**
00028                    The entity translations map used by parens_serializer.
00029                  */
00030                 entity_translation_map & parens_serializer_translations();
00031 
00032                 /**
00033                    De/serializes objects from/to a lisp-like grammar.
00034                 */
00035                 template <typename NodeType>
00036                 class parens_serializer : public tree_builder_lexer<NodeType,sharing::parens_sharing_context>
00037                 {
00038                 public:
00039                         typedef NodeType node_type;
00040 
00041                         typedef parens_serializer<node_type> this_type; // convenience typedef
00042                         typedef tree_builder_lexer<node_type,sharing::parens_sharing_context> parent_type; // convenience typedef
00043 
00044                         parens_serializer() : parent_type( "parens_data_nodeFlexLexer" ),
00045                                               m_depth(0)
00046                         {
00047                                 this->magic_cookie( MAGIC_COOKIE_PARENS );
00048                         }
00049 
00050                         virtual ~parens_serializer() {}
00051 
00052                         typedef entity_translation_map translation_map;
00053 
00054                         /**
00055                            Reimplemented to return this type's entity
00056                            translation map.
00057                          */
00058                         virtual const translation_map & entity_translations() const
00059                         {
00060                                 return parens_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                                 size_t depth = this->m_depth++;
00070                                 if( 0 == depth )
00071                                 {
00072                                         node_type & meta = this->metadata();
00073                                         dest << this->magic_cookie() << '\n';
00074                                         meta.set( "serializer_revision", PARENS_VERSION );
00075                                         meta.set( "serializer_class", ::classname<this_type>() );
00076                                         //this->serialize( meta, dest );
00077                                 }
00078 
00079 
00080                                 std::string indent;
00081                                 // i know this quote check is fairly expensive, but 2 bytes per
00082                                 // object adds up. Consider: 10k objects would take up
00083                                 // 20k bytes just in classname quotes!
00084                                 std::string quote =
00085                                         (std::string::npos != src.impl_class().find('<'))
00086                                         ? "\""
00087                                         : "";
00088                                 dest << src.name() << "=" << this->m_open
00089                                      << quote << src.impl_class() << quote;
00090 
00091                                 bool gotp = (src.begin() != src.end());
00092 
00093                                 if( gotp )
00094                                 {
00095                                         //TAB(1,0);
00096                                         std::for_each(src.begin(),
00097                                                       src.end(),
00098                                                       key_value_serializer<node_type>(
00099                                                               &(this->entity_translations()),
00100                                                               dest,
00101                                                               /* indent + */ ' ' + this->m_open ,
00102                                                               " ",
00103                                                               this->m_close + ' ' )
00104                                                       );
00105                                 }
00106                                 bool gotch = (src.children().begin() != src.children().end());
00107                                 if( gotch )
00108                                 { // got children?
00109                                         dest << '\n';
00110                                         TAB(1,0);
00111                                         std::for_each( src.children().begin(),
00112                                                        src.children().end(),
00113                                                        node_child_simple_formatter<this_type>(
00114                                                                     *this,
00115                                                                     dest,
00116                                                                     indent,
00117                                                                     "" )
00118                                                        );
00119                                         TAB(0,1);
00120                                 }
00121 
00122                                 dest << this->m_close << '\n';
00123 
00124                                 if( 0 == depth )
00125                                 {
00126                                         dest.flush(); // << std::endl; // else client may be forced to manually flush().
00127                                 }
00128                                 --this->m_depth;
00129                                 return true;
00130                         }
00131 
00132 
00133 
00134                 private:
00135                         size_t m_depth;
00136                         static const std::string m_open;
00137                         static const std::string m_close;
00138                 };
00139                 template <typename NodeType>
00140                 const std::string parens_serializer<NodeType>::m_open = "(";
00141                 template <typename NodeType>
00142                 const std::string parens_serializer<NodeType>::m_close = ")";
00143 
00144     } // namespace io
00145 } // namespace s11n
00146 
00147 #undef TAB
00148 
00149 #endif // parens_SERIALIZER_H_INCLUDED

Generated on Tue Oct 26 18:25:59 2004 for s11n by  doxygen 1.3.9.1