valarray.hpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////
00002 // valarray.hpp: s11n algos/proxies for handling std::valarray objects.
00003 // This header is not included by default: clients who want to de/serialize
00004 // valarrays must include it themselves.
00005 ////////////////////////////////////////////////////////////////////////
00006 #ifndef s11n_VALARRAY_HPP_INCLUDED
00007 #define s11n_VALARRAY_HPP_INCLUDED 1
00008 
00009 #include <stdio.h> // snprintf()
00010 #include <valarray>
00011 #include <s11n.net/s11n/variant.hpp> // for lexical casting
00012 
00013 namespace s11n {
00014 
00015         /**
00016            s11n::va encapsulates de/serialization operators for
00017            std::valarray objects.
00018         */
00019         namespace va {
00020 
00021                 /**
00022                    Serializes src to dest. Returns true on success,
00023                    false on error. VAT must be a std::valarray type
00024                    with a numeric value_type.
00025 
00026            Always returns true.
00027 
00028            Each entry is stored as a key/value pair in src,
00029            which means this algorithm works with all
00030            iostreamable contained types. Since valarray is
00031            intended for use with numbers, this should be
00032            appropriate for all cases.
00033 
00034            To avoid entering numeric keys into dest, which don't
00035            work with XML serializers, and to keep proper ordering of
00036            the keys, it synthesizes sequential numbers, preceded by
00037            an 'x', for use as keys. The number of digits in the keys
00038            is calculated based off of src.size().
00039 
00040            This function never returns false, but will throw if
00041            src has more than some arbitrarily large number of items
00042            (at least 64 bits worth), due to a minor detail you can
00043            read about in the source code.
00044 
00045            ACHTUNG: precision of doubles in limited to
00046            whatever default is used by s11n for lexical
00047            casting via iostreams.
00048                 */
00049                 template <typename NodeT, typename VAT>
00050                 bool serialize_valarray( NodeT & dest, const VAT & src )
00051                 {
00052                         typedef s11n::node_traits<NodeT> TR;
00053                         TR::class_name( dest, ::s11n::s11n_traits<VAT>::class_name(&src) );
00054                         const int buffsize = 9; // leaves us with 8 hex digits, which is more than your system can hold in one valarray, i would think.
00055                         char num[buffsize];
00056                         char fmt[buffsize];
00057                         size_t sz = src.size();
00058                         int places = 1; // # of digits to use
00059                         for( ; sz >= 0x0f; sz = (size_t)(sz/0x0f)) { ++places; }
00060             if( places > (buffsize-1) )
00061             {
00062                 throw ::s11n::s11n_exception( "%s:%d: Internal error: overflow in serialize_valarray(). Too many items in valarray.", __FILE__,__LINE__);
00063             }
00064                         snprintf( fmt, buffsize, "x%%0%dx", places ); // e.g. 5 digits evals to "x%05x"
00065                         sz = src.size();
00066                         TR::set( dest, "size", sz );
00067                         for( size_t i = 0 ; i < sz; i++ )
00068                         {
00069                                 snprintf( num, buffsize, fmt, i );
00070                                 TR::set( dest, num, src[i] );
00071                         }
00072                         return true;
00073                 }
00074 
00075                 /**
00076                    Deserializes dest from src. Returns true on
00077                    success, false on error. VAT must be a
00078                    std::valarray type with a numeric value_type.
00079 
00080            Always returns true.
00081                 */
00082                 template <typename NodeT, typename VAT>
00083                 bool deserialize_valarray( const NodeT & src, VAT & dest )
00084                 {
00085                         typedef ::s11n::node_traits<NodeT> TR;
00086                         typedef typename VAT::value_type VT;
00087                         typename TR::property_map_type::const_iterator it = TR::properties(src).begin();
00088             typename TR::property_map_type::const_iterator et = TR::properties(src).end();
00089                         const static std::string szkey = "size";
00090                         size_t size = TR::get( src, szkey, dest.size() );
00091                         VT defaultval;
00092                         dest.resize( size, defaultval );
00093                         size_t i = 0;
00094                         for( ; et != it; ++it )
00095                         {
00096                                 if( szkey == (*it).first ) continue;
00097                                 dest[i++] = ::s11n::Detail::variant( (*it).second ).template cast_to<VT>( defaultval );
00098                         }
00099                         return true;
00100                 }
00101 
00102                 /**
00103                    A Serializable proxy for valarray types.
00104                 */
00105                 struct valarray_serializable_proxy
00106                 {
00107 
00108                         valarray_serializable_proxy()
00109                         {}
00110 
00111                         /**
00112                            see serialize_valarray().
00113 
00114                         */
00115                         template <typename NodeType, typename SerType>
00116                         bool operator()( NodeType & dest, const SerType & src ) const
00117                         {
00118                                 return serialize_valarray( dest, src );
00119                         }
00120 
00121                         /** see deserialize_valarray(). */
00122                         template <typename NodeType, typename SerType>
00123                         bool operator()( const NodeType & src, SerType & dest ) const
00124                         {
00125                                 return deserialize_valarray( src, dest );
00126                         }
00127                 };
00128 
00129         } // namespace va
00130 
00131 
00132 
00133         /**
00134            s11n_traits<> specialization for std::valarray types.
00135         */
00136         template <typename ValueType>
00137         struct s11n_traits < std::valarray<ValueType> >
00138         {
00139                 typedef std::valarray<ValueType> serializable_type;
00140                 typedef ::s11n::va::valarray_serializable_proxy serialize_functor;
00141                 typedef serialize_functor deserialize_functor;
00142                 typedef ::s11n::cl::object_factory<serializable_type> factory_type;
00143         typedef ::s11n::default_cleanup_functor<serializable_type> cleanup_functor;
00144                 static bool cl_reg_placeholder;
00145         static std::string class_name( const serializable_type * instance_hint )
00146         {
00147             if( cl_reg_placeholder == true ); // just to reference it. w/o this cl reg never happens :(
00148             return "valarray";
00149         }
00150         };
00151 
00152     template <typename VT>
00153     bool s11n_traits< std::valarray< VT > >::cl_reg_placeholder =
00154         (
00155          ::s11n::cl::classloader_register_base<std::valarray< VT > >( s11n_traits< std::valarray< VT > >::class_name(0) )
00156          , 0 );
00157 
00158 
00159 } // namespace s11n
00160 
00161 
00162 
00163 #endif // s11n_VALARRAY.HPP_HPP_INCLUDED

Generated on Wed Jun 4 21:45:18 2008 for libs11n by  doxygen 1.5.3