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

compact_serializer.h

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

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