Scopira 20080306

traits.h

00001 
00002 /*
00003  *  Copyright (c) 2002-2010    National Research Council
00004  *
00005  *  All rights reserved.
00006  *
00007  *  This material is confidential and proprietary information of
00008  *  National Research Council Canada ("Confidential Information").
00009  *  This Confidential Information may only be used and reproduced
00010  *  in accordance with the terms of the license agreement.
00011  *
00012  */
00013 
00014 #ifndef __INCLUDED__SCOPIRA_TOOL_TRAITS_H__
00015 #define __INCLUDED__SCOPIRA_TOOL_TRAITS_H__
00016 
00017 #include <vector>
00018 
00019 #include <scopira/tool/flow.h>
00020 #include <scopira/tool/util.h>
00021 #include <scopira/tool/platform.h>
00022 
00023 namespace scopira
00024 {
00025   namespace tool
00026   {
00027     // base for traits
00028     template <class T> class flowtraits_base_g;
00029     // serialization via traits (default)
00030     template <class T> class flowtraits_g;
00031     
00032     // specializtions
00033     template <> class flowtraits_g<bool>;
00034     template <> class flowtraits_g<unsigned char>;
00035     template <> class flowtraits_g<char>;
00036     template <> class flowtraits_g<short>;
00037     template <> class flowtraits_g<int>;
00038 #ifdef PLATFORM_32
00039     template <> class flowtraits_g<long>; // no longer needed?
00040 #endif
00041     template <> class flowtraits_g<int64_t>;
00042     template <> class flowtraits_g<float>;
00043     template <> class flowtraits_g<double>;
00044 
00045     template <> class flowtraits_g<std::string>;
00046 
00047     template <class EE> class flowtraits_g<std::vector<EE> >;
00048   }
00049 }
00050 
00057 template <class T> class scopira::tool::flowtraits_base_g
00058 {
00059   public:
00060     typedef T data_type;
00061 
00062   public:
00063     template <class COL>
00064       static bool load_collection(itflow_i &in, COL &v) {
00065         typename COL::iterator ii, endii;
00066         int64_t sz;
00067 
00068         if (!in.read_int64_t(sz))
00069           return false;
00070         // or should this be changed to a clear/push_back like system to support lists, etc?
00071         v.resize(static_cast<size_t>(sz));
00072         endii = v.end();
00073         for (ii=v.begin(); ii != endii; ++ii)
00074           if (!in.read_generic(*ii))
00075             return false;
00076 
00077         return true;
00078       }
00079 
00080     template <class COL>
00081       static void save_collection(otflow_i &out, const COL &v) {
00082         typename COL::const_iterator ii, endii;
00083         int64_t sz;
00084 
00085         sz = v.size();
00086 
00087         out.write_int64_t(sz);
00088 
00089         endii = v.end();
00090         for (ii=v.begin(); ii !=endii; ++ii)
00091           out.write_generic(*ii);
00092       }
00093 };
00094 
00100 template <class T> class scopira::tool::flowtraits_g : public scopira::tool::flowtraits_base_g<T>
00101 {
00102   public:
00103     static bool load(itflow_i &in, T & outv) { return outv.load(in); }
00104     static void save(otflow_i &out, const T &v) { v.save(out); }
00105     static void to_string(const T &v, std::string &out) { out = "binary"; }
00106     static bool from_string(std::string &s, T &out) { return false; }
00107 };
00108 
00110 template <>
00111 class scopira::tool::flowtraits_g<bool> : public scopira::tool::flowtraits_base_g<bool>
00112 {
00113   public:
00114     static bool load(itflow_i &in, bool & outv) { return in.read_bool(outv); }
00115     static void save(otflow_i &out, const bool &v) { out.write_bool(v); }
00116     static void to_string(const bool &v, std::string &out) { tool::int_to_string(v,out); }
00117     static bool from_string(std::string &s, bool &out) { int i; bool b = tool::string_to_int(s,i); out= i!=0; return b; }
00118 };
00119 
00121 template <>
00122 class scopira::tool::flowtraits_g<unsigned char> : public scopira::tool::flowtraits_base_g<unsigned char>
00123 {
00124   public:
00125     static bool load(itflow_i &in, unsigned char & outv) { return in.read_byte(outv)>0; }
00126     static void save(otflow_i &out, const unsigned char &v) { out.write_byte(v); }
00127     static void to_string(const unsigned char &v, std::string &out) { tool::int_to_string(v,out); }
00128     static bool from_string(std::string &s, unsigned char &out) { int i; bool b = tool::string_to_int(s,i); out=static_cast<unsigned char>(i); return b; }
00129 };
00130 
00132 template <>
00133 class scopira::tool::flowtraits_g<char> : public scopira::tool::flowtraits_base_g<char>
00134 {
00135   public:
00136     static bool load(itflow_i &in, char & outv) { return in.read_char(outv); }
00137     static void save(otflow_i &out, const char &v) { out.write_char(v); }
00138     static void to_string(const char &v, std::string &out) { tool::int_to_string(v,out); }
00139     static bool from_string(std::string &s, char &out) { int i; bool b = tool::string_to_int(s,i); out=static_cast<char>(i); return b; }
00140 };
00141 
00143 template <>
00144 class scopira::tool::flowtraits_g<short> : public scopira::tool::flowtraits_base_g<short>
00145 {
00146   public:
00147     static bool load(itflow_i &in, short & outv) { bool b;int ii; b = in.read_int(ii); outv = ii; return b; }
00148     static void save(otflow_i &out, const short &v) { out.write_int(v); }
00149     static void to_string(const short &v, std::string &out) { tool::int_to_string(v,out); }
00150     static bool from_string(std::string &s, short &out) { int i; bool b = tool::string_to_int(s,i); out=static_cast<short>(i); return b; }
00151 };
00152 
00154 template <>
00155 class scopira::tool::flowtraits_g<int> : public scopira::tool::flowtraits_base_g<int>
00156 {
00157   public:
00158     static bool load(itflow_i &in, int & outv) { return in.read_int(outv); }
00159     static void save(otflow_i &out, const int &v) { out.write_int(v); }
00160     static void to_string(const int &v, std::string &out) { tool::int_to_string(v,out); }
00161     static bool from_string(std::string &s, int &out) { return tool::string_to_int(s,out); }
00162 };
00163 
00166 #ifdef PLATFORM_32
00167 template <>
00168 class scopira::tool::flowtraits_g<long> : public scopira::tool::flowtraits_base_g<long>
00169 {
00170   public:
00171     static bool load(itflow_i &in, long & outv) { return in.read_long(outv); }
00172     static void save(otflow_i &out, const long &v) { out.write_long(v); }
00173     static void to_string(const long &v, std::string &out) { tool::long_to_string(v,out); }
00174     static bool from_string(std::string &s, long &out) { return tool::string_to_long(s,out); }
00175 };
00176 #endif
00177 
00179 template <>
00180 class scopira::tool::flowtraits_g<int64_t> : public scopira::tool::flowtraits_base_g<int64_t>
00181 {
00182   public:
00183     static bool load(itflow_i &in, int64_t & outv) { return in.read_int64_t(outv); }
00184     static void save(otflow_i &out, const int64_t &v) { out.write_int64_t(v); }
00185     static void to_string(const int64_t &v, std::string &out) { tool::int64_t_to_string(v,out); }
00186     static bool from_string(std::string &s, int64_t &out) { return tool::string_to_int64_t(s,out); }
00187 };
00188 
00190 template <>
00191 class scopira::tool::flowtraits_g<float> : public scopira::tool::flowtraits_base_g<float>
00192 {
00193   public:
00194     static bool load(itflow_i &in, float & outv) { return in.read_float(outv); }
00195     static void save(otflow_i &out, const float &v) { out.write_float(v); }
00196     static void to_string(const float &v, std::string &out) { tool::double_to_string(v,out); }
00197     static bool from_string(std::string &s, float &out) { double i; bool b = tool::string_to_double(s,i); out=static_cast<float>(i); return b; }
00198 };
00199 
00201 template <>
00202 class scopira::tool::flowtraits_g<double> : public scopira::tool::flowtraits_base_g<double>
00203 {
00204   public:
00205     static bool load(itflow_i &in, double & outv) { return in.read_double(outv); }
00206     static void save(otflow_i &out, const double &v) { out.write_double(v); }
00207     static void to_string(const double &v, std::string &out) { tool::double_to_string(v,out); }
00208     static bool from_string(std::string &s, double &out) { return tool::string_to_double(s,out); }
00209 };
00210 
00211 
00212 // basic object specializations
00213 template <>
00214 class scopira::tool::flowtraits_g<std::string> : public scopira::tool::flowtraits_base_g<std::string>
00215 {
00216   public:
00217     static bool load(itflow_i &in, std::string & outv) { return in.read_string(outv); }
00218     static void save(otflow_i &out, const std::string &v) { out.write_string(v); }
00219     static void to_string(const std::string &v, std::string &out) { out = v; }
00220     static bool from_string(std::string &s, std::string &out) { out = s; return true; }
00221 };
00222 
00223 
00224 // some specializations of STL containers
00225 template <class EE>
00226 class scopira::tool::flowtraits_g<std::vector<EE> > : public scopira::tool::flowtraits_base_g<std::vector<EE> >
00227 {
00228   public:
00229     static bool load(itflow_i &in, std::vector<EE> & outv) { return load_collection(in, outv); }
00230     static void save(otflow_i &out, const std::vector<EE> &v) { save_collection(out, v); }
00231     static void to_string(const std::vector<EE> &v, std::string &out) { out = "std::vector<EE>"; }
00232     static bool from_string(std::string &s, std::vector<EE> &out) { return false; }
00233 };
00234 
00235 //
00236 // implementation of some stuff in flow.h to avoid circular refs
00237 //
00238 
00239 template <class TT>
00240 inline bool scopira::tool::itflow_i::read_generic(TT &v)
00241 {
00242   return scopira::tool::flowtraits_g<TT>::load(*this, v);
00243 }
00244 
00245 template <class TT>
00246 inline void scopira::tool::otflow_i::write_generic(const TT &v)
00247 {
00248   scopira::tool::flowtraits_g<TT>::save(*this, v);
00249 }
00250 
00251 #endif
00252