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__