GME  13
MetaUtilities.h
Go to the documentation of this file.
00001 
00002 #ifndef MGA_METAUTILITIES_H
00003 #define MGA_METAUTILITIES_H
00004 
00005 #ifndef MGA_CORECOLLECTION_H
00006 #include "../Common/CommonCollection.h"
00007 #endif
00008 
00009 #include <vector>
00010 #include <algorithm>
00011 
00012 class CMgaMetaProject;
00013 class CMgaMetaBase;
00014 
00015 // --------------------------- CCoreObjectPtr
00016 
00017 class CCoreObjectPtr;
00018 typedef std::vector<CCoreObjectPtr> coreobjects_type;
00019 typedef coreobjects_type::iterator coreobjects_iterator;
00020 
00021 class CCoreObjectPtr
00022 {
00023 public:
00024         CCoreObjectPtr() { }
00025         explicit CCoreObjectPtr(IUnknown *q) { COMTHROW( ::QueryInterface(q, p) ); }
00026         explicit CCoreObjectPtr(ICoreObject *q) : p(q) { }
00027         CCoreObjectPtr(const CCoreObjectPtr &q) : p(q.p) { }
00028 
00029         operator ICoreObject*() const { return p; }
00030         ICoreObject* operator->() const { ASSERT( p != NULL ); return p; }
00031 
00032         ICoreObject* operator=(ICoreObject *q) { p = q; return q; }
00033         ICoreObject* operator=(const CCoreObjectPtr &q) { p = q.p; return p; }
00034 
00035 public:
00036         void GetCollectionValue(attrid_type attrid, coreobjects_type &ret) const;
00037         void GetStringValue(attrid_type attrid, BSTR *ret) const;
00038         void GetVariantValue(attrid_type attrid, VARIANT *ret) const;
00039         long GetLongValue(attrid_type attrid) const;
00040         VARIANT_BOOL GetBoolValue(attrid_type attrid) const;
00041         void GetPointerValue(attrid_type attrid, CCoreObjectPtr &ret) const;
00042         metaid_type GetMetaID() const;
00043         objid_type GetObjID() const;
00044 
00045         void PutStringValue(attrid_type attrid, BSTR a);
00046         void PutLongValue(attrid_type attrid, long a);
00047         void PutVariantValue(attrid_type attrid, VARIANT a);
00048         void PutBoolValue(attrid_type attrid, VARIANT_BOOL l);
00049         void PutPointerValue(attrid_type attrid, ICoreObject *a);
00050         void PutLockValue(attrid_type attrid, locking_type locking);
00051 
00052         void Load() { PutLockValue(ATTRID_LOCK, LOCKING_READ); }
00053         void LoadCollectionValue(attrid_type attrid, coreobjects_type &ret);
00054 
00055 public:
00056         CComObjPtr<ICoreObject> p;
00057 };
00058 
00059 // --------------------------- PutOut
00060 
00061 inline ICoreObject **PutOut(CCoreObjectPtr &coreobj)
00062 {
00063         return PutOut(coreobj.p);
00064 }
00065 
00066 // --------------------------- ComGetAttrValue
00067 
00068 struct objid_lessthan
00069 {
00070         bool operator()(const CCoreObjectPtr &a, const CCoreObjectPtr &b) const
00071         {
00072                 metaid_type am = a.GetMetaID();
00073                 metaid_type bm = b.GetMetaID();
00074 
00075                 if( am != bm )
00076                         return am > bm;
00077 
00078                 return a.GetObjID() > b.GetObjID();
00079         }
00080 };
00081 
00082 
00083 
00084 struct objid_morethan
00085 {
00086         bool operator()(const CCoreObjectPtr &a, const CCoreObjectPtr &b) const
00087         {
00088                 metaid_type am = a.GetMetaID();
00089                 metaid_type bm = b.GetMetaID();
00090 
00091                 if( am != bm )
00092                         return am > bm;
00093 
00094                 return a.GetObjID() < b.GetObjID();
00095         }
00096 };
00097 
00098 
00099 
00100 
00101 
00102 
00103 template<class ITFTYPE, class COLLITF>
00104 HRESULT ComGetCollectionValue(IUnknown *me, attrid_type attrid, COLLITF **p) {
00105         CHECK_OUT(p);
00106 
00107         COMTRY
00108         {
00109                 ASSERT( me != NULL );
00110                 CCoreObjectPtr self(me);
00111 
00112                 coreobjects_type coreobjects;
00113                 self.GetCollectionValue(attrid, coreobjects);
00114         
00115                 typedef CCoreCollection<COLLITF, std::vector<ITFTYPE*>, ITFTYPE, ITFTYPE> COMTYPE;
00116 
00117                 CComObjPtr<COMTYPE> coll;
00118                 CreateComObject(coll);
00119 
00120                 coreobjects_iterator i = coreobjects.begin();
00121                 coreobjects_iterator e = coreobjects.end();
00122                 while( i != e )
00123                 {
00124                         CComObjPtr<ITFTYPE> q;
00125                         COMTHROW( ::QueryInterface(*i, q) );
00126 
00127                         coll->Add(q);
00128 
00129                         ++i;
00130                 }
00131 
00132                 MoveTo(coll, p);
00133         }
00134         COMCATCH(;)
00135 }
00136 
00137 template<class ITFTYPE, class COLLITF>
00138 HRESULT ComGetSortedCollValue(IUnknown *me, attrid_type attrid, COLLITF **p) {
00139         CHECK_OUT(p);
00140 
00141         COMTRY
00142         {
00143                 ASSERT( me != NULL );
00144                 CCoreObjectPtr self(me);
00145 
00146                 coreobjects_type coreobjects;
00147                 self.GetCollectionValue(attrid, coreobjects);
00148         
00149                 std::sort(coreobjects.begin(), coreobjects.end(), objid_morethan());
00150 
00151                 typedef CCoreCollection<COLLITF, std::vector<ITFTYPE*>, ITFTYPE, ITFTYPE> COMTYPE;
00152 
00153                 CComObjPtr<COMTYPE> coll;
00154                 if(!coll) CreateComObject(coll);
00155 
00156                 coreobjects_iterator i = coreobjects.begin();
00157                 coreobjects_iterator e = coreobjects.end();
00158                 while( i != e )
00159                 {
00160                         CComObjPtr<ITFTYPE> q;
00161                         COMTHROW( ::QueryInterface(*i, q) );
00162 
00163                         coll->Add(q);
00164 
00165                         ++i;
00166                 }
00167 
00168                 MoveTo(coll, p);
00169         }
00170         COMCATCH(;)
00171 }
00172 
00173 template<class ITFTYPE>
00174 HRESULT ComGetCollValueByName(BSTR name, IUnknown *me, attrid_type attrid, attrid_type nameid, ITFTYPE **p)
00175 {
00176         CHECK_OUT(p);
00177 
00178         COMTRY
00179         {
00180                 ASSERT( me != NULL );
00181                 CCoreObjectPtr self(me);
00182 
00183                 coreobjects_type coreobjects;
00184                 self.GetCollectionValue(attrid, coreobjects);
00185 
00186                 coreobjects_iterator i = coreobjects.begin();
00187                 coreobjects_iterator e = coreobjects.end();
00188                 while( i != e )
00189                 {
00190                         CComBstrObj n;
00191                         (*i).GetStringValue(nameid, PutOut(n));
00192                         
00193                         if( n == name )
00194                         {
00195                                 COMTHROW( ::QueryInterface(*i, p) );
00196                                 return S_OK;
00197                         }
00198 
00199                         ++i;
00200                 }
00201 
00202                 COMRETURN(E_NOTFOUND);
00203         }
00204         COMCATCH(;)
00205 }
00206 
00207 template<class ITFTYPE, class COLLITF>
00208 HRESULT ComGetLinkCollectionValue(IUnknown *me, attrid_type collid, attrid_type ptrid, COLLITF **p) {
00209         CHECK_OUT(p);
00210 
00211         COMTRY
00212         {
00213                 ASSERT( me != NULL );
00214                 CCoreObjectPtr self(me);
00215 
00216                 coreobjects_type coreobjects;
00217                 self.GetCollectionValue(collid, coreobjects);
00218 
00219                 typedef CCoreCollection<COLLITF, std::vector<ITFTYPE*>, ITFTYPE, ITFTYPE> COMTYPE;
00220 
00221                 CComObjPtr<COMTYPE> coll;
00222                 CreateComObject(coll);
00223 
00224                 coreobjects_iterator i = coreobjects.begin();
00225                 coreobjects_iterator e = coreobjects.end();
00226                 while( i != e )
00227                 {
00228                         CCoreObjectPtr obj;
00229                         (*i).GetPointerValue(ptrid, obj);
00230 
00231                         CComObjPtr<ITFTYPE> q;
00232                         COMTHROW( ::QueryInterface(obj, q) );
00233 
00234                         coll->Add(q);
00235 
00236                         ++i;
00237                 }
00238 
00239                 MoveTo(coll, p);
00240         }
00241         COMCATCH(;)
00242 }
00243 
00244 template<class ITFTYPE>
00245 HRESULT ComGetLinkCollValueByName(BSTR name, IUnknown *me, attrid_type collid, attrid_type ptrid, ITFTYPE **p) {
00246         CHECK_OUT(p);
00247 
00248         COMTRY
00249         {
00250                 ASSERT( me != NULL );
00251                 CCoreObjectPtr self(me);
00252 
00253                 CComBstrObj_lightequal equal( me);
00254                 coreobjects_type coreobjects;
00255                 self.GetCollectionValue(collid, coreobjects);
00256 
00257                 coreobjects_iterator i = coreobjects.begin();
00258                 coreobjects_iterator e = coreobjects.end();
00259                 while( i != e )
00260                 {
00261                         CCoreObjectPtr obj;
00262                         (*i).GetPointerValue(ptrid, obj);
00263 
00264                         CComBstrObj n;
00265                         obj.GetStringValue(ATTRID_NAME, PutOut(n));
00266                         
00267                         if( equal( n, name))//if( n == name )
00268                         {
00269                                 COMTHROW( ::QueryInterface(obj, p) );
00270                                 return S_OK;
00271                         }
00272 
00273                         ++i;
00274                 }
00275 
00276                 COMRETURN(E_NOTFOUND);
00277         }
00278         COMCATCH(;)
00279 }
00280 
00281 template<class ITFTYPE, class COLLITF>
00282 HRESULT ComGetSortedLinkCollValue(IUnknown *me, attrid_type collid, attrid_type ptrid, COLLITF **p) {
00283 
00284         CHECK_OUT(p);
00285 
00286         COMTRY
00287         {
00288                 ASSERT( me != NULL );
00289                 CCoreObjectPtr self(me);
00290 
00291                 coreobjects_type coreobjects;
00292                 self.GetCollectionValue(collid, coreobjects);
00293 
00294                 std::sort(coreobjects.begin(), coreobjects.end(), objid_morethan());
00295 
00296                 typedef CCoreCollection<COLLITF, std::vector<ITFTYPE*>, ITFTYPE, ITFTYPE> COMTYPE;
00297 
00298                 CComObjPtr<COMTYPE> coll;
00299                 CreateComObject(coll);
00300 
00301                 coreobjects_iterator i = coreobjects.begin();
00302                 coreobjects_iterator e = coreobjects.end();
00303                 while( i != e )
00304                 {
00305                         CCoreObjectPtr obj;
00306                         (*i).GetPointerValue(ptrid, obj);
00307 
00308                         CComObjPtr<ITFTYPE> q;
00309                         COMTHROW( ::QueryInterface(obj, q) );
00310 
00311                         coll->Add(q);
00312 
00313                         ++i;
00314                 }
00315 
00316                 MoveTo(coll, p);
00317         }
00318         COMCATCH(;)
00319 }
00320 
00321 template<class ITFTYPE>
00322 HRESULT ComGetPointerValue(IUnknown *me, attrid_type attrid, ITFTYPE **p)
00323 {
00324         CHECK_OUT(p);
00325 
00326         COMTRY
00327         {
00328                 ASSERT( me != NULL );
00329                 CCoreObjectPtr self(me);
00330 
00331                 CCoreObjectPtr pointer;
00332                 self.GetPointerValue(attrid, pointer);
00333 
00334                 if( pointer != NULL )
00335                         COMTHROW( ::QueryInterface(pointer, p) );
00336         }
00337         COMCATCH(;)
00338 }
00339 
00340 HRESULT ComGetAttrValue(IUnknown *me, attrid_type attrid, BSTR *p);
00341 HRESULT ComGetAttrValue(IUnknown *me, attrid_type attrid, VARIANT *p);
00342 HRESULT ComGetAttrValue(IUnknown *me, attrid_type attrid, long *p);
00343 
00344 HRESULT ComGetDisplayedName(IUnknown *me, attrid_type dispattrid, attrid_type nameattrid, BSTR *p);
00345 HRESULT ComGetObjType(IUnknown *me, objtype_enum *p);
00346 
00347 // --------------------------- ComCreateObject
00348 
00349 template<class ITFTYPE>
00350 HRESULT ComCreateMetaObj(IUnknown *me, metaid_type metaid, attrid_type pointer, ITFTYPE **p)
00351 {
00352         CHECK_OUT(p);
00353         ASSERT( me != NULL );
00354 
00355         COMTRY
00356         {
00357                 CCoreObjectPtr self(me);
00358 
00359                 CComObjPtr<ICoreProject> coreproject;
00360                 COMTHROW( self->get_Project(PutOut(coreproject)) );
00361                 ASSERT( coreproject != NULL );
00362 
00363                 CCoreObjectPtr subobject;
00364                 COMTHROW( coreproject->CreateObject(metaid, PutOut(subobject)) );
00365 
00366                 subobject.PutPointerValue(pointer, self);
00367 
00368                 COMTHROW( ::QueryInterface(subobject, p) );
00369         }
00370         COMCATCH(;)
00371 }
00372 
00373 template<class ITFTYPE>
00374 HRESULT ComDefineBase(CMgaMetaBase *me, metaid_type metaid, attrid_type pointer, ITFTYPE **p)
00375 {
00376         CHECK_OUT(p);
00377         ASSERT( me != NULL );
00378 
00379         CMgaMetaProject *metaproject = me->metaproject;
00380         ASSERT( metaproject != NULL );
00381 
00382         COMTRY
00383         {
00384                 CCoreObjectPtr self(me);
00385 
00386                 CCoreObjectPtr subobject;
00387                 metaproject->CreateMetaBase(metaid, subobject);
00388 
00389                 subobject.PutPointerValue(pointer, self);
00390 
00391                 COMTHROW( ::QueryInterface(subobject, p) );
00392         }
00393         COMCATCH(;)
00394 }
00395 
00396 template<class ITFTYPE>
00397 HRESULT ComAddLink(CMgaMetaBase *me, metaid_type metaid, 
00398         attrid_type here, attrid_type there, ITFTYPE *p)
00399 {
00400         if( p == NULL )
00401                 COMRETURN(E_POINTER);
00402 
00403         ASSERT( me != NULL );
00404 
00405         CMgaMetaProject *metaproject = me->metaproject;
00406         ASSERT( metaproject != NULL );
00407 
00408         COMTRY
00409         {
00410                 CCoreObjectPtr self(me);
00411                 CCoreObjectPtr other(p);
00412 
00413                 CCoreObjectPtr link;
00414                 metaproject->CreateMetaObj(metaid, link);
00415 
00416                 link.PutPointerValue(here, self);
00417                 link.PutPointerValue(there, other);
00418         }
00419         COMCATCH(;)
00420 }
00421 
00422 template<class ITFTYPE>
00423 HRESULT ComRemoveLink(CMgaMetaBase *me, metaid_type metaid, 
00424         attrid_type here, attrid_type there, ITFTYPE *p)
00425 {
00426         return E_NOTIMPL;
00427 }
00428 
00429 // --------------------------- ComPutAttrValue
00430 
00431 HRESULT ComPutAttrValue(IUnknown *self, attrid_type attrid, BSTR p);
00432 HRESULT ComPutAttrValue(IUnknown *self, attrid_type attrid, long p);
00433 HRESULT ComPutAttrValue(IUnknown *self, attrid_type attrid, VARIANT p);
00434 
00435 // try to avoid it, not nice interface
00436 //HRESULT ComPutPointerValue(IUnknown *me, attrid_type attrid, IDispatch *p);
00437 
00438 // --------------------------- Others
00439 
00440 // this changes the variant type from BSTR
00441 void ChangeAttrValueType(CComVariant &v, attval_enum attval);
00442 
00443 HRESULT ComDeleteObject(IUnknown *self);
00444 
00445 // --------------------------- Traverse
00446 
00447 // these functions are implemented in the Meta.cpp
00448 void TraverseObject(CMgaMetaProject *metaproject, CCoreObjectPtr &me);
00449 void TraverseCollection(CMgaMetaProject *metaproject, CCoreObjectPtr &me, attrid_type attrid);
00450 
00451 // --------------------------- PathItem
00452 
00453 typedef struct pathitem_type
00454 {
00455         CComBstrObj terminal_name;
00456         CComBstrObj continual_name;
00457 } pathitem_type;
00458 
00459 typedef std::vector<pathitem_type> pathitems_type;
00460 
00461 typedef struct jointpath_type
00462 {
00463         CComBstrObj ptrspec_name;
00464         pathitems_type pathitems;
00465 } jointpath_type;
00466 
00467 typedef std::vector<jointpath_type> jointpaths_type;
00468 
00469 // --------------------------- STL function objects
00470 
00471 struct BSTR_hashfunc 
00472 {
00473         size_t operator()(const CComBstrObj &str) const 
00474         {
00475                 if(str.p == NULL) return 0;
00476                 return *str.p;
00477         }
00478 };
00479 
00480 struct BSTR_equalkey 
00481 {
00482         bool operator()(const CComBstrObj &str1, const CComBstrObj &str2) const 
00483         {
00484                 return str1 == str2;    
00485         }
00486 };
00487 
00488 struct metaid_hashfunc : public stdext::hash_compare<metaref_type>
00489 {
00490         size_t operator()(metaref_type metaref) const
00491         {
00492                 return metaref;
00493         }
00494         bool operator()(metaref_type id1, metaref_type id2) const
00495         {
00496                 // this must be < logic
00497                 //return id1 == id2;
00498                 return id1 < id2;
00499         }
00500 };
00501 
00502 CComBSTR truncateName( IUnknown *p_bs, CComBSTR pIn);
00503 
00504 struct CComBstrObj_lightequal
00505 {
00506         CComBSTR m_nmspc;
00507         //CComBstrObj_lightequal() {} // we do not allow this
00508 
00509         template<class TMETABASE>
00510         CComBstrObj_lightequal( TMETABASE p_bs) 
00511         {
00512                 CComQIPtr<IMgaMetaBase> bs( p_bs);
00513                 if( bs)
00514                 {
00515                         CComPtr<IMgaMetaProject> pr;
00516                         COMTHROW( bs->get_MetaProject( &pr));
00517                         COMTHROW( pr->GetNmspc( &m_nmspc)); // fetch namespace into m_nmspc
00518                 }
00519         }
00520 
00521         CComBstrObj_lightequal( const CComBSTR pNmspc)
00522                 : m_nmspc( pNmspc)
00523         {
00524         }
00525 
00526         //previously p1 was pUnknown, p2 was pFullName, and we thought that the user would give Fullnames
00527         bool operator()( const CComBstrObj &pFullNmInParadigm, const CComBstrObj &pUnknownFormat) const
00528         {
00529                 if( pFullNmInParadigm == pUnknownFormat)
00530                         return true;
00531                 else if( m_nmspc.Length() > 0)
00532                 {
00533                         CComBSTR longername;
00534                         COMTHROW(longername.AppendBSTR( m_nmspc));
00535                         COMTHROW(longername.Append( _T("::")));
00536                         COMTHROW(longername.AppendBSTR( pUnknownFormat));
00537                         return pFullNmInParadigm == longername;
00538                 }
00539                 else
00540                 {
00541                         return false;
00542                 }
00543         }
00544 
00545         bool operator()( const CComBstrObj &pFullNmInParadigm, BSTR pUnknownFormat) const
00546         {
00547                 return operator()(pFullNmInParadigm, CComBstrObj(pUnknownFormat));
00548         }
00549 };
00550 
00551 
00552 // --------------------------- TRACE
00553 
00554 #ifdef _DEBUG
00555 
00556 #define PATH_TRACE AtlTrace
00557 
00558 #endif
00559 
00560 inline void NOOP_TRACE(LPCSTR, ...) { }
00561 
00562 #ifndef PATH_TRACE
00563 #define PATH_TRACE 1 ? void(0) : NOOP_TRACE
00564 #endif
00565 
00566 #endif//MGA_METAUTILITIES_H