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

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 // 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> // base interfaces
00012 #include <s11n.net/s11n/traits.hpp> // node_traits
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                            Sharing context used by parens_serializer.
00023                         */
00024                         struct parens_sharing_context {};
00025                 }
00026 
00027 
00028                 /**
00029                    The entity translations map used by parens_serializer.
00030                  */
00031                 entity_translation_map & parens_serializer_translations();
00032 
00033                 /**
00034                    De/serializes objects from/to a lisp-like grammar.
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; // convenience typedef
00043                         typedef tree_builder_lexer<node_type,sharing::parens_sharing_context> parent_type; // convenience typedef
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                            Reimplemented to return this type's entity
00057                            translation map.
00058                          */
00059                         virtual const translation_map & entity_translations() const
00060                         {
00061                                 return parens_serializer_translations();
00062                         }
00063 
00064 
00065                         /**
00066                            Writes src out to dest.
00067                         */
00068                         virtual bool serialize( const node_type & src, std::ostream & dest )
00069                         {
00070                                 typedef ::s11n::node_traits<node_type> NT;
00071                                 size_t depth = this->m_depth++;
00072                                 if( 0 == depth )
00073                                 {
00074                                         dest << this->magic_cookie()
00075 //                                              << "\n(* serializer info: "
00076 //                                              << "\n\t" << PARENS_VERSION
00077 //                                              << "\n\tBuilt " << __TIME__ << " on " __DATE__
00078 //                                              << "\n*)"
00079                                              << "\n";
00080                                 }
00081 
00082                                 std::string indent;
00083                                 std::string implclass = NT::class_name(src);
00084 
00085                                 // i know this quote check is fairly expensive, but 2 bytes per
00086                                 // object adds up. Consider: 10k objects would take up
00087                                 // 20k bytes just in classname quotes!
00088                                 std::string quote =
00089                                         (std::string::npos != implclass.find('<'))
00090                                         ? "\""
00091                                         : "";
00092                                 dest << NT::name(src) << "=" << this->m_open
00093                                      << quote << implclass << quote;
00094 
00095                                 typename NT::property_map_type::const_iterator beg = NT::properties(src).begin(),
00096                                         end = NT::properties(src).end();
00097                                 if( end != beg )
00098                                 {
00099                                         //INDENT(1,0);
00100                                         std::for_each(beg, end,
00101                                                       key_value_serializer<node_type>(
00102                                                               &(this->entity_translations()),
00103                                                               dest,
00104                                                               /* indent + */ ' ' + this->m_open ,
00105                                                               " ",
00106                                                               this->m_close )
00107                                                       );
00108                                 }
00109                                 typename NT::child_list_type::const_iterator chbeg = NT::children(src).begin(),
00110                                         chend = NT::children(src).end();
00111                                 if( chend != chbeg )
00112                                 { // got children?
00113                                         dest << '\n';
00114                                         INDENT(1,0);
00115                                         std::for_each( chbeg, chend,
00116                                                        node_child_simple_formatter<this_type>(
00117                                                                     *this,
00118                                                                     dest,
00119                                                                     indent,
00120                                                                     "" )
00121                                                        );
00122                                         INDENT(0,1);
00123                                 }
00124 
00125                                 dest << this->m_close << '\n';
00126 
00127                                 if( 0 == depth )
00128                                 {
00129                                         dest.flush(); // << std::endl; // else client may be forced to manually flush().
00130                                 }
00131                                 --this->m_depth;
00132                                 return true;
00133                         }
00134 
00135 
00136 
00137                 private:
00138                         size_t m_depth;
00139                         static const std::string m_open;
00140                         static const std::string m_close;
00141                 };
00142                 template <typename NodeType>
00143                 const std::string parens_serializer<NodeType>::m_open = "(";
00144                 template <typename NodeType>
00145                 const std::string parens_serializer<NodeType>::m_close = ")";
00146 
00147     } // namespace io
00148 } // namespace s11n
00149 
00150 #undef PARENS_VERSION
00151 #undef INDENT
00152 
00153 #endif // parens_SERIALIZER_H_INCLUDED

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