XMLSerialisation.h

00001 /*
00002 www.sourceforge.net/projects/tinybind
00003 Original code copyright (c) 2004 IMVU, Inc (author: eric@imvu.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 //Memory leaks fixed and drastically hacked for thread safety by Lorien Dunn during integration with LDK
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     // support up to 3 tags
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         // by casting away const here, we can support member pointers to arrays
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     {//stricmp
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 // BEGIN ATTRIBUTE MAKERS
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 // END ATTRIBUTE MAKERS
00464 
00465 // BEGIN PEER MAKERS
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 // END PEER MAKERS
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                     // no problem
00579                     continue;
00580                 }
00581                 else
00582                 {
00583                     // error
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                 //data->reserve(sz);
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                 //data->reserve(sz);
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 }//namespace LDK
00870 
00871 
00872 #endif //__LDK_XMLBIND_HH__

Generated on Fri Aug 17 18:32:26 2007 for LDK by  doxygen 1.5.1