00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #ifdef _WINDOWS
00029 #define strcasecmp _stricmp
00030 #endif
00031 
00032 #ifndef __LDK_XMLBIND_HH__
00033 #define __LDK_XMLBIND_HH__
00034 
00035 #include "LDK/XML.h"
00036 #include "LDK/SStream.h"
00037 #include "LDK/Threading.h"
00038 #include <vector>
00039 #include <list>
00040 #include <string.h>
00041 
00042 namespace LDK
00043 {
00044 
00045 class LDK_API IdentityBase
00046 {
00047 };
00048 
00049 template<class T>
00050 class Identity : public IdentityBase
00051 {
00052 public:
00053     typedef T type;
00054 
00055 };
00056 
00057 enum MemberSerializeFlags
00058 {
00059     MemberSerializeFlagsNone = 0,
00060     MemberOptional = 1,
00061 };
00062 
00063 class LDK_API Tag
00064 {
00065 public:
00066     
00067     char const * tag_[3];
00068 
00069     Tag(char const * tagOne = NULL)
00070     {
00071         tag_[0] = tagOne;
00072         tag_[1] = NULL;
00073         tag_[2] = NULL;
00074     }
00075 
00076     Tag(char const * tagOne, char const * tagTwo)
00077     {
00078         tag_[0] = tagOne;
00079         tag_[1] = tagTwo;
00080         tag_[2] = NULL;
00081     }
00082 
00083     Tag(char const * tagOne, char const * tagTwo, char const * tagThree)
00084     {
00085         tag_[0] = tagOne;
00086         tag_[1] = tagTwo;
00087         tag_[2] = tagThree;
00088     }
00089 };
00090 
00091 struct LDK_API SerializeParams
00092 {
00093     Tag tag_;
00094 };
00095 
00096 
00097 
00098 template<class T>
00099 class XmlBinding
00100 {
00101 public:
00102     virtual ~XmlBinding() {}
00103     virtual bool fromXml(XmlElement const & elem, T * data, SerializeParams const &) const = 0;
00104     virtual bool intoXml(XmlElement * elem, T const & data, SerializeParams const &) const = 0;
00105 };
00106 
00107 template<class T>
00108 bool BindToXml(XmlElement * elemOut, T const & dataIn)
00109 {
00110     SmartPointer<XmlBinding<T> > binding = GetXmlBinding( dataIn, Identity<T>() );
00111     SerializeParams params;
00112     return binding->intoXml( elemOut, dataIn, params );
00113 }
00114 
00115 template<class T>
00116 bool BindFromXml( XmlElement const & elemIn, T * dataOut )
00117 {
00118     SmartPointer<XmlBinding<T> > binding = GetXmlBinding( *dataOut, Identity<T>() );
00119     SerializeParams params;
00120     return binding->fromXml( elemIn, dataOut, params );
00121 }
00122 
00123 
00124 template<class T>
00125 class IMemberHolder
00126 {
00127 public:
00128     MemberSerializeFlags flags_;
00129     Tag tag_;
00130     SerializeParams params_;
00131 
00132     void setFlags( MemberSerializeFlags f )
00133     {
00134         flags_ = f;
00135     }
00136 
00137     SerializeParams const & params()
00138     {
00139         params_.tag_ = tag_;
00140         return params_;
00141     }
00142 
00143     virtual char const * tag( int which = 0) { return tag_.tag_[which]; }
00144 
00145     virtual bool fromXml( XmlElement const &, T * ) = 0;
00146     virtual bool intoXml( XmlElement *, T const * ) = 0;
00147     virtual bool isAttributeMember() = 0;
00148 };
00149 
00150 template<class T, class MT>
00151 class IMemberValuePolicy
00152 {
00153 public:
00154     virtual MT getMemberValue( T const * thisPtr ) = 0;
00155     virtual void setMemberValue( T * thisPtr, MT const & mv ) = 0;
00156 };
00157 
00158 
00159 template<class T, class MT>
00160 class MemberFuncHolder : public IMemberValuePolicy<T, MT>
00161 {
00162 public:
00163     MT (T::*getter_)();
00164     void (T::*setter_)(MT);
00165 
00166     virtual MT getMemberValue( T const * thisPtr )
00167     {
00168         return (const_cast<T*>(thisPtr)->*getter_)();
00169     }
00170 
00171     virtual void setMemberValue( T * thisPtr, MT const & mv )
00172     {
00173         (thisPtr->*setter_)(mv);
00174     }
00175 };
00176 
00177 template<class T, class MT>
00178 class MemberFuncHolderConstRef  : public IMemberValuePolicy<T, MT>
00179 {
00180 public:
00181   MT const & (T::*getter_)();
00182   void (T::*setter_)(MT const &);
00183 
00184     virtual MT getMemberValue( T const * thisPtr )
00185     {
00186         return (thisPtr->*getter_)();
00187     }
00188 
00189     virtual void setMemberValue( T * thisPtr, MT const & mv )
00190     {
00191         (thisPtr->*setter_)(mv);
00192     }
00193 };
00194 
00195 template<class T, class MT>
00196 class MemberPtrHolder : public IMemberValuePolicy<T, MT>
00197 {
00198 public:
00199     MT T::*memberPtr_;
00200     virtual MT getMemberValue( T const * thisPtr ) { return thisPtr->*memberPtr_; }
00201     virtual void setMemberValue( T * thisPtr, MT const & mv )
00202     {
00203         
00204         thisPtr->*memberPtr_ = const_cast<MT &>(mv);
00205     }
00206 };
00207 
00208 
00209 template<class T, class MT>
00210 class MemberRefFuncHolder : public IMemberValuePolicy<T, MT>
00211 {
00212 public:
00213     MT & (T::*memberRefFunc_)();
00214     virtual MT getMemberValue( T const * thisPtr ) { return (const_cast<T*>(thisPtr)->*memberRefFunc_)(); }
00215     virtual void setMemberValue( T * thisPtr, MT const & mv ) { (thisPtr->*memberRefFunc_)() = mv; }
00216 };
00217 
00218 
00219 template<class T, class MT>
00220 class FromXmlElement : public IMemberHolder<T>
00221 {
00222 public:
00223 
00224     IMemberValuePolicy<T, MT> * mvPolicy_;
00225     FromXmlElement( IMemberValuePolicy<T, MT> * mvPolicy )
00226     {
00227         mvPolicy_ = mvPolicy;
00228     }
00229 
00230     virtual bool fromXml( XmlElement const & elem, T * thisPtr)
00231     {
00232         MT  mv = mvPolicy_->getMemberValue(thisPtr);
00233         SmartPointer<XmlBinding<MT> > binding = GetXmlBinding( mv,  Identity<MT>()  );
00234         if( binding->fromXml(elem, &mv, IMemberHolder<T>::params()) )
00235         {
00236             mvPolicy_->setMemberValue(thisPtr, mv);
00237             return true;
00238         }
00239         return false;
00240     }
00241 
00242     virtual bool intoXml( XmlElement * elem, T const * thisPtr)
00243     {
00244         MT const & mv = mvPolicy_->getMemberValue(thisPtr);
00245         SmartPointer<XmlBinding<MT> > binding = GetXmlBinding( mv,  Identity<MT>() );
00246         String oldValue = elem->Value();
00247         elem->SetValue( IMemberHolder<T>::tag() );
00248         bool ret = binding->intoXml( elem, mv, IMemberHolder<T>::params() );
00249         elem->SetValue( oldValue );
00250         return ret;
00251     }
00252 
00253     virtual bool isAttributeMember() { return true; }
00254 };
00255 
00256 
00257 template<class T, class MT, class FromXmlPolicy, class MemberValuePolicy>
00258 class MemberHolder
00259 {
00260 public:
00261     FromXmlPolicy xmlPolicy_;
00262     MemberValuePolicy mvPolicy_;
00263 
00264     MemberHolder()
00265     : xmlPolicy_((IMemberValuePolicy<T, MT> *)&mvPolicy_)
00266     {
00267     }
00268 };
00269 
00270 
00271 template<class T, class MT>
00272 class FromXmlChildElement : public IMemberHolder<T>
00273 {
00274 public:
00275     IMemberValuePolicy<T, MT> * mvPolicy_;
00276     FromXmlChildElement( IMemberValuePolicy<T, MT> * mvPolicy )
00277     {
00278         mvPolicy_ = mvPolicy;
00279     }
00280 
00281     virtual bool fromXml( XmlElement const & elem, T * thisPtr)
00282     {
00283         if( !strcasecmp(elem.Value(), IMemberHolder<T>::tag()) )
00284         {
00285             MT mv;
00286             SmartPointer<XmlBinding<MT> > binding = GetXmlBinding( mv,  Identity<MT>()  );
00287             if( binding->fromXml(elem, &mv, IMemberHolder<T>::params()) )
00288             {
00289                 mvPolicy_->setMemberValue(thisPtr, mv);
00290                 return true;
00291             }
00292             return false;
00293         }
00294         return false;
00295     }
00296 
00297     virtual bool intoXml( XmlElement * elem, T const * thisPtr)
00298     {
00299         MT const & mv = mvPolicy_->getMemberValue(thisPtr);
00300         XmlElement child(IMemberHolder<T>::tag());
00301         SmartPointer<XmlBinding<MT> > binding = GetXmlBinding( mv, Identity<MT>()  );
00302         if( binding->intoXml( &child, mv, IMemberHolder<T>::params() ) )
00303         {
00304             elem->InsertEndChild(child);
00305             return true;
00306         }
00307         return false;
00308     }
00309 
00310     virtual bool isAttributeMember() { return false; }
00311 };
00312 
00313 template<class T, class MT>
00314 class FromXmlAttribute  : public IMemberHolder<T>
00315 {
00316 public:
00317     IMemberValuePolicy<T, MT> * mvPolicy_;
00318     FromXmlAttribute( IMemberValuePolicy<T, MT> * mvPolicy )
00319     {
00320         mvPolicy_ = mvPolicy;
00321     }
00322 
00323     virtual bool fromXml( XmlElement const & elem, T * thisPtr)
00324     {
00325         MT mv;
00326         const char * attributeValue = elem.Attribute( IMemberHolder<T>::tag() );
00327         if( attributeValue && *attributeValue )
00328         {
00329             StringStream strm;
00330             strm << attributeValue;
00331             strm >> mv;
00332             mvPolicy_->setMemberValue(thisPtr, mv);
00333             return true;
00334         }
00335         return false;
00336     }
00337 
00338     virtual bool intoXml( XmlElement * elem, T const * thisPtr)
00339     {
00340         MT const & mv = mvPolicy_->getMemberValue(thisPtr);
00341         StringStream strm;
00342         strm << mv;
00343         elem->SetAttribute( IMemberHolder<T>::tag(), strm.str() );
00344         return true;
00345     }
00346 
00347     virtual bool isAttributeMember() { return true; }
00348 };
00349 
00350 template<class T, class MT>
00351 IMemberHolder<T> * Member(  MT T::*mp )
00352 {
00353     typedef FromXmlChildElement<T, MT> XmlPolicy;
00354     typedef MemberPtrHolder<T, MT> MemberValuePolicy;
00355     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00356     MH_Type * mph = LDK_CREATE0(MH_Type);
00357     mph->mvPolicy_.memberPtr_ = mp;
00358     return &mph->xmlPolicy_;
00359 }
00360 
00361 template<class T, class MT>
00362 IMemberHolder<T> * Member(MT & (T::*mp)() )
00363 {
00364     typedef FromXmlChildElement<T, MT> XmlPolicy;
00365     typedef MemberRefFuncHolder<T, MT> MemberValuePolicy;
00366     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00367     MH_Type * mph = LDK_CREATE0(MH_Type);
00368     mph->mvPolicy_.memberRefFunc_ = mp;
00369     return &mph->xmlPolicy_;
00370 }
00371 
00372 template<class T, class MT>
00373 IMemberHolder<T> * Member(  MT (T::*getter)(), void (T::*setter)(MT) )
00374 {
00375     typedef FromXmlChildElement<T, MT> XmlPolicy;
00376     typedef MemberFuncHolder<T, MT> MemberValuePolicy;
00377     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00378     MH_Type * mph = LDK_CREATE0(MH_Type);
00379     mph->mvPolicy_.getter_ = getter;
00380     mph->mvPolicy_.setter_ = setter;
00381     return &mph->xmlPolicy_;
00382 }
00383 
00384 template<class T, class MT>
00385 IMemberHolder<T> * Member(  MT (T::*getter)()const, void (T::*setter)(MT) )
00386 {
00387     typedef FromXmlChildElement<T, MT> XmlPolicy;
00388     typedef MemberFuncHolder<T, MT> MemberValuePolicy;
00389     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00390     MH_Type * mph = LDK_CREATE0(MH_Type);
00391     mph->mvPolicy_.getter_ = (MT (T::*)())getter;
00392     mph->mvPolicy_.setter_ = setter;
00393     return &mph->xmlPolicy_;
00394 }
00395 
00396 template<class T, class MT>
00397 IMemberHolder<T> * Member
00398 (
00399     MT const & (T::*getter)(),
00400     void (T::*setter)(MT const &)
00401 )
00402 {
00403     typedef FromXmlChildElement<T, MT> XmlPolicy;
00404     typedef MemberFuncHolderConstRef<T, MT> MemberValuePolicy;
00405     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00406     MH_Type * mph = LDK_CREATE0(MH_Type);
00407     mph->mvPolicy_.getter_ = getter;
00408     mph->mvPolicy_.setter_ = setter;
00409     return &mph->xmlPolicy_;
00410 }
00411 
00412 
00413 template<class T, class MT>
00414 IMemberHolder<T> * MemberAttribute(  MT T::*mp )
00415 {
00416     typedef FromXmlAttribute<T, MT> XmlPolicy;
00417     typedef MemberPtrHolder<T, MT> MemberValuePolicy;
00418     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00419     MH_Type * mph = LDK_CREATE0(MH_Type);
00420     mph->mvPolicy_.memberPtr_ = mp;
00421     return &mph->xmlPolicy_;
00422 }
00423 
00424 template<class T, class MT>
00425 IMemberHolder<T> * MemberAttribute(  MT (T::*getter)(), void (T::*setter)(MT) )
00426 {
00427     typedef FromXmlAttribute<T, MT> XmlPolicy;
00428     typedef MemberFuncHolder<T, MT> MemberValuePolicy;
00429     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00430     MH_Type * mph = LDK_CREATE0(MH_Type);
00431     mph->mvPolicy_.getter_ = getter;
00432     mph->mvPolicy_.setter_ = setter;
00433     return &mph->xmlPolicy_;
00434 }
00435 
00436 template<class T, class MT>
00437 IMemberHolder<T> * MemberAttribute(  MT (T::*getter)() const, void (T::*setter)(MT) )
00438 {
00439     typedef FromXmlAttribute<T, MT> XmlPolicy;
00440     typedef MemberFuncHolder<T, MT> MemberValuePolicy;
00441     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00442     MH_Type * mph = LDK_CREATE0(MH_Type);
00443     mph->mvPolicy_.getter_ = (MT (T::*)())getter;
00444     mph->mvPolicy_.setter_ = setter;
00445     return &mph->xmlPolicy_;
00446 }
00447 
00448 template<class T, class MT>
00449 IMemberHolder<T> * MemberAttribute
00450 (
00451     MT const & (T::*getter)(),
00452     void (T::*setter)(MT const &)
00453 )
00454 {
00455     typedef FromXmlAttribute<T, MT> XmlPolicy;
00456     typedef MemberFuncHolderConstRef<T, MT> MemberValuePolicy;
00457     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00458     MH_Type * mph = LDK_CREATE0(MH_Type);
00459     mph->mvPolicy_.getter_ = getter;
00460     mph->mvPolicy_.setter_ = setter;
00461     return &mph->xmlPolicy_;
00462 }
00463 
00464 
00465 
00466 template<class T, class MT>
00467 IMemberHolder<T> * MemberPeer(  MT T::*mp )
00468 {
00469     typedef FromXmlElement<T, MT> XmlPolicy;
00470     typedef MemberPtrHolder<T, MT> MemberValuePolicy;
00471     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00472     MH_Type * mph = LDK_CREATE0(MH_Type);
00473     mph->mvPolicy_.memberPtr_ = mp;
00474     return &mph->xmlPolicy_;
00475 }
00476 
00477 template<class T, class MT>
00478 IMemberHolder<T> * MemberPeer(  MT (T::*getter)(), void (T::*setter)(MT) )
00479 {
00480     typedef FromXmlElement<T, MT> XmlPolicy;
00481     typedef MemberFuncHolder<T, MT> MemberValuePolicy;
00482     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00483     MH_Type * mph = LDK_CREATE0(MH_Type);
00484     mph->mvPolicy_.getter_ = getter;
00485     mph->mvPolicy_.setter_ = setter;
00486     return &mph->xmlPolicy_;
00487 }
00488 
00489 template<class T, class MT>
00490 IMemberHolder<T> * MemberPeer
00491 (
00492     MT const & (T::*getter)(),
00493     void (T::*setter)(MT const &)
00494 )
00495 {
00496     typedef FromXmlElement<T, MT> XmlPolicy;
00497     typedef MemberFuncHolderConstRef<T, MT> MemberValuePolicy;
00498     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00499     MH_Type * mph = LDK_CREATE0(MH_Type);
00500     mph->mvPolicy_.getter_ = getter;
00501     mph->mvPolicy_.setter_ = setter;
00502     return &mph->xmlPolicy_;
00503 }
00504 
00505 template<class T, class MT>
00506 IMemberHolder<T> * MemberPeer(MT & (T::*mp)() )
00507 {
00508     typedef FromXmlElement<T, MT> XmlPolicy;
00509     typedef MemberRefFuncHolder<T, MT> MemberValuePolicy;
00510     typedef MemberHolder<T, MT, XmlPolicy, MemberValuePolicy> MH_Type;
00511     MH_Type * mph = LDK_CREATE0(MH_Type);
00512     mph->mvPolicy_.memberRefFunc_ = mp;
00513     return &mph->xmlPolicy_;
00514 }
00515 
00516 
00517 
00518 template<class T>
00519 class MemberXmlBinding : public XmlBinding<T>
00520 {
00521 private:
00522     std::vector<IMemberHolder<T>*> members_;
00523 
00524 public:
00525     virtual ~MemberXmlBinding()
00526     {
00527         for(size_t i=0;i<members_.size();i++)
00528         {
00529             LDK::destroy(members_[i]);
00530         }
00531     }
00532 
00533     bool empty() const
00534     {
00535         return members_.empty();
00536     }
00537 
00538     IMemberHolder<T> * AddMember( Tag tag, IMemberHolder<T> * mph )
00539     {
00540         mph->flags_ = MemberSerializeFlagsNone;
00541         mph->tag_ = tag;
00542         members_.push_back( mph );
00543         return mph;
00544     }
00545 
00546     virtual bool fromXml( XmlElement const & elem, T * data, SerializeParams const & params ) const
00547     {
00548         XmlElement const * child = elem.FirstChildElement();
00549         for( size_t i = 0; i < members_.size(); i++ )
00550         {
00551             IMemberHolder<T> * mph = members_[i];
00552             bool error = false;
00553 
00554             bool ret;
00555             if( mph->isAttributeMember() )
00556             {
00557                 ret = mph->fromXml( elem, data );
00558             }
00559             else
00560             {
00561                 if( !child )
00562                 {
00563                     return false;
00564                 }
00565                 ret = mph->fromXml( *child, data );
00566             }
00567             error = !ret;
00568             if( mph->isAttributeMember() ) {} 
00569             else if( !error )
00570             {
00571                 child = child->NextSiblingElement();
00572             }
00573 
00574             if( error )
00575             {
00576                 if( mph->isAttributeMember() )
00577                 {
00578                     
00579                     continue;
00580                 }
00581                 else
00582                 {
00583                     
00584                     return false;
00585                 }
00586             }
00587         }
00588         return true;
00589     }
00590 
00591     virtual bool intoXml( XmlElement * elem, T const & data, SerializeParams const & ) const
00592     {
00593         for( size_t i = 0; i < members_.size(); i++ )
00594         {
00595             IMemberHolder<T> * mph = members_[i];
00596             mph->intoXml( elem, &data );
00597         }
00598         return true;
00599     }
00600 };
00601 
00602 template<class T>
00603 class GenericXmlBinding : public XmlBinding<T>
00604 {
00605 public:
00606     virtual bool fromXml( XmlElement const & elem, T * data, SerializeParams const & ) const
00607     {
00608         const XmlNode * node = elem.FirstChild();
00609         const XmlText * nodedata = node->ToText();
00610         StringStream strm;
00611         strm << nodedata->Value();
00612         strm >> *data;
00613         return true;
00614     }
00615 
00616     virtual bool intoXml( XmlElement * elem, T const & data, SerializeParams const & ) const
00617     {
00618         StringStream strm;
00619         strm << data;
00620         XmlText textData( strm.str() );
00621         elem->InsertEndChild( textData );
00622         return true;
00623     }
00624 };
00625 
00626 #ifdef _MSC_VER
00627 #pragma warning (default : 4251)
00628 #endif
00629 
00630 template<>
00631 class LDK_API GenericXmlBinding<const char*> : public XmlBinding<const char*>
00632 {
00633 static TLSKey mKey;
00634 static bool mInitialised;
00635 static Mutex mMutex;
00636 
00637     static void dtor(void* tls)
00638     {
00639         LDK::destroy(reinterpret_cast<std::string*>(tls));
00640     }
00641 public:
00642     GenericXmlBinding()
00643     {
00644         Lock lock(mMutex);
00645         if(!mInitialised)
00646         {
00647             mKey = threadLocalCreateKey(dtor);
00648             mInitialised = true;
00649         }
00650     }
00651     virtual bool fromXml( XmlElement const & elem, const char ** data, SerializeParams const & ) const
00652     {
00653         if(!mInitialised)
00654             Lock lock(mMutex);
00655         const XmlNode * node = elem.FirstChild();
00656         const XmlText * nodedata = node->ToText();
00657 
00658         std::string* strHolder = reinterpret_cast<std::string*>(threadLocalGet(mKey));
00659         if(!strHolder)
00660         {
00661             strHolder = new std::string;
00662             threadLocalSet(mKey,strHolder);
00663         }
00664         *strHolder = nodedata->Value();;
00665         *data = strHolder->c_str();
00666         return true;
00667     }
00668 
00669     virtual bool intoXml( XmlElement * elem, const char* const & data, SerializeParams const & ) const
00670     {
00671         if(!mInitialised)
00672             Lock lock(mMutex);
00673         StringStream strm;
00674         strm << data;
00675         XmlText textData( strm.str() );
00676         elem->InsertEndChild( textData );
00677         return true;
00678     }
00679 };
00680 
00681 template<class T, class VecT>
00682 class StlContainerXmlBinding : public XmlBinding<VecT>
00683 {
00684 public:
00685 
00686     char const * subTag_;
00687     bool useSubTag_;
00688     char const * sizeAttributeName_;
00689 
00690     StlContainerXmlBinding(bool useSubTag, char const * st = NULL, char const * sizeAttributeName = NULL)
00691     :subTag_(st), useSubTag_(useSubTag), sizeAttributeName_(sizeAttributeName)
00692     {
00693     }
00694 
00695     virtual bool fromXml( XmlElement const & elem, VecT * data, SerializeParams const & params ) const
00696     {
00697         data->clear();
00698         XmlElement const * child;
00699         child = elem.FirstChildElement();
00700         if( sizeAttributeName_ )
00701         {
00702             int sz = 0;
00703             StringStream strm;
00704             strm << sizeAttributeName_;
00705             strm >> sz;
00706 
00707             if( sz )
00708             {
00709                 
00710             }
00711         }
00712 
00713         T value;
00714         while(child)
00715         {
00716             SmartPointer<XmlBinding<T> > binding = GetXmlBinding( value,  Identity<T>()  );
00717             bool ret = binding->fromXml( *child, &value, params );
00718             data->push_back(value);
00719             if( ! ret )
00720             {
00721                 return false;
00722             }
00723             child = child->NextSiblingElement();
00724         }
00725         return true;
00726     }
00727 
00728     virtual bool intoXml( XmlElement * elem, VecT const & data, SerializeParams const & params ) const
00729     {
00730         if( sizeAttributeName_ )
00731         {
00732             StringStream strm;
00733             strm << data.size();
00734             elem->SetAttribute( sizeAttributeName_, strm.str() );
00735         }
00736         for( typename VecT::const_iterator i = data.begin(); i != data.end(); i++ )
00737         {
00738             T const & value = *i;
00739             SmartPointer<XmlBinding<T> > binding = GetXmlBinding( value,  Identity<T>()  );
00740             char const * tag;
00741             if( useSubTag_ )
00742             {
00743                 tag = subTag_;
00744             }
00745             else
00746             {
00747                 tag = elem->Value();
00748             }
00749             XmlElement child(tag);
00750             if( ! binding->intoXml( &child, value, params ) )
00751             {
00752                 return false;
00753             }
00754             elem->InsertEndChild(child);
00755         }
00756         return true;
00757     }
00758   };
00759 
00760 template<class T, class VecT>
00761 class StlContainerPtrBinding : public XmlBinding<VecT>
00762 {
00763 public:
00764 
00765     char const * subTag_;
00766     bool useSubTag_;
00767     char const * sizeAttributeName_;
00768     StlContainerPtrBinding(bool useSubTag, char const * st = NULL, char const * sizeAttributeName = NULL)
00769     :subTag_(st), useSubTag_(useSubTag), sizeAttributeName_(sizeAttributeName)
00770     {
00771     }
00772 
00773     virtual bool fromXml( XmlElement const & elem, VecT * data, SerializeParams const & params ) const
00774     {
00775         data->clear();
00776         XmlElement const * child;
00777         child = elem.FirstChildElement();
00778         if( sizeAttributeName_ )
00779         {
00780             int sz = 0;
00781             StringStream strm;
00782             strm << sizeAttributeName_;
00783             strm >> sz;
00784             if( sz )
00785             {
00786                 
00787             }
00788         }
00789         while(child)
00790         {
00791             T * value = LDK_CREATE0(T);
00792             if( !value->create() )
00793             {
00794                 return false;
00795             }
00796             SmartPointer<XmlBinding<T> > binding = GetXmlBinding( *value,  Identity<T>()  );
00797             bool ret = binding->fromXml( *child, value, params );
00798             data->push_back(value);
00799             if( ! ret )
00800             {
00801                 return false;
00802             }
00803             child = child->NextSiblingElement();
00804         }
00805         return true;
00806     }
00807 
00808     virtual bool intoXml( XmlElement * elem, VecT const & data, SerializeParams const & params ) const
00809     {
00810         if( sizeAttributeName_ )
00811         {
00812             StringStream strm;
00813             strm << data.size();
00814             elem->SetAttribute( sizeAttributeName_, strm.str() );
00815         }
00816         for( typename VecT::const_iterator i = data.begin(); i != data.end(); i++ )
00817         {
00818             T const * value = *i;
00819             if( ! value )
00820             {
00821                 continue;
00822             }
00823             SmartPointer<XmlBinding<T> > binding = GetXmlBinding( *value,  Identity<T>()  );
00824             char const * tag;
00825             if( useSubTag_ )
00826             {
00827                 tag = subTag_;
00828             }
00829             else
00830             {
00831                 tag = elem->Value();
00832             }
00833             XmlElement child(tag);
00834             if( ! binding->intoXml( &child, *value, params ) )
00835             {
00836                 return false;
00837             }
00838             elem->InsertEndChild(child);
00839         }
00840         return true;
00841     }
00842 };
00843 
00844 
00845 template<class T>
00846 XmlBinding<T>*
00847 GetXmlBinding( T const &, IdentityBase  )
00848 {
00849     return LDK_CREATE0(GenericXmlBinding<T>);
00850 }
00851 
00852 template<class T, class VecT>
00853 XmlBinding<VecT>*
00854 GetXmlBinding( std::vector<T> const &, Identity<VecT>  )
00855 {
00856     typedef StlContainerXmlBinding<T,VecT> Bind;
00857     return LDK_CREATE1(Bind,false);
00858 }
00859 
00860 
00861 template<class T, class VecT>
00862 XmlBinding<VecT>*
00863 GetXmlBinding( std::list<T> const &, Identity<VecT>  )
00864 {
00865     typedef StlContainerXmlBinding<T,VecT> Bind;
00866     return LDK_CREATE1(Bind,false);
00867 }
00868 
00869 }
00870 
00871 
00872 #endif //__LDK_XMLBIND_HH__