GME
13
|
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