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

compact_serializer.hpp

Go to the documentation of this file.
00001 #ifndef compact_SERIALIZER_H_INCLUDED
00002 #define compact_SERIALIZER_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // compact_serializer.hpp: a binary-like serializer 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_COMPACT "51191011"
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 compact_serializer.
00023                         */
00024                         struct compact_sharing_context {};
00025                 }
00026 
00027                 /**
00028                    De/serializes objects from/to a compact binary-like grammar.
00029                 */
00030                 template <typename NodeType>
00031                 class compact_serializer : public tree_builder_lexer<NodeType,sharing::compact_sharing_context>
00032                 {
00033                 public:
00034                         typedef NodeType node_type;
00035 
00036                         typedef compact_serializer<node_type> this_type; // convenience typedef
00037                         typedef tree_builder_lexer<node_type,sharing::compact_sharing_context> parent_type; // convenience typedef
00038 
00039                         compact_serializer() : parent_type( "compact_data_nodeFlexLexer" ),
00040                                               m_depth(0)
00041                         {
00042                                 this->magic_cookie( MAGIC_COOKIE_COMPACT );
00043                         }
00044 
00045                         virtual ~compact_serializer() {}
00046 
00047                         typedef entity_translation_map translation_map;
00048 
00049 
00050                         /**
00051                            Writes src out to dest.
00052                         */
00053                         virtual bool serialize( const node_type & src, std::ostream & dest )
00054                         {
00055                                 typedef ::s11n::node_traits<node_type> node_traits;
00056 
00057                                 static const int ctrlwidth = 2;
00058                                 static const int size2b = 2;
00059                                 static const int size4b = 4;
00060                                 static const int cookiewidth = 8;
00061                                 
00062                                 static const unsigned long Magic_Cookie_4B = 0x51191011;
00063                                 static const unsigned long Node_Open = 0xf1;
00064                                 static const unsigned long Node_Close = 0xf0;
00065                                 static const unsigned long Prop_Open =  0xe1;
00066                                 static const unsigned long Data_End = 0x51190000; // not strictly necessary
00067 
00068 
00069 
00070                                 std::string nname = node_traits::name( src );
00071                                 std::string impl = node_traits::class_name( src );
00072                                 std::string::size_type sizE = 0;
00073                                 std::string::size_type ins;
00074                                 // WTF must all this stream manip be done on every fucking insert?
00075 #define OS_INT(C,W) dest.width(W);dest<<std::hex<<std::right<<(unsigned int)(C);
00076 #define INSERT(vaR,WIDTH) sizE = vaR.size(); OS_INT(sizE,WIDTH); \
00077                 for( ins = 0; ins < sizE; ins++ ) {\
00078             /*OS_INT(vaR[ins],charwidth);*/ \
00079             dest << (unsigned char) vaR[ins]; \
00080         };
00081                                 size_t depth = this->m_depth++;
00082                                 
00083                                 if ( 0 == depth )
00084                                 {
00085                                         dest.setf( std::ios_base::hex );
00086                                         dest.fill('0');
00087                                         dest.setf(std::ios_base::right, std::ios_base::adjustfield);
00088                                         OS_INT(Magic_Cookie_4B,cookiewidth);
00089                                         dest << '\n';
00090                                 }
00091 
00092                                 OS_INT(Node_Open,ctrlwidth);
00093                                 INSERT(nname,size2b);
00094                                 INSERT(impl,size2b);
00095                                 typedef typename node_traits::property_map_type PMT;
00096                 typedef typename PMT::const_iterator CIT;
00097                                 CIT it = node_traits::properties(src).begin();
00098                                 CIT et = node_traits::properties(src).end();
00099                                 std::string propval;
00100                                 std::string propname;
00101                                 for ( ; it != et; ++it )
00102                                 {
00103                                         OS_INT(Prop_Open,ctrlwidth);
00104                                         propname = ( *it ).first;
00105                                         INSERT(propname,size2b);
00106                                         propval = ( *it ).second;
00107                                         INSERT(propval,size4b);
00108                                         //OS_INT(Prop_Close);
00109                                 }
00110 
00111                                 std::for_each( node_traits::children(src).begin(),
00112                                                node_traits::children(src).end(),
00113                                                node_child_simple_formatter<this_type>( *this, dest,"","" )
00114                                                );
00115 
00116                                 OS_INT(Node_Close,ctrlwidth);
00117                                 dest << '\n';
00118                                 if( 0 == depth )
00119                                 {
00120                                         OS_INT(Data_End,cookiewidth);
00121                                         dest << std::endl;
00122                                         // maintenance: dest must be flush()ed or the client may be forced to do it.
00123                                 }
00124                                 --this->m_depth;
00125                                 return true;
00126                         }
00127 #undef OS_INT
00128 #undef INSERT
00129 
00130 
00131 
00132                 private:
00133                         size_t m_depth;
00134                 };
00135 
00136     } // namespace io
00137 } // namespace s11n
00138 
00139 #undef INDENT
00140 
00141 #endif // compact_SERIALIZER_H_INCLUDED

Generated on Fri Nov 25 17:19:28 2005 for libs11n-1.2.0 by  doxygen 1.4.4